How can I use vTaskDelay in my libraries?

I have a main file which creates the tasks, starts the scheduler, etc.
I also wrote functions to control LEDs, sensors, etcetera. I want to move those functions to their own files and folders, e.g., /lib/leds/src/led_strips.c
However, those functions need delays. How can I use vTaskDelay from a library?
Should I add the whole freertos through cmake to each library?
Even if I did that, will the scheduler work properly? For example, will it know to execute other tasks while the LED is blinking?

EDIT: Would passing vTaskDelay as a parameter work? would that passed function be compatible with the scheduler? Any alternative solution is also welcome.

You shouldn’t need to add the entire FreeRTOS Kernel source to each library. You will need to do two things to make vTaskDelay accessible.

First - You will need to make sure the tasks.h header file, which declares the vTaskDelay function, and any header dependencies it has (which there aren’t many 1, 2) are satisfied. If you’re using CMake, you can do this using the target_include_directories command.

Second - You will need to compile the required FreeRTOS source files (notably tasks.c) with the libraries when the libraries are being built.

Now alternatively, your project might already be using CMake and youcould simply consume the FreeRTOS Kernel as a library through CMake.


By doing the above, you’ve made the vTaskDelay() function available to your library files. These library functions can then be called with the scheduler running and will successfully delay for the time period you specify.

As for your other questions…

Even if I did that, will the scheduler work properly? For example, will it know to execute other tasks while the LED is blinking?

FreeRTOS runs a single task at a time. What I think you want to do is to have a task which toggles the LED from either on->off or off->on that runs at an interval. While the toggle task is running, no other task will run however if you delay between iterations of this toggle task using vTaskDelay then your other waiting task(s) will be ran in priority order.

With the change you’ve specified the scheduler will still work properly. The scheduler only executes the highest priority unblocked task at a time. As long as your LED task blocks between calls, other tasks will execute.

Would passing vTaskDelay as a parameter work? would that passed function be compatible with the scheduler? Any alternative solution is also welcome.

You can pass vTaskDelay as a function pointer if you’d like but simply including task.h into your library file and using vTaskDelay as a normal function will be more readable.

Hi Kody,
Thank you very much for your explanation. I include my solution below. I tested it and it works, but please let me know if there’s anything I could have done better.

So in led_strips.h I included these headers:

#include <FreeRTOS.h>
#include <task.h>

And in the CMakeLists.txt file, located where led_strips.c is, I added:

add_library(LedStrips led_strips.c $ENV{FREERTOS_PATH}/FreeRTOS-Kernel/tasks.c)

target_include_directories(LedStrips PRIVATE $ENV{FREERTOS_PATH}/FreeRTOS-Kernel/include)
target_include_directories(LedStrips PRIVATE $ENV{FREERTOS_PATH})
target_include_directories(LedStrips PRIVATE $ENV{FREERTOS_PATH}/FreeRTOS-Kernel/portable/GCC/ARM_CM0)

target_link_directories(LedStrips PRIVATE $ENV{FREERTOS_PATH}/FreeRTOS-Kernel)
target_link_directories(LedStrips PRIVATE $ENV{FREERTOS_PATH}/FreeRTOS-Kernel/portable/MemMang)
target_link_directories(LedStrips PRIVATE $ENV{FREERTOS_PATH}/FreeRTOS-Kernel/portable/GCC/ARM_CM0)

I feel like I had to add a bunch of directories to make it work. That’s why I’m wondering if there was a better way.

Nothing is looking out of place to me…The directories you’ve added all make sense. Tasks require a heap for object creation (found in MemMang) which in turn requires your port allocation (found in your GCC/ARM_CM0 directory). If it works, I’d say you’re good :slight_smile:

To add another option which isn’t necessarily a better way (but simply a different way you can go if you want) would be to use the FetchContent CMake functionality to download the Kernel and make it’s content available. This may include some extra files which could slow down your build though.

1 Like

Thank you very much for your help.

1 Like