Recent

Author Topic: Esp32 / freeRTOS using fpcupdelux  (Read 8749 times)

ajvperth

  • New member
  • *
  • Posts: 9
Esp32 / freeRTOS using fpcupdelux
« on: January 05, 2025, 07:38:57 pm »
Hello,
I like to use fpc as a C alternative to program Esp32 micro-controllers.
I started with a clean Linux openSUSE Leap VirtualBox image and installed fpcupdeluxe.
Using fpcupdeluxe I installed the stable FPC and stable Lazarus version.
Compiling and running hello,pas was as expected.

hello.pas
=========
program hello;
uses    sysutils;
var     n   : Integer;
begin
    while true do
    begin
        n += 1;
        writeLn(n, ' Hello world');
        sleep(1000);
    end;
end.

Then using fpcupdeluxe I installed the trunk FPC and trunk Lazarus version for cross xtensa / freertos installed by clicking the ESP32 button.
Compiling / running the same hello.pas from above compiled with the message Success in green en resulted into a hello file [1.44 MB] in my project folder.

This file was uploded into the esp32 by:

Esp32 upload (as with micropython)
=============================
1. $ . ~/work/venv_esp/bin/activate
   (venv) esptool.py -p /dev/ttyUSB0 -c esp32 flash_id     -->  flash info
   (venv) esptool.py -p /dev/ttyUSB0 -c esp32 erase_flash  -->  erase flash
   (venv) esptool.py -p /dev/ttyUSB0 -c esp32 -b 460800 write_flash -z 0x1000 hello
   (venv) deactivate
2. $ picocom -b 115200 /dev/ttyUSB0
   -->  flash read err, 1000
   Ctrl-a-x


Esp32 upload (as in fpc wiki)
==========================
1. ref: https://wiki.lazarus.freepascal.org/Xtensa
2. $ . ~/work/venv_esp/bin/activate
   (venv) esptool.py -p /dev/ttyUSB0 -c esp32 flash_id     -->  flash info
   (venv) esptool.py -p /dev/ttyUSB0 -c esp32 erase_flash  -->  erase flash
3. from wiki:
   (venv) 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   ?????
4. as bootloader.bin and partition-table.bin are not generated by fpcupdeluxe, I assume its embedded in hello
   (venv) esptool.py -p /dev/ttyUSB0 -b 460800 --before default_reset --after hard_reset -c esp32  write_flash --flash_mode dio --flash_size detect --flash_freq 40m 0x1000 hello
5. $ picocom -b 115200 /dev/ttyUSB0
   -->  flash read err, 1000
   Ctrl-a-x
6. (venv) esptool.py -p /dev/ttyUSB0 -b 460800 --before default_reset --after hard_reset -c esp32  write_flash --flash_mode dio --flash_size detect --flash_freq 40m 0x10000 hello
7. $ picocom -b 115200 /dev/ttyUSB0
   -->  flash read err, 1000
   Ctrl-a-x
8. also tried in forced bootloader mode  with boot and rst buttons -->  same results

My question is how to get this hello file running on a esp32?
or how to make an image that is running on the esp32
thanks in advance.

ccrause

  • Hero Member
  • *****
  • Posts: 1018
Re: Esp32 / freeRTOS using fpcupdelux
« Reply #1 on: January 06, 2025, 07:32:07 am »
Please provide full output of esptool commands and the serial output of the boot process, the following discussion is based on assumptions due to incomplete information.

Quote
   (venv) esptool.py -p /dev/ttyUSB0 -c esp32 -b 460800 write_flash -z 0x1000 hello
The 2nd stage bootloader should be flashed to address 0x1000, not the program  Unless of course it is a combined image containing both bootloader, partitions and program.

Quote
3. from wiki:
   (venv) 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   ?????
4. as bootloader.bin and partition-table.bin are not generated by fpcupdeluxe, I assume its embedded in hello
   (venv) esptool.py -p /dev/ttyUSB0 -b 460800 --before default_reset --after hard_reset -c esp32  write_flash --flash_mode dio --flash_size detect --flash_freq 40m 0x1000 hello
FPC only creates the program image (hello.bin), the partition table and bootloader should either be existing in flash (and compatible with the esp-idf library configuration) or be flashed to the esp32. You should provide the path to the bootloader and partition images. Did you observe errors during flashing? Fpcupdeluxe typically saves the bootloader and partition table in FPCUPDELUXE_ROOT/cross//lib/xtensa-freertos/lx6/.

