FreeRTOS Advanced topics ¶
This section explains the most useful advanced FreeRTOS features on STM32, shows when to use them, and highlights key design practices for building robust, deterministic, and maintainable applications.
1. Architecture Guidelines ¶
A clear architecture makes FreeRTOS applications easier to scale, test, and debug.
Recommended patterns
Assign one clear responsibility per task
Keep ISRs minimal and move processing into tasks
Combine DMA with task notifications
Avoid blocking HAL calls in time-critical tasks
Use an asynchronous logging task fed by a queue
2. Priorities and Scheduling ¶
Set task priorities carefully to preserve responsiveness and avoid starvation.
Simple priority model
High priority: real-time acquisition, short deadlines
Medium priority: main processing
Low priority: logging, diagnostics, background work
Common mistakes
Assigning high priority to too many tasks
Running endless loops without vTaskDelay(), blocking calls, or event waits
Sharing resources without protection
Practical tip
Use mutexes when tasks share resources, because mutexes support priority inheritance and help reduce priority inversion.
3. Task Notifications ¶
Use task notifications as a lightweight alternative to semaphores, queues, and event groups for direct task signaling.
Typical use cases
Wake up a task from an ISR
Signal DMA transfer completion
Count fast events with very low overhead
Why use them
Minimal memory footprint
Fast execution
Built into each task
Best practices
Prefer vTaskNotifyGiveFromISR() with ulTaskNotifyTake() for simple producer/consumer patterns
Use xTaskNotify() when you need bitwise flags or custom update modes
Call portYIELD_FROM_ISR() when the awakened task must run immediately
4. Queues, Stream Buffers, and Message Buffers ¶
Use queues for fixed-size items and structured inter-task communication. Use stream buffers and message buffers for byte streams or variable-length payloads.
How to choose
Queue: fixed-size elements, commands, small data objects
Stream Buffer: continuous byte stream such as UART RX
Message Buffer: variable-size messages
STM32 tips
With UART DMA, for example, let the ISR or HAL callback notify a worker task
Keep parsing and protocol handling out of HAL callbacks
Send pointers through queues instead of copying large buffers
5. Event Groups ¶
Use event groups when a task must wait for multiple events or when several tasks share common status flags.
Typical use cases
Synchronize startup of multiple subsystems
Wait for several software or hardware conditions
Represent simple global states
6. Software Timers ¶
Use software timers to schedule delayed or periodic actions without creating one task per timeout.
Good practices
Keep timer callbacks short and non-blocking
Avoid blocking API calls inside callbacks
Use timers for supervision, retries, timeouts, and light periodic checks
Attention
FreeRTOS executes timer callbacks in the timer service task. If that task runs at a too low priority, timer latency will increase.
7. Static and Dynamic Memory Management ¶
FreeRTOS supports several heap implementations ( heap_1 to heap_5) and also supports static object creation.
Recommended approach on STM32
Prefer static allocation in safety-critical or production-grade designs
If you use dynamic allocation, select the heap strategy deliberately and control all allocations centrally
Measure stack usage with uxTaskGetStackHighWaterMark()
Useful safeguards
Enable:
8. Interrupts and FromISR APIs ¶
Keep STM32 interrupt handlers short and defer heavy processing to tasks.
What to do
Use the …FromISR API variants
Signal a dedicated processing task from the ISR
Verify configMAX_SYSCALL_INTERRUPT_PRIORITY
Critical STM32 note
Incorrect NVIC priority configuration can cause hard-to-debug failures, lockups, or data corruption. Align STM32, CMSIS, and FreeRTOS priority settings carefully.
9. Tickless Idle and Low Power ¶
Enable tickless idle to reduce power consumption when the system stays idle.
Validation points
Check the impact on timing accuracy
Validate wake-up sources such as RTC, EXTI, or peripherals
Test interactions with HAL, SysTick, and low-power clock sources
10. Debug, Trace, and Runtime Diagnostics ¶
Instrument the system early so you can observe behavior under real load.
Useful tools