Awake from sleep: Tickless Idle Mode

Dear FreeRTOS folk.

I’m working on a FreeRTOS port for ATmega1284P and trying to save as much power as possible in the Tickless Idle Mode, but an obstacle appeared.

For example, I’ve a “Sleep Mode” task which suspends all of the other tasks after an initially selected timeout passed and suspends itself to let the Idle task be the only one which is able to run. There are no timers and any other tasks are blocked with an infinite timeout.

And this eventually leads to the implementation of the portSUPPRESS_TICKS_AND_SLEEP() macro which puts my MCU to sleep. How should I let the tasks know that this implementation returns back from sleep?

Does it mean that I’d rather handle an external interrupt which awakes my MCU and resume a required task from its ISR?

Thanks for any help.

That would be one way of doing it.

Our implementations don’t place tasks into the suspended state though, it just looks for a pre-defined period of time during which no tasks will execute then
re-programs the clock to wake up from sleep mode when the next task wants to run - so the tasks just run at the times they would have done had the system not gone into a sleep mode at all.

For example, if the tick executes every 1ms, and all tasks other than the idle task are in the blocked state, and the nearest time a task will leave the blocked
state is 5000ms in the future, then the timer used to generate the tick is re-programmed to instead generate an interrupt in 5000ms. That timer interrupt brings the system out of sleep and the task executes immediately because the time at which it leaves
the blocked state has been reached. The timer is then re-programmed to generate ticks every 1ms again.

Hi Richard,

What if I don’t know this period of time at all?

You could imagine a device with a screen and several buttons which isn’t supposed to do anything after a timeout when user didn’t press any button.

I’d like to be able to put the device to the deepest sleep mode possible and awake it when any of the buttons will be pressed (assume that they can generate their own interrupts which are able to wake the MCU up).

Btw, I’ve written my own implementation of the portSUPPRESS_TICKS_AND_SLEEP() macro, so I don’t do any clock re-programming there.

Ah! You meant implementations provided by the FreeRTOS distribution itself. I may implement it in a way I prefer.

Thanks for your help :slight_smile: I haven’t expected any help to come that fast.

Doesn’t sound like you need it in your case, but if you did, then prvGetExpectedIdleTime() dives you the next expected execution time.

In your case though, if all tasks are blocked indefinitely, then your original suggestion of unblocking a task from which ever interrupt brought the system out
of sleep mode would seem reasonable.