FreeRTOS notes

FreeRTOS is closer to an operating system toolkit than an operating system proper, that’s why the FreeRTOS port provides only functionality that FreeRTOS itself provides out of the box, which isn’t much.

All the libuv API functions are still there but they return UV_ENOTSUP when something is unsupported.

Things that work:

Things that don’t work (this list is not exhaustive):

Libuv functions are not ISR-safe, not even uv_async_send().

YMMV on 8-bit or 16-bit systems.

Libuv tries its level best to run correctly on systems with unusual tick rates, like 333 Hz.

Libuv uses index configTASK_NOTIFICATION_ARRAY_ENTRIES - 1 (usually 0) for bookkeeping. Build with -DUV_FREERTOS_NOTIFY_INDEX=<n> to use another index.

Threads created with uv_thread_create() and uv_thread_create_ex():

  • Inherit the priority of their parent thread; if the scheduler hasn’t been started yet, priority tskIDLE_PRIORITY + 1 is used instead.

  • Get a 128 KiB stack by default; see the UV_THREAD_HAS_STACK_SIZE option of uv_thread_options_t.

  • Should not call vTaskDelete(NULL). See uv_thread_join() and uv_thread_detach().

Build libuv with -DUV_FREERTOS_TLS_BASE=<n> and -DUV_FREERTOS_TLS_SIZE=<n> to limit the range of thread-local keys. The default range is 0..configNUM_THREAD_LOCAL_STORAGE_POINTERS-1 but that leaves no space for other parts of your program that depend on thread-local storage.

Libuv requires the following FreeRTOS build options and errors if they are not set:

  • INCLUDE_uxTaskPriorityGet

  • INCLUDE_vTaskDelay

  • INCLUDE_vTaskDelete

  • INCLUDE_vTaskSuspend

  • INCLUDE_xTaskGetSchedulerState

  • configUSE_COUNTING_SEMAPHORES

  • configUSE_MUTEXES

  • configUSE_TASK_NOTIFICATIONS

Supported but not required:

In your CMakeLists.txt, include FreeRTOS before libuv. Libuv’s build scripts will then auto-detect FreeRTOS and do the right thing. If that’s not an option, set LIBUV_BUILD_FOR_FREERTOS=ON explicitly. Building with autotools is not supported.