G2Labs Grzegorz Grzęda
Developing with FreeRTOS on ESP32: Multitasking and Synchronization
June 12, 2024
Developing with FreeRTOS on ESP32: Multitasking and Synchronization
Welcome back to our ongoing series on developing with FreeRTOS on the ESP32 microcontroller. In the previous posts, we have looked at the basics of FreeRTOS as well as task management. Today, we will dive deeper into multitasking and synchronization techniques with FreeRTOS on ESP32.
Multitasking with FreeRTOS
Microcontrollers often require handling multiple tasks simultaneously. FreeRTOS allows us to implement multitasking efficiently. Each task in FreeRTOS has its own stack, program counter, and registers. The tasks may run concurrently or be scheduled by the RTOS kernel.
Let’s consider a scenario where we need to blink an LED and monitor a button simultaneously. We can handle these tasks in separate FreeRTOS tasks.
|
|
Here, we define ledTask
and buttonTask
as separate tasks, each performing its respective job. The vTaskDelay
function is used to suspend the task for a given number of milliseconds.
In your setup
function, you can create these tasks using xTaskCreate
:
By creating the tasks, we ensure that the LED and button tasks run concurrently without blocking each other.
Synchronization with FreeRTOS
Often, tasks need to synchronize their activities or share resources. FreeRTOS provides various synchronization primitives that allow tasks to communicate and cooperate efficiently.
Mutex
Mutexes (mutual exclusions) are the most commonly used synchronization primitive. They protect shared resources from simultaneous access by multiple tasks.
|
|
In this example, mutex
is created using xSemaphoreCreateMutex()
. Each task then acquires the mutex using xSemaphoreTake()
before accessing the shared resource and releases it using xSemaphoreGive()
afterward.
Semaphores
Semaphores are used for signaling between tasks. They ensure that tasks proceed based on specific events or conditions.
|
|
Here, we use xSemaphoreCreateBinary()
to create the semaphore. Task 2 periodically signals the semaphore using xSemaphoreGive()
, and Task 1 waits for the semaphore using xSemaphoreTake()
. This allows Task 1 to proceed only when signaled by Task 2.
Queues
Queues enable communication between tasks by allowing them to send and receive messages.
|
|
In this example, queue
is created using xQueueCreate()
. Task 2 sends data to the queue using xQueueSend()
, and Task 1 receives data from the queue using xQueueReceive()
. This allows tasks to exchange data or information asynchronously.
Conclusion
Using FreeRTOS on ESP32 allows us to efficiently develop multitasking applications with synchronization mechanisms. We explored multitasking with separate tasks as well as synchronization techniques using mutexes, semaphores, and queues. These tools empower us to design robust and responsive embedded systems.
In the next post, we will look at interrupt handling with FreeRTOS on ESP32. Stay tuned!
Happy coding!