Sign in Join
Wiki copytemporary

Xtensa: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11> **Warning:** The Xtensa support is highly experimental and prone to be broken. This description is work in progress.
22
33------------------------------------------------------------------------
44
55So far Linux and macOS hosts only, currently most of the work concentrates on the ESP32 variant with the lx6 cores.
66
77------------------------------------------------------------------------
88
99## Xtensa-FreeRTOS
1010
1111### Preparing FPC
1212
1313A native FPC development branch ("main" in git; formerly "trunk" in svn) must be installed and working on the system and will be used to compile the xtensa cross compiler. Download the latest development source code for FPC. One straightforward option is to download the code directly from [GitLab](https://gitlab.com/freepascal.org/fpc/source). Click on the download button the the landing page, this will show different archive file formats to be downloaded. Click on your preferred file format to start downloading:
1414
1515![](/wiki-images/a/ab/Download_fpc_source.png)
1616
1717Once downloaded, extract all the files into a folder, such as `~/fpc/main`.
1818
1919Or use [git to clone the FPC source repository](https://wiki.freepascal.org/FPC_git). Although the clone operation will download a large amount of data, subsequent updates to later revisions will only consume a small amount of data.
2020
2121Another alternative is to use [fpcupdeluxe](https://wiki.freepascal.org/fpcupdeluxe) which automates all the steps below (not extensively tested).
2222
2323### ESP32
2424
2525#### Preparations
2626
2727Install esp-idf based on the instructions given here:
2828
2929[Get Started (for Stable Release)](https://docs.espressif.com/projects/esp-idf/en/stable/get-started/index.html)
3030
3131Follow the instructions to a least step 8 where you build the hello_word demo project.
3232
3333Copy all the freshly compiled .a files from the current project directory to a directory of your choice:
3434
35-` mkdir ~/esp/xtensa-esp32-elf-libs `\
36-` find . -path ./build/bootloader -prune -o -name "*.a" -exec cp {} ~/esp/xtensa-esp32-elf-libs \;`\
37-` find ~/esp/esp-idf/components -name "*.a" -exec cp {} ~/esp/xtensa-esp32-elf-libs \;`
35+```text
36+ mkdir ~/esp/xtensa-esp32-elf-libs
37+ find . -path ./build/bootloader -prune -o -name "*.a" -exec cp {} ~/esp/xtensa-esp32-elf-libs \;
38+ find ~/esp/esp-idf/components -name "*.a" -exec cp {} ~/esp/xtensa-esp32-elf-libs \;
39+```
3840
3941Optionally (but recommended) also copy the *esp32_out.ld* and *esp32.project.ld* files from the */build/esp32/* folder, or *./build/esp-idf/esp32* and *./build/esp-idf/esp32/ld* folders, into *~/esp/xtensa-esp32-elf-libs* (with the rest of the SDK libraries). These linker scripts are required when linking a fpc project and needs to be reconstructed if not found by fpc.
4042
4143Notes:
4244
4345- Make sure that you are in the directory where you have built the hello_world demo project when executing the find commands above.
4446- One should not copy libraries from the project/build/bootloader directory, since these libraries do not contain full functionality.
4547- Some of the required libraries are located in the esp-idf/components folder. Important to also copy the libraries in the ~/esp/esp-idf/components directory if the demo project was copied to outside the esp-idf directory.
4648
4749Now you are ready to compile fpc and rtl.
4850
4951execute
5052
51-`export IDF_PATH=~/esp/esp-idf`\
52-`source ~/esp/esp-idf/export.sh`
53+```text
54+export IDF_PATH=~/esp/esp-idf
55+source ~/esp/esp-idf/export.sh
56+```
5357
5458to get the path and environment set (namely tools path and \$IDF_PATH are needed)
5559
5660#### Build FPC
5761
5862Change into the fpc (e.g. ~/fpc/main) directory and run
5963
60-` make FPC=fpc CPU_TARGET=xtensa OS_TARGET=freertos SUBARCH=lx6 "CROSSOPT=-XPxtensa-esp32-elf- -Cfhard" all -j`
64+```text
65+ make FPC=fpc CPU_TARGET=xtensa OS_TARGET=freertos SUBARCH=lx6 "CROSSOPT=-XPxtensa-esp32-elf- -Cfhard" all -j
66+```
6167
6268#### Tips & Tricks
6369
6470If linking fails due to missing libraries, you can search them by (replace missing_symbol by the missing symbol):
6571
66-` xtensa-esp32-elf-objdump -t ~/esp/xtensa-esp32-elf-libs/*.a | grep 'missing_symbol\|xtensa-esp32-elf-libs'`
72+```text
73+ xtensa-esp32-elf-objdump -t ~/esp/xtensa-esp32-elf-libs/*.a | grep 'missing_symbol\|xtensa-esp32-elf-libs'
74+```
6775
6876fpc doesn't automatically allocate heap space for this target. When using dynamic memory allocation remember to specify a heap size (for example -Ch1024).
6977
7078#### Compile and run test program
7179
7280Create a hello world program:
7381
7482``` pascal
7583 program hello;
7684 begin
7785 WriteLn('Hello world.');
7886 end.
7987```
8088
8189in a new folder and compile it with:
8290
83-` ~/fpc/main/compiler/ppcrossxtensa -Fu~/fpc/main/rtl/units/xtensa-freertos/ -Tfreertos -XPxtensa-esp32-elf- -O3 -Wpesp32 -Fl~/esp/xtensa-esp32-elf-libs  -Fl~/.espressif/tools/xtensa-esp32-elf/esp-2021r2-8.4.0/xtensa-esp32-elf/xtensa-esp32-elf/lib/ hello`
91+```text
92+ ~/fpc/main/compiler/ppcrossxtensa -Fu~/fpc/main/rtl/units/xtensa-freertos/ -Tfreertos -XPxtensa-esp32-elf- -O3 -Wpesp32 -Fl~/esp/xtensa-esp32-elf-libs -Fl~/.espressif/tools/xtensa-esp32-elf/esp-2021r2-8.4.0/xtensa-esp32-elf/xtensa-esp32-elf/lib/ hello
93+```
8494
8595> **Note:** You may need to change "esp-2021r2-8.4.0" in the above command to the appropriate release name for your installation.
8696
8797> **Note:** Different versions of esp-idf require different libraries to link. Use the -WP command line option to specify the version number, e.g. *-WP4.3.2*.
8898
8999Get partition-table.bin and bootloader.bin from the hello_world example compiled above and copy them into the same directory as the compiled hello.bin. For the default setup, use:
90100
91-` cp ~/esp/hello_world/build/partition_table/partition-table.bin ~/esp/hello_world/build/bootloader/bootloader.bin .`
101+```text
102+ cp ~/esp/hello_world/build/partition_table/partition-table.bin ~/esp/hello_world/build/bootloader/bootloader.bin .
103+```
92104
93105Flash with:
94106
95-` esptool.py -p /dev/ttyUSB0 -b 460800 --before default_reset --after hard_reset --chip esp32  write_flash --flash_mode dio --flash_size detect --flash_freq 40m 0x1000 bootloader.bin 0x8000 partition-table.bin 0x10000 hello.bin`
107+```text
108+ esptool.py -p /dev/ttyUSB0 -b 460800 --before default_reset --after hard_reset --chip esp32 write_flash --flash_mode dio --flash_size detect --flash_freq 40m 0x1000 bootloader.bin 0x8000 partition-table.bin 0x10000 hello.bin
109+```
96110
97111- The maximum feasible baud rate depends on the USB-serial chip interfacing with the ESP32 chip, see [this link](https://www.esp32.com/viewtopic.php?t=420). A baud rate of 921600 has worked successfully for flashing over a CP210x chip.
98112
99113Monitor the output with:
100114
101-` idf_monitor.py  --port /dev/ttyUSB0 hello.elf`
115+```text
116+ idf_monitor.py --port /dev/ttyUSB0 hello.elf
117+```
102118
103119Note:
104120
105121- Once the bootloader and partition table has been flashed once one could also just flash the application only:
106122
107-` esptool.py -p /dev/ttyUSB0 -b 460800 --before default_reset --after hard_reset --chip esp32  write_flash --flash_mode dio --flash_size detect --flash_freq 40m 0x10000 hello.bin`
123+```text
124+ esptool.py -p /dev/ttyUSB0 -b 460800 --before default_reset --after hard_reset --chip esp32 write_flash --flash_mode dio --flash_size detect --flash_freq 40m 0x10000 hello.bin
125+```
108126
109127### ESP8266
110128
111129#### Preparations
112130
113131Install the ESP8266-RTOS-SDK (currently up to v3.4 supported by FPC) based on the instructions given here: [Get Started](https://docs.espressif.com/projects/esp8266-rtos-sdk/en/v3.4/get-started/)
114132
115133Follow the tutorial till the test of the hello world program so it is ensured, that everything works.
116134
117135Copy all the freshly compiled .a files from the current project directory to a directory of your choice:
118136
119-` mkdir ~/esp/xtensa-lx106-elf-libs `\
120-` find . -path ./build/bootloader -prune -o -name "*.a" -exec cp {} ~/esp/xtensa-lx106-elf-libs \;`
137+```text
138+ mkdir ~/esp/xtensa-lx106-elf-libs
139+ find . -path ./build/bootloader -prune -o -name "*.a" -exec cp {} ~/esp/xtensa-lx106-elf-libs \;
140+```
121141
122142Optionally (but recommended) also copy the *esp8266_out.ld* and *esp8266.project.ld* files from the */build/esp8266/* folder into *~/esp/xtensa-lx106-elf-libs* (with the rest of the SDK libraries). These linker scripts are required when linking a fpc project and needs to be reconstructed if not found by fpc.
123143
124144Notes:
125145
126146- Make sure that you are in the directory where you have built the hello_world demo project when executing the find commands above.
127147- One should not copy libraries from the project/build/bootloader directory, since these libraries do not contain full functionality.
128148
129149Now you are ready to compile fpc and rtl.
130150
131151#### Build FPC
132152
133153Change into the fpc (e.g. `~/fpc/main`) directory and run:
134154
135-` make FPC=fpc CPU_TARGET=xtensa OS_TARGET=freertos SUBARCH=lx106 BINUTILSPREFIX=xtensa-lx106-elf- all -j`
155+```text
156+ make FPC=fpc CPU_TARGET=xtensa OS_TARGET=freertos SUBARCH=lx106 BINUTILSPREFIX=xtensa-lx106-elf- all -j
157+```
136158
137159#### Tips & Tricks
138160
139161fpc doesn't automatically allocate heap space for this target. When using dynamic memory allocation remember to specify a heap size (for example -Ch1024).
140162
141163#### Compile and run test program
142164
143165Create a hello world program:
144166
145167``` pascal
146168 program hello;
147169 begin
148170 WriteLn('Hello world.');
149171 end.
150172```
151173
152174in a separate directory and compile it with:
153175
154-` ~/fpc/main/compiler/ppcrossxtensa -Fu~/fpc/main/rtl/units/xtensa-freertos/ -Tfreertos -XPxtensa-lx106-elf- -O3 -Wpesp8266 hello -Fl~/esp/xtensa-lx106-elf-libs/ -Fl$IDF_PATH/components/esp8266/lib -Fl$IDF_PATH/components/newlib/newlib/lib -Fl~/esp/xtensa-lx106-elf/xtensa-lx106-elf/lib/ -WP3.4`
176+```text
177+ ~/fpc/main/compiler/ppcrossxtensa -Fu~/fpc/main/rtl/units/xtensa-freertos/ -Tfreertos -XPxtensa-lx106-elf- -O3 -Wpesp8266 hello -Fl~/esp/xtensa-lx106-elf-libs/ -Fl$IDF_PATH/components/esp8266/lib -Fl$IDF_PATH/components/newlib/newlib/lib -Fl~/esp/xtensa-lx106-elf/xtensa-lx106-elf/lib/ -WP3.4
178+```
155179
156180Get partitions_singleapp.bin and bootloader.bin from the hello_world example compiled above and copy them into the same dir as the compiled hello.bin
157181
158182Flash with:
159183
160-` $IDF_PATH/components/esptool_py/esptool/esptool.py --chip esp8266 --port "/dev/ttyUSB0" --baud 921600 --before "default_reset" --after "hard_reset" write_flash -z --flash_mode "dio" --flash_freq "40m" --flash_size "2MB"   0x0 bootloader.bin 0x10000 hello.bin 0x8000 partitions_singleapp.bin`
184+```text
185+ $IDF_PATH/components/esptool_py/esptool/esptool.py --chip esp8266 --port "/dev/ttyUSB0" --baud 921600 --before "default_reset" --after "hard_reset" write_flash -z --flash_mode "dio" --flash_freq "40m" --flash_size "2MB" 0x0 bootloader.bin 0x10000 hello.bin 0x8000 partitions_singleapp.bin
186+```
161187
162188Monitor the output with:
163189
164-` $IDF_PATH/tools/idf_monitor.py --baud 74880 --port /dev/ttyUSB0 hello.elf`
190+```text
191+ $IDF_PATH/tools/idf_monitor.py --baud 74880 --port /dev/ttyUSB0 hello.elf
192+```
165193
166194Note:
167195
168196- Different versions of the SDK may require different libraries to link. Use the -WP command line option to specify the SDK version number, e.g. *-WP3.4*.
169197
170198### Using both ESP32 and ESP8266
171199
172200Both controllers use the same ppcrossxtensa compiler, but different versions of the RTL. The default folder structure of fpc does not cater for this, so each time the cross compiler is built, it will overwrite the RTL files in rtl/units/xtensa-freertos. To use both ESP32 and ESP8266 in parallel (i.e. without rebuilding the RTL to switch to a different compiler), the following approach can be used:
173201
1742021\. Once the cross compiler is built, rename the rtl/units/xtensa-freertos folder to rtl/units/xtensa-freertos/\$subarch, where \$subarch is either lx6 or lx106.
175203
1762042\. Edit fpc.cfg. Locate the line with the path to the rtl (e.g. -Fu~/fpc/main/rtl/units/\$fpctarget) and modify it as follows:
177205
178-` #ifdef cpuxtensa`\
179-`   -Fu~/fpc/main/rtl/units/$fpctarget/$fpcsubarch`\
180-` #else`\
181-`   -Fu~/fpc/main/rtl/units/$fpctarget`\
182-` #endif`
206+```text
207+ #ifdef cpuxtensa
208+ -Fu~/fpc/main/rtl/units/$fpctarget/$fpcsubarch
209+ #else
210+ -Fu~/fpc/main/rtl/units/$fpctarget
211+ #endif
212+```
183213
184214Both esp-idf and ESP8266-RTOS-SDK use an environment variable named IDF_PATH to point to the path of the respective SDK. If both SDKs are installed, the path to the desired SDK can be passed to the compiler using the -Ff command line switch. This path is used to locate scripts and linker configuration files - the location of library files still need to be specified using -Fl.
185215
186216## Xtensa-Linux
187217
188218### To use with QEMU
189219
190220#### Build binutils
191221
192222Get binutils-gdb sources, e.g. by
193223
194-` git clone `[`git://sourceware.org/git/binutils-gdb`](git://sourceware.org/git/binutils-gdb)
224+```text
225+ git clone git://sourceware.org/git/binutils-gdb
226+```
195227
196228Binutils 2.34 is known to work, so optionally do
197229
198-` git checkout binutils-2_34`
230+```text
231+ git checkout binutils-2_34
232+```
199233
200234Copy <https://github.com/FPK/binutils-xtensa-config/blob/master/lx6/xtensa-config.h> into binutils-gdb/include to configure binutils for the CPU type support by FPC for xtensa-linux. This replaces the original file.
201235
202236Configure and build binutils with
203237
204-` ./configure --target=xtensa-linux --disable-gdb --disable-sim --disable-readline --disable-libdecnumber`\
205-``  make -j `nproc` ``\
206-` sudo make install`
238+```text
239+ ./configure --target=xtensa-linux --disable-gdb --disable-sim --disable-readline --disable-libdecnumber
240+ make -j `nproc`
241+ sudo make install
242+```
207243
208244#### Build FPC
209245
210246Get latest trunk and build it with:
211247
212-` make FPC=fpc all -j "CROSSOPT=-Cfhard" OS_TARGET=linux CPU_TARGET=xtensa`
248+```text
249+ make FPC=fpc all -j "CROSSOPT=-Cfhard" OS_TARGET=linux CPU_TARGET=xtensa
250+```
213251
214252#### Test FPC
215253
216254Create a hello world in the FPC top level directory. Compile it with:
217255
218-` compiler/ppcrossxtensa hello.pp -Tlinux -Furtl/units/xtensa-linux`
256+```text
257+ compiler/ppcrossxtensa hello.pp -Tlinux -Furtl/units/xtensa-linux
258+```
219259
220260Run it with:
221261
222-` qemu-xtensa ./hello`
262+```text
263+ qemu-xtensa ./hello
264+```
223265
224266## Xtensa-Embedded
225267
226268## Emulation and debugging using qemu (ESP32)
227269
228270### Install qemu (from source)
229271
230272The official release of qemu supports the xtensa architecture but lacks support for the ESP32 and ESP8266 boards. To use qemu with ESP32 (ESP8266 support is not yet officially available) one can use Espressif's port of qemu (refer to this for detail information: <https://github.com/espressif/esp-toolchain-docs/blob/main/qemu/README.md>).
231273
232274### Automated testing with qemu
233275
234276For automated testing one needs to return an exit code from qemu to indicate the outcome of a test. One way to achieve this is to call the simcall instruction passing 1 in register a2 and the exit code in register a3:
235277
236278``` asm
237279 procedure qemu_exit(const exitcode: uint32); assembler; noreturn;
238280 asm
239281 mov a3, a2 // copy exitcode value into a3
240282 movi a2, 1 // set a2 to 1 - exit request
241283 simcall
242284 end;
243285```
244286
245287---
246288*From the Free Pascal wiki, page "Xtensa", as it stood on 2024-01-13 after a change by Ccrause, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
247289Category: Embedded

Back to history