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?


Reply via email to