Quote
(venv) esptool.py -p /dev/ttyUSB0 -c esp32 erase_flash  -->  erase flash
This command will delete everything in flash, including the bootloader and partitions.  After this command one must flash a bootloader and optionally (but basically required) the partition image.

Quote
flash read err, 1000
The first stage bootloader expects the second stage bootloader at address 0x1000, this error likely indicates an invalid bootloader at this address.

Note:
Quote
        sleep(1000);
For freertos this will call a procedural variable which is by default unassigned, so your loop will repeat very quickly with no pause.  Use the freertos procedure vTaskDelay for a delay that plays nice with the OS scheduler:
Code: Pascal  [Select][+][-]
  1. program hello;
  2.  
  3. procedure vTaskDelay(xTicksToDelay: uint32); external;
  4.  
  5. var     n   : Integer;
  6. begin
  7.     while true do
  8.     begin
  9.         n += 1;  // The Pascal alternative to this C construct is inc(i) :-)
  10.         writeLn(n, ' Hello world');
  11.         vTaskDelay(100);  // delay time specified in OS ticks, typically a tick duration is 10 ms
  12.     end;
  13. end.

ajvperth

  • New member
  • *
  • Posts: 9
Re: Esp32 / freeRTOS using fpcupdelux
« Reply #2 on: January 06, 2025, 11:29:03 am »
Dear CCrause,
thank you very much for this detailed answer, I think it will bring me much further.
although it will be later this week before I have results.

I am wondering what more is available with external suffix like:
procedure vTaskDelay(xTicksToDelay: uint32); external;
Do you know where I can find this? Maybe it is explained in a wiki?

Thanks, Anthony

ccrause

  • Hero Member
  • *****
  • Posts: 1018
Re: Esp32 / freeRTOS using fpcupdelux
« Reply #3 on: January 06, 2025, 12:41:43 pm »
I am wondering what more is available with external suffix like:
procedure vTaskDelay(xTicksToDelay: uint32); external;
Do you know where I can find this? Maybe it is explained in a wiki?

The esp-idf SDK is documented, a good starting point is here: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/index.html

Pascal wrappers for some of the functionality (based on an old version v4.3) is available here: https://github.com/ccrause/fpc-esp-freertos

ajvperth

  • New member
  • *
  • Posts: 9
Re: Esp32 / freeRTOS using fpcupdelux
« Reply #4 on: January 07, 2025, 11:08:03 pm »
Dear CCrause,
thanks for your hints, that makes a lot of sense to me.
Unfortunately the line "procedure vTaskDelay(xTicksToDelay: uint32); external;" produces a undefined reference to vTaskDelay linking error.
I assume that in Lazarus Project Options | Compiler options | Paths a link to a .so file or directory should be provided.
Can you give me a hint to what is needed?

indeed in FPCUPDELUXE_ROOT/cross/lib/xtensa-freertos/lx6/ I see bootloader.bin. Also partitions_singleapp.bin and partitions_two_ota.bin; assuming ota stands for over the air I think partitions_singleapp.bin is the needed partitions.bin

Thanks, Anthony

ccrause

  • Hero Member
  • *****
  • Posts: 1018
Re: Esp32 / freeRTOS using fpcupdelux
« Reply #5 on: January 08, 2025, 09:06:51 am »
Dear CCrause,
thanks for your hints, that makes a lot of sense to me.
Unfortunately the line "procedure vTaskDelay(xTicksToDelay: uint32); external;" produces a undefined reference to vTaskDelay linking error.
I assume that in Lazarus Project Options | Compiler options | Paths a link to a .so file or directory should be provided.
Can you give me a hint to what is needed?
vTaskDelay should be located in libfreertos.a which should already be required to compile the FPC esp32 unit (see the version specific llibrary list).  fpcupdeluxe should already provide the paths to the required libraries in fpc.cfg specific to the cross compiler it installs so my suspicion is that something is wrong.  To figure out what is wrong though requires a bit more information.

libfreertos.a should be in FPCUPDELUXE_ROOT/cross/lib/xtensa-freertos/lx6/.  Confirm that it contains the symbol vTaskDelay by running grep:
Code: Text  [Select][+][-]
  1. $ rgrep vTaskDelay libfreertos.a
  2. grep: libfreertos.a: binary file matches

Next ensure that your project is compiled with appropriate settings.  Show the full command line parameters passed to FPC (in menu click Project > Project Options, then click on Compiler Options in the tree view, then click on the Show Options button, ensure the relative paths option is unselected and Show multiple lines is selected).  The first entry should be the location of the compiler used for your project.  There should be an fpc.cfg file in the same folder, please attach this for inspection.

Next step to is to enable full debug output of the compiler (in menu click Project > Project Options, then expand Compiler Options in the tree view, then click on Verbosity and select Show everything (-va)).  This should dump a whole bunch of compiler output to the Messages window when you compile your project.  If not, right click inside the Messages window, click on Filter non urgent Messages and select Filter None, do not filter by urgency. To copy all the messages right click in the Messages window, click on Copy and then click on Copy All/Original Messages to Clipboard.

Quote
Indeed in FPCUPDELUXE_ROOT/cross/lib/xtensa-freertos/lx6/ I see bootloader.bin. Also partitions_singleapp.bin and partitions_two_ota.bin; assuming ota stands for over the air I think partitions_singleapp.bin is the needed partitions.bin
Yes, you are correct.

ajvperth

  • New member
  • *
  • Posts: 9
Re: Esp32 / freeRTOS using fpcupdelux
« Reply #6 on: January 08, 2025, 12:10:02 pm »
Dear CCrause,
thanks again for your suggestions, it is very much appreciated.
Indeed  FPCUPDELUXE_ROOT/cross/lib/xtensa-freertos/lx6/ contains libfreertos.a size=1 MB and holding a reference to vTaskDelay

FPC command line as generated by Lazarus:
/home/ajv/bin/fpcupdeluxe/esp32/fpc/bin/x86_64-linux/fpc.sh
-MObjFPC
-Scghi
-Cg
-O1
-gw3
-gl
-l
-vabq
-Fi/home/ajv/bin/fpcupdeluxe/esp32/projects/lib/x86_64-linux
-Fu/home/ajv/bin/fpcupdeluxe/esp32/projects/
-FU/home/ajv/bin/fpcupdeluxe/esp32/projects/lib/x86_64-linux/
-FE/home/ajv/bin/fpcupdeluxe/esp32/projects/
-o/home/ajv/bin/fpcupdeluxe/esp32/projects/hello_esp32
hello_esp32.lpr

The test shows:
Warning: ppu exist twice: esp32/fpc/units/x86_64-linux/utils-pas/js/dirwatch.ppu
                          esp32/fpc/units/x86_64-linux/utils-pas/fcl-base/dirwatch.ppu

fpc.sh contains:
/home/ajv/bin/fpcupdeluxe/esp32/fpc/bin/x86_64-linux/fpc -n @/home/ajv/bin/fpcupdeluxe/esp32/fpc/bin/x86_64-linux/fpc.cfg "$@"

the fpc.cfg file is attached
the full debugger output is in attached file fpc_messages_1.txt

I assumed Lazarus is preconfigured for Esp32 cross compilation as in
Project | Project options | Config and target  -->  it states in Target platform all Defaults
I changed this:
Target OS       : Default --> FreeRTOS
Target CPU      : Default --> xtensa
Target processor: Default --> lx6

the test now shows:
HINT: using config file /home/ajv/bin/fpcupdeluxe/esp32/fpc/bin/x86_64-linux/fpc.cfg
ERROR: RTL unit not found: objpas.ppu
ERROR: RTL unit not found: sysutils.ppu
ERROR: RTL unit not found: classes.ppu
ERROR: RTL unit not found: avl_tree.ppu
ERROR: RTL unit not found: zstream.ppu

the full debugger output is in attached file fpc_messages_2.txt

looking to the first "not found" error:
[0.004] (11032) Interpreting option "-Fu/home/ajv/bin/fpcupdeluxe/esp32/packages.fppkg/units/x86_64-linux/*"
the path I have:
/home/ajv/bin/fpcupdeluxe/esp32/packages.fppkg/config/ only"

I hope you are able to make something out of this.

Best regards, Anthony

ccrause

  • Hero Member
  • *****
  • Posts: 1018
Re: Esp32 / freeRTOS using fpcupdelux
« Reply #7 on: January 08, 2025, 04:58:58 pm »
Dear CCrause,
thanks again for your suggestions, it is very much appreciated.
Indeed  FPCUPDELUXE_ROOT/cross/lib/xtensa-freertos/lx6/ contains libfreertos.a size=1 MB and holding a reference to vTaskDelay

FPC command line as generated by Lazarus:
/home/ajv/bin/fpcupdeluxe/esp32/fpc/bin/x86_64-linux/fpc.sh
-MObjFPC
-Scghi
-Cg
-O1
-gw3
-gl
-l
-vabq
-Fi/home/ajv/bin/fpcupdeluxe/esp32/projects/lib/x86_64-linux
-Fu/home/ajv/bin/fpcupdeluxe/esp32/projects/
-FU/home/ajv/bin/fpcupdeluxe/esp32/projects/lib/x86_64-linux/
-FE/home/ajv/bin/fpcupdeluxe/esp32/projects/
-o/home/ajv/bin/fpcupdeluxe/esp32/projects/hello_esp32
hello_esp32.lpr

The test shows:
Warning: ppu exist twice: esp32/fpc/units/x86_64-linux/utils-pas/js/dirwatch.ppu
                          esp32/fpc/units/x86_64-linux/utils-pas/fcl-base/dirwatch.ppu

fpc.sh contains:
/home/ajv/bin/fpcupdeluxe/esp32/fpc/bin/x86_64-linux/fpc -n @/home/ajv/bin/fpcupdeluxe/esp32/fpc/bin/x86_64-linux/fpc.cfg "$@"

the fpc.cfg file is attached
the full debugger output is in attached file fpc_messages_1.txt

I assumed Lazarus is preconfigured for Esp32 cross compilation as in
Project | Project options | Config and target  -->  it states in Target platform all Defaults
Lazarus only passes the target specifications across to fpc.  fpc then figures out which compiler to use based on the settings passed.  If the target information is set to default, fpc compiles the program for the host system. So for cross compiling one should always set the target information - as you have done below.

Quote
I changed this:
Target OS       : Default --> FreeRTOS
Target CPU      : Default --> xtensa
Target processor: Default --> lx6

the test now shows:
HINT: using config file /home/ajv/bin/fpcupdeluxe/esp32/fpc/bin/x86_64-linux/fpc.cfg
ERROR: RTL unit not found: objpas.ppu
ERROR: RTL unit not found: sysutils.ppu
ERROR: RTL unit not found: classes.ppu
ERROR: RTL unit not found: avl_tree.ppu
ERROR: RTL unit not found: zstream.ppu

the full debugger output is in attached file fpc_messages_2.txt
The errors you mentioned above are not found in fpc_messages_2.txt, not sure where you saw that?

Quote
looking to the first "not found" error:
[0.004] (11032) Interpreting option "-Fu/home/ajv/bin/fpcupdeluxe/esp32/packages.fppkg/units/x86_64-linux/*"
the path I have:
/home/ajv/bin/fpcupdeluxe/esp32/packages.fppkg/config/ only"

I hope you are able to make something out of this.
This is not fatal for your use case since your program does not use packages.

A promising clue is the following: [0.004] Searching file /home/ajv/bin/fpcupdeluxe/esp32/fpc/units/xtensa-freertos/lx6/rtl/system.ppu... found
This means that the compiler located the xtensa-freertos system unit for subarch lx6, so the RTL unit search path is correctly configured.

The real problem is flagged almost at the end of fpc_messages_2.txt: [0.016] Fatal: (10022) Can't find unit lnfodwrf used by hello_esp32
Debug information is not available on embedded and freertos targets, so go to the debug options of your project and unselect Display line numbers in run-time error backtraces (-gl).

ajvperth

  • New member
  • *
  • Posts: 9
Re: Esp32 / freeRTOS using fpcupdelux
« Reply #8 on: January 08, 2025, 06:24:02 pm »
Dear CCrause,

thanks, we have made a step forwards, but I have no idea how many steps it is to the finish.

the messages:
HINT: using config file /home/ajv/bin/fpcupdeluxe/esp32/fpc/bin/x86_64-linux/fpc.cfg
ERROR: RTL unit not found: objpas.ppu
ERROR: RTL unit not found: sysutils.ppu
ERROR: RTL unit not found: classes.ppu
ERROR: RTL unit not found: avl_tree.ppu
ERROR: RTL unit not found: zstream.ppu
I see in the Project | Project options | Test button

I did: unselect Display line numbers in run-time error backtraces (-gl)
and compiled again.
Now I have the error: /home/ajv/bin/fpcupdeluxe/esp32/cross/bin/xtensa-freertos/bin/xtensa-esp32-elf-lc: can not find libcoexist.a
I do have: /home/ajv/bin/fpcupdeluxe/esp32/cross/lib/xtensa-freertos/lx6/esp32/libcoexist.a
the messages output is in attached file fpc_messages_3.txt

In my project options:
Other unit files (-Fu) is empty
Include files (-Fi) is ($ProjOutDir)
Libraries (-Fl) is emty

so I added /home/ajv/bin/fpcupdeluxe/esp32/cross/lib/xtensa-freertos/lx6/esp32/ to other unit files
Are you aware of a path macro like ($ProjOutDir) for part of this path?

Now I have no errors with Compile and Build.
In my project directory I find hello_esp32.elf [3.2 MB] and hello_esp32.bin [167 kB]
I will upload the three *.bin file to the esp32 and I let you know how it goes on.

Anthony

ccrause

  • Hero Member
  • *****
  • Posts: 1018
Re: Esp32 / freeRTOS using fpcupdelux
« Reply #9 on: January 08, 2025, 07:40:34 pm »
Dear CCrause,

thanks, we have made a step forwards, but I have no idea how many steps it is to the finish.

the messages:
HINT: using config file /home/ajv/bin/fpcupdeluxe/esp32/fpc/bin/x86_64-linux/fpc.cfg
ERROR: RTL unit not found: objpas.ppu
ERROR: RTL unit not found: sysutils.ppu
ERROR: RTL unit not found: classes.ppu
ERROR: RTL unit not found: avl_tree.ppu
ERROR: RTL unit not found: zstream.ppu
I see in the Project | Project options | Test button
The Test button test a few different configuration options.  The errors it reports do not appear to be useful for this particular cross compilation case.

Quote
I did: unselect Display line numbers in run-time error backtraces (-gl)
and compiled again.
Now I have the error: /home/ajv/bin/fpcupdeluxe/esp32/cross/bin/xtensa-freertos/bin/xtensa-esp32-elf-lc: can not find libcoexist.a
I do have: /home/ajv/bin/fpcupdeluxe/esp32/cross/lib/xtensa-freertos/lx6/esp32/libcoexist.a
the messages output is in attached file fpc_messages_3.txt

At least the other SDK libraries are found. libcoexist is a bit of a problem, since it was introduced as a dependency on the FPC side after the fcupdeluxe snapshot for esp32 was finalised.  This will have to be updated on fpcupdeluxe's side to be consistent with the compiler.

Quote
In my project options:
Other unit files (-Fu) is empty
Include files (-Fi) is ($ProjOutDir)
Libraries (-Fl) is emty

so I added /home/ajv/bin/fpcupdeluxe/esp32/cross/lib/xtensa-freertos/lx6/esp32/ to other unit files
Are you aware of a path macro like ($ProjOutDir) for part of this path?

Now I have no errors with Compile and Build.
In my project directory I find hello_esp32.elf [3.2 MB] and hello_esp32.bin [167 kB]
I will upload the three *.bin file to the esp32 and I let you know how it goes on.

Anthony
This may very well work, keep us updated!

ajvperth

  • New member
  • *
  • Posts: 9
Re: Esp32 / freeRTOS using fpcupdelux
« Reply #10 on: January 09, 2025, 08:29:13 am »
Dear CCrause,

you did a great job.
My Esp32 is running a "Hello World" application written in Lazarus while communicating through the USB port!
This is a good starting I can build on.

Best regards, Anthony.

ccrause

  • Hero Member
  • *****
  • Posts: 1018
Re: Esp32 / freeRTOS using fpcupdelux
« Reply #11 on: January 09, 2025, 09:25:31 am »
Quote
I did: unselect Display line numbers in run-time error backtraces (-gl)
and compiled again.
Now I have the error: /home/ajv/bin/fpcupdeluxe/esp32/cross/bin/xtensa-freertos/bin/xtensa-esp32-elf-lc: can not find libcoexist.a
I do have: /home/ajv/bin/fpcupdeluxe/esp32/cross/lib/xtensa-freertos/lx6/esp32/libcoexist.a
the messages output is in attached file fpc_messages_3.txt

At least the other SDK libraries are found. libcoexist is a bit of a problem, since it was introduced as a dependency on the FPC side after the fcupdeluxe snapshot for esp32 was finalised.  This will have to be updated on fpcupdeluxe's side to be consistent with the compiler.

In case someone else also runs into this issue, here is a manual fix to add libcoexist to the fpcupdeluxe version of esp-idf v4.3.2:
* Download libcoexist.a
* Copy libcoexist.a into FPCUPDELUXE_ROOT/cross/lib/xtensa-freertos/lx6/
Nothing else needs to be adjusted, the linker should now find this library.

ajvperth

  • New member
  • *
  • Posts: 9
Re: Esp32 / freeRTOS using fpcupdelux
« Reply #12 on: January 09, 2025, 10:11:32 am »
or in Compiler options |  Paths | Other Unit files:
$ProjPath/../cross/lib/xtensa-freertos/lx6/esp32/ if you develop your application in the projects directory
b.t.w. I do this to have a fixed location for the .bin file to flash the Esp32 using a script.  ;-)

 

TinyPortal © 2005-2018