I would like to have a set number of things happen when the idle task is called. I put my board to sleep when there is nothing to do (loops in idle mode right now). The problem with just sticking all the power down steps in the idle task is that this task is jumped into and out of from any point within. I need to have a set number of steps occur before putting the micro into lpm3 (MSP430).
Whats a good way fo going about this?
Oh ya, I am not just calling lpm3, but talking to external hardware to shut it down (and other stuff). So there is an important order to the shutdown task.
For something like this, I would use an idle hook function, and in that function enter a critical section, and inside that section quickly check that it really is time to go to sleep (and not just that all the other tasks are just temporarily busy), if not time, quickly end the critical section, but if it is time, perform the shutdown. Depending on the condition that will be used to wake you up, you probably need to end the critical section just before actually going to sleep.
close, I don’t know that processor, and the definition of “sleep” varies by processor and application.
pseudo code:
idle hook function (will be called periodically by the idle task) {
Enter Critical Section
if(ok to go to sleep) {
prepare system to go to sleep
enter sleep state
wake system up from sleep state
end critical section
} else {
end critical section
maybe go to idle state if one is available
}
}
Note that if you need an interrupt to wake you up from the sleep state, and the critical section disables that interrupt, the prepare to go to sleep may need to end with a exit critical section or at least re enabling that interrupt.
I am assuming that the sleep being talked about here is a significant shutdown state that may take some time to recover from (restarting clocks and the like) and may disable some peripherals, so should only be entered when conditions are right for it. I have added an “Idle” routine, if the processor supports it, that saves a bit of power by stopping the processor until an interrupt occurs (if we are in the idle task, nothing else is going to be able to execute until an interrupt occurs anyway, might as well let the processor take a break). If you have other tasks at the idle priority that can use the time productively, then you can skip the idle state.
There is a lot to think about. Mostly because i need to keep a certain interrupt enabled when going to sleep, but when waking on that interrupt, service my powerup routine before i service that said interrupt.
As I said, the prepare system to go to sleep will probably end with enabling some needed interrupts. If the interrupt processing function itself needs to fully wake up the processor, then you may need to have a flag that the enter sleep routine sets, so that the interrupt know that IT needs to do the wake up (and it can clear the flag so the code in the idle hook know enough to not do the wake up it self too.)
It may be possible to make the interrupt to just a bit of minimal processing that could be done in the native “just woke up state” and do something to wake up a task to do most of the work,
Thinking about this, part of the “preparing to go to sleep” routine will need to be disabling the scheduler, and re-enabling it AFTER you do all the wake up code, otherwise some other task might get started before you wake up everything.