FreeRTOS Concurrency - MisterRager/Codelab-Indicator-Lights GitHub Wiki
FreeRTOS Concurrency: Tasks
/**
* Using a FreeRTOS task, display a spinning rainbow on the LED ring.
*/
void animate_ring_rotate(struct led_state *ring_ptr);
/**
* Stop the "spinning rainbow" task.
*/
void stop_animate_ring_rotate();
This couplet of functions uses a FreeRTOS task to create an animation effect in the background. Tasks are the way FreeRTOS managed concurrency (multi-tasking). Each task has its own stack, a parameter provided on launch, and access to the same global and static variable space as any other task.
xTaskCreate(
task_spin_ring,
"LED Spinner",
4096,
ring_ptr,
5,
NULL);
Tasks are launched by calling xTaskCreate from freertos/tasks.h and generally run indefinitely. Here, the function task_spin_ring is called with ring_ptr cast to a void * as its one argument. It has been launched with a stack depth of 4096 and priority of 5. Since the last parameter is NULL, no handle is held onto for managing the task.
static void task_spin_ring(void *args)
{
...
ESP_LOGI(TAG, "Stopped spinning");
xEventGroupClearBits(group_handle_spin_ring, BIT_STOP_SPIN | BIT_IS_SPINNING);
vTaskDelete(NULL);
}
When a task function is allowed to exit, be sure to clean up any state that is associated with it: free your mallocs, toggle any bits, and above all, call vTaskDelete(NULL), else the device will crash.
The other concurrency primitive being used is the event group (see freertos/event_groups.h). Event groups are used to send signals to tasks. They are implemented as a bitfields to be queried through provided functions:
xEventGroupGetBits: read the current state of the groupxEventGroupSetBits: flip bits onxEventGroupClearBits: flip bits offxEventGroupWaitBits: observe the specified bits, and resume either when they are set or after the limit is expired