Compiling FreeRTOS with FreeRTOS-POSIX on ESP32 failes

Hi,

I’m trying to build FreeRTOS with an additional POSIX layer for my ESP32 project. For this I’m using the FreeRTOS-POSIX lab project. However, I have an awful amount of errors when comping because ESP-IDF already has some POSIX support build in. The FreeRTOS_POSIX_portable.hdoes try to mitigate this and excludes certain headers from being included but there are a variety of issues that I can’t seem to get around to.

I originally posted this on the FreeRTOS-POSIX lab GitHub page as an issue. But they redirected me to this forum instead.

Below is copied from the original GitHub issue

I’m having some trouble getting this to work with an ESP32 (w/ ESP-IDF 4.1). There seems to be all kinds of missing headers and deprecated function calls. After modifying the source code I got some part to compile, but now I’m stuck on a number of problems, and I’m not sure if I’m doing something wrong.
Like:

  • implicit declaration of function xSemaphoreCreateCountingStatic
  • error: ‘errno’ undeclared (could be easily fixed with #include “errno.h”)
  • #include "Atomic.h" not found
  • #include "FreeRTOS.h" instead of #include "freertos/FreeRTOS.h"
  • taskENTER_CRITICAL(); missing mux argument.
  • int sched_get_priority_max( int policy ); not implemented by ESP-IDF while shed.h is disabled in FreeRTOS_POSIX_portable.h
  • Pthread types header from FreeRTOS_POSIX is read instead of ESP-IDF while the FreeRTOS-POSIX pthread header is disabled in FreeRTOS_POSIX_portable.h causing failed to find declarations.
  • There are some more, but I can’t remember them right now.

I might have done something horribly wrong and that it is all my fault, but the issues just seem to keep piling up, and I thought you guys might have a better idea what is going on. My CMakeLists.txt looks like this:

idf_component_register(
        SRCS
        "FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_pthread.c"
        "FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_semaphore.c"
        "FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_clock.c"
        "FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_timer.c"
        "FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_utils.c"
        "FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_mqueue.c"
        "FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_pthread_barrier.c"
        "FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_sched.c"
        "FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_unistd.c"
        "FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_pthread_mutex.c"
        "FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_pthread_cond.c"

        INCLUDE_DIRS
        "include/FreeRTOS_POSIX"

        PRIV_INCLUDE_DIRS
        "FreeRTOS-Plus-POSIX/include"
        "FreeRTOS-Plus-POSIX/include/portable"
        "FreeRTOS-Plus-POSIX/include/portable/espressif/esp32_devkitc_esp_wrover_kit"
        "include"
        "include/private"
        "/home/noeel/esp/esp-idf-v4.1/components/freertos/include/freertos"

        PRIV_REQUIRES pthread newlib
)

unmodified source code build log looks like this

Hi @Noedel-Man,

I have begun digging into this and made some decent progress. I hope to have a working example to share with you early next week.

To address some of your questions in the meantime:

  1. To have access to xSemaphoreCreateCountingStatic you will need to modify the FreeRTOS component with the ESP idf menuconfig command. There is a checkbox to enable static FreeRTOS API.
  2. Atomic.h was introduced in FreeRTOS v10.3, whilst ESP IDF is using FreeRTOS V8.2.0, so you will need to swap atomic operations to critical sections. I have begun doing this work, and should be relatively trivial, as you basically just wrap similar logic in a portENTER/EXIT_CRITICAL() block
  3. On the ESP32 port for IDF v4.2 (I am sorry I am using v4.2 to make my example, I can downgrade if this ends up being an issue, but it was what we are using in our other codebase), the critical section needs a mux to support SMP, an example can be found here in the ESP GPIO driver https://github.com/espressif/esp-idf/blob/2532ddd9f447f6fab02bc2d1654534a7621e033a/components/driver/gpio.c#L57. All you must do is create this static portMUX_TYPE spinlock object, and pass it as a pointer. Note that you will need to swap taskENTER/EXIT_CRITICAL() to portENTER/EXIT_CRITICAL().

I have not yet dug into the rest of your issues, but will post a reply here again on Monday with more progress.

Thanks,

Carl

Thank you Carl for your quick reply and swift research. I was worried that I skipped something trival but I’m relieved that it was not my fault :blush:.

  • ESP-IDF 4.2 should be fine, I could upgrade if need be.
  • If I remember correctly FreeRTOS could also be disabled in menuconfig allowing us to use the upstream version of FreeRTOS with support for atomic.h. This would also mitigate some other problems I think.
  • Maybe we could collaborate on this on git? otherwise we would both try the same fixes.

Hi @Noedel-Man,

Using the FreeRTOS distribution instead of the one in the ESP IDF will have caveats as some features won’t be available, eg. GDBStub, SMP, etc. I ended up porting it to the modified ESP FreeRTOS code hosted in the ESP IDF v4.2.

I have created a branch on my fork here https://github.com/lundinc2/esp-idf/tree/posix-port with my changes. I had to modify the FreeRTOS+POSIX library as well in order to get a compiling version, and you can see those changes reflected in the submodule pointing to my fork of the POSIX code. I also needed to backport some minor changes to the kernel that were introduced for POSIX.

I modified the IDF hello world example https://github.com/lundinc2/esp-idf/tree/posix-port/examples/get-started/hello_world to compile the POSIX code, and then run the POSIX demo found at https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_POSIX/demo/posix_demo.html. Running this code requires just navigating to the hello_world directory, and running idf.py flash monitor.

The code compiles and the demo runs, but there is some ugliness left, nonetheless I hope you found this example helpful. This is still a work in progress, so if you have any feedback / changes to share I would be happy to see it.

It would be good to hear about your use case for this library, as it is still in the Labs project state.

Thanks,

Carl

Hi Carl,

Very nice results! I have read your changes and I’am wondering if we could somehow make them avaliable upsteam. The changes to ESP-IDF seem very minimal, maybe makeconfigUSE_POSIX... avaliable via the make menuconfig menu?
I will ask RichardBarry for his input as well. Anyway thank you so much for your time.

It would be good to hear about your use case for this library, as it is still in the Labs project state.

I’m creating a cross-platform library for embedded devices and would like it only use POSIX