Search code examples
freertoscortex-msleep-mode

FreeRTOS is slow to wake after long processor sleep


(Cross-posted on Electrical Engineering Stack Exchange)

I'm using FreeRTOS in an application which requires the processor to sleep in low power mode for a long time (as long as 12 hours), then wake up in response to an interrupt request. I'm having a problem with the amount of time taken for FreeRTOS to wake up.

Before going to sleep, I disable the scheduler through a call to vTaskSuspendAll().

On waking, I calculate the amount of time that the processor has been asleep, and update FreeRTOS via a call to vTaskJumpTime(). I then make a call to xTaskResumeAll() to restart the scheduler.

The issue I have is that xTaskResumeAll() makes a call to xTaskIncrementTick() once for each tick that has been missed while the processor was asleep (recorded through vTaskJumpTime()). It takes about 12 seconds to wake after an hour asleep (3,600,000 calls to xTaskIncrementTick()).

Much as I'm tempted to modify the FreeRTOS xTaskIncrementTick() function, so that it can jump a number of ticks in one call, experience says that I would be smart to look for a standard way first.

Has anyone found another way to implement this behavior which doesn't result in the long wake-up delay?

This is implemented on an Microchip/Atmel SAM4L (Cortex-M4). I use the AST sub system to record the time that the processor is asleep. The sleep is implemented through BPM sub system bpm_sleep() in RETENTION mode.


Solution

  • FreeRTOS's built in low power support uses vTaskStepTick() to jump the tick count forward in one go. It can do that because it won't calculate a wake time (the time at which it leaves low power mode) past the time it knows a task must unblock because a timeout expired. If you remain in sleep mode past the time a task should have unblocked because its timeout expired you have an error anyway. The best place to get FreeRTOS support is it's dedicated support forum.