Currently I’m working about a possible way to manage the sleep modes in FreeRTOS. Since even other companies use sleep modes to manage the power management, I thought to adopt a strategy common to all. Below, it is a sum up about my idea.
Sleep Mode for tasks
Basically, inside in each task’s body the user can define the sleep mode to go in for the next idle tasks ( using PMSetSleepMode) and the Power Framework will choose only that sleep mode in common among tasks.
Sleep mode for ISRs
An example: If two tasks request to stay in sleep mode 2 and just before to go in idle task, an interrupt occurs, then can be the case that the sleep mode chosen is not longer valid after ISR’s execution. For this reason, we need to define an API to choose the sleep mode also for ISR.
But in this case we have the necessity to know for how long we have to keep the sleep mode chosen by ISR. This is an important case, in fact if many ISRs occur (each ISR defines a different sleep mode) the system before to choose a sleep modes must be sure that it doesn’t go in a wrong one.
For instance: ISR1 wants to stay in Sleep Mode 1 (because the ISR2 is triggered by a peripheral of Sleep mode 1), then when ISR2 occurs, the system can go in sleep mode 2. Thus, the system can’t understand for how long a sleep mode can be kept valid. To cope this issue, a function “PMLockSleepMode” defines a starter point of a sleep mode and another function “PMUnlockSleepMode” defines the end of that sleep mode. The idea is to freeze the sleep mode for a while. The user can unlock the mode in another ISR or in a Task.
If we don’t want to freeze the sleep mode, we can use the function “PMSetSleepModeISR”. After invocation of this function, the system keeps valid the sleep mode only until the end of first idle task. For the following idle tasks the sleep mode is discarded.
Power Management Framework
+ PMSetSleepMode (unsigned char mode) ==> Set a sleep mode for that task (sleep mode is used in next idle tasks);
+ PMSetSleepModeISR (unsigned char mode) ==> Set a sleep mode for that ISR (sleep mode is used only for next idle task);
+ PMGetSleepMode () ==>Returns the current sleep mode where the system can go to. The sleep mode depends from the requests done by other tasks or ISRs. This function is used only inside tasks body;
+ PMGetSleepModeISR() ==>Returns the current sleep mode where the system can go to. The sleep mode depends from the requests done by other tasks or ISRs. This function is used only inside ISRs body;
+ PMLockSleepModeISR (unsigned char mode) ==> Lock a sleep mode inside an ISR. The lock can be done only inside an ISR. A sleep mode can be locked for many times (max 256). A further version of this function might be to lock a sleep mode for a duration of time given in input;
+ PMUnlockSleepModeISR (unsigned char mode) ¬==> Unlock a sleep mode from an ISR.
+ PMUnlockSleepMode (unsigned char mode) ==> Unlock a sleep mode from a task.
+ PMIdleSleepMode() ==> Returns the suitable sleep mode for idle task. This function is invoked inside idle task, it is used before to go in sleep mode.
+ PMGoToSleep (unsigned char mode) ==> This function pushes the MCU in sleep mode taken in input.
Actually, I’ve developed an implementation about this power framework for Energy Micro. For me it is really important to get feedback and suggestions to improve my work.