FreeRTOS System / Task Management Strategy

hirohiro wrote on Sunday, November 03, 2019:

Hey all, I’m looking for a little guidance on how to implement a system controller in the RTOS environment. To give a bit of context, the basics are that I have an embedded system running on a cortex M3 with a few tasks managing various components of the system.

  1. Sensor Task - configure/handle accelerometer
  2. CLI Task - logging, commanding
  3. Radio Task - Manage BLE radio
  4. System Task - Overall system control.

Generally each task is responsible for it’s own domain, while the system task monitors system level things like battery level, charging, switching between system modes, etc. One case in particular that I’m having trouble with is entering a deep sleep state. The device needs to go into a very lower power “shelf mode” to preserve battery. In order to this all the tasks need to cleanly stop what they are doing, put their peripherals/GPIOs into a low power state, set-up wake conditions and then stop execution. Conversely when waking up all the tasks need to be reinitialized, the peripherals reconfigured and the tasks restarted.

What’s the recommended way to accomplish this? Is there a FreeRTOS mechanism to bring down/stop a task, or to reuse the startup function when waking up from sleep? How do I trigger this process from the system state- should I have a state machine in each task that handles transitioning itself? Is it better to simply trigger a system reset and let everything come up clean?

Any thoughts on the architecture/implementation for this would be much appreciated!

rtel wrote on Sunday, November 03, 2019:

The default tickless low power mode allows you to have application
defined pre and post sleep macros that can be used to do things like
turn peripherals off pre sleep and on again post sleep - but it doesn’t
go through each task individually allowing the task to do its own thing
so either you would need to have the tasks register a callback that the
pre-sleep macro can call, or just do the power down centrally. If the
tasks are to re-start from the beginning again on wake up then you could
also use the presleep macro to just delete the tasks.

richard_damon wrote on Sunday, November 03, 2019:

Generally for this sort of state, you need to send a notification to each task telling it to shut down, and the task checks that flag as part of it normal control loop and diverts to shutdown code, they then send back a notification that they are done and ready to shut down.

For a shutdown as deep as your seem to be describing, the procesor often comes out of it via a reset, so you will naturally go through your startup code, and perhaps you can detect this action and perhaps bypass some of the initialization which doesn’t need to be performed by instead use some saved state that was kept through the shutdown.

hirohiro wrote on Sunday, November 03, 2019:

Thanks guys, it seems like I will indeed need some sort of state tracking in each task then.

rtel wrote on Sunday, November 03, 2019:

This can help in implementing something as per Richard D’s suggestion.