Energy Saving Modes

Hello,

I am currently looking into FreeRTOS because I write my BA thesis about different IoT-OS. One of the topics that I want to compare those is energy management, especially energy saving modes (sleep mode, deep sleep mode etc.). Can someone maybe give me a short introduction on how this is done in FreeRTOS? If I understand it correctly, there aren´t sleep modes, instead this is done with the idle task hook.

Thank you for helping me out!

and

provide some more details.

1 Like

@hs2 linked you exactly what you should need!

In summary some MCUs have a lower power mode and can be placed into this mode when work isn’t being done. While the FreeRTOS tick isn’t much work to a chip, it is periodic work which has to happen. This periodic work can prevent a lower power mode. To help reduce power consumption FreeRTOS offers tickless idle. Tickless idle does not require a tick interrupt which in turn saves the work of running the interrupt, in turn allowing the MCU to be placed into it’s power saving state when the idle task would have ran instead.

1 Like

The page on tickless idle for the Cortex M0 says there are two macros that get called either side of a WFI instruction and there is talk of an “expected idle time”. In my application, I do no time calculations that span an idle time so I do not really care if the “ticks since boot” value is correct long term. Wakeup happens from a GPIO transition interrupt. It says that if I use ExpectedIdle=0 then the WFI is not executed. So in that case do I just call WFI myself at the end of my configPRE_SLEEP_PROCESSING macro?

You are likely taking about this code block:

            configPRE_SLEEP_PROCESSING( xModifiableIdleTime );

            if( xModifiableIdleTime > 0 )
            {
                __asm volatile ( "dsb" ::: "memory" );
                __asm volatile ( "wfi" );
                __asm volatile ( "isb" );
            }

            configPOST_SLEEP_PROCESSING( xExpectedIdleTime );

If the implementation of configPRE_SLEEP_PROCESSING does not want to call WFI, it can set the parameter xModifiableIdleTime to zero:

/* ShouldSleep determines when to call WFI. */
#define configPRE_SLEEP_PROCESSING( xModifiableIdleTime )   \
    {                                                       \
        if( ShouldSleep( xModifiableIdleTime ) == pdFALSE ) \
        {                                                   \
            /* Do not call WFI. */                          \
            xModifiableIdleTime = 0;                        \
        }                                                   \
    }

If you want to call WFI, you should not set xModifiableIdleTime to 0.