Using the LPMs is a bit tricky. To keep awake after the ISR returns, the ISR needs to modify the stack content, so that on exiting the ISR the status register is NOT reloaded from stack with LPM set. Using a task-switching OS might cause some problems, as task switching usually is done by stack switching and therefore the wrong return value might be manipulated. If your timer interrupt that wakes from LPM is also handling the task switching, you MUST ensure that the LPM bits are cleared on the threads stack you want to exit to 'awake' and remain set on all threads that shall continue sleeping. Also, some of the processors have problems with the instruction right after entering LPM (check the errata sheets).
Normally, the OS that handles the thread switching should also handle LPMs itself and you shouldn't enter LPM yourself but call something like ThreadSleep() when the thread shall sleep (other threads might choke if the processor goes unexpectedly into sleep mode). If no thread is currently running, the OS should activate LPM by itself. If there are different sleep modes, every thread should specify in which sleep mode it wants to sleep (in case it uses some active hardware that won't like some deeper modes) and the 'lightest' sleep should be chosen by the scheduler. In your case, it seems that the idle loop is a separate thread (with its own stack) that enters sleep mode and never leaves it again. When the task switching ISR returns to the idle loop, the LPM is reactivated. If it returns to one of the 'active' tasks, the processor remains active, as the status register is restored from 'their' stack and does not have the LPM flags set.. If you add debug code to your idle loop, you'll surely notice that it won't run at all. But as it is an idle loop, this is not a problem. JMGross ----- Ursprüngliche Nachricht ----- Von: Bernard Mentink An: GCC for MSP430 - http://mspgcc.sf.net Gesendet am: 01 Mrz 2009 22:29:59 Betreff: [Mspgcc-users] Interrupt issues Hi All, I have an MSP430 application running on top of the excellent QF (quantum framework ..) scheduler/RTOS and currently have the LPM1 instruction in the idle loop, and the main OS timer interrupt qualified with the "wakeup" keyword, and that all works fine, everything goes to sleep and wakes up on interrupt. However, I have some procedural code (non state-machine) that during which, I would like to sleep for one clock tick (the clock tick is currently 2MS), so I thought I could just call LPM1 in the procedural code and it should wakeup and continue next tick. The problem is it doesn't and never seems to wakeup at all, yet the LPM1 macro works fine from the OS idle loop. I am not sure why this is happening. Can someone shed some light on this issue? I also notice that the LPMx macros do not set the GIE bit as well as the low power bits, yet other compilers set the GIE bit ... Anyone know why mspgcc doesnot?
