Common Mistakes When Using FreeRTOS
main() Stack Overwritten When vTaskStartScheduler() Called
Be warned, the stack used by main()
could potentially be overwritten as soon as vTaskStartScheduler()
is called. This is true is using a Cortex-M3 and interrupts, as the interrupts use the same stack space as main()
.
This is shown in the following example:
Accessing variables created in main()
from tasks could result in segmentation faults. This is not what you would expect, as you have probably learnt that variables stay valid as long as they are still in scope, and since main()
never exits, the variable should still be valid! However, FreeRTOS re-used main()
’s stack to save space. This is what the FreeRTOS website had to say (take in July 2014):
Recover the stack used by
main()
. The stack used upon program entry is not required once the RTOS scheduler has been started (unless your application callsvTaskEndScheduler()
, which is only supported directly in the distribution for the PC and Flashlite ports, or uses the stack as an interrupt stack as is done in the ARM Cortex-M and RX ports). Every task has its own stack allocated so the stack allocated tomain()
is available for reuse once the RTOS scheduler has started.
Interpreting portTICK_RATE_MS Incorrectly
What causes this confusion is that portTICK_RATE_MS
is incorrectly named. It doesn’t represent the number of ticks per millisecond as the name suggests, but rather the number of milliseconds per tick. A better name would be portTICK_PERIOD_MS
.
The incorrect way of using portTICK_RATE_MS
to delay the current task for 400 milliseconds would be:
The correct way would be: