----- Ursprüngliche Nachricht -----
Von: Peter Bigot
Gesendet am: 06 Dez 2011 17:15:18

On Tue, Dec 6, 2011 at 8:46 AM, JMGross <msp...@grossibaer.de> wrote:
>> LMP is exited, since an ISR is pending. 
>> (I'm not sure whether the DCO/XT wakeup time does apply in this case)
>> the instruction after the BIS is executed (it aslready had been fetched 
>> before the BIS was executed, hence the usual NOP after an LPM entry)

> There's normally a no-op after disabling interrupts because of the
> chance that the following instruction should have been protected from
> interrupts, but that the disable would not occur in time due to
> pipelining.  (The __disable_interrupt intrinsic does this for you, at
> least with IAR (second-hand) and mspgcc (first-hand) since it can't
> guarantee what instruction will immediately follow.) 

IIRC, CCS doesn't. Nor do the BIC/BIS intrinsics which many people use,
either for combining GIE and LPM set, or even just for setting GIE.

>> I know of no
>> reason why it's necessary to do that after LPM mode settings.  What's
>> your reference for this advice?

Logical thinking and experience.
many people set a breakpoint on the next instruction, expectign it hit after
LPM was entered and ended by an ISR, but it is hit right before the LPM
was entered at all.
Also, like with GIE, the instruction after the BIS will be executed before
the ISR is entered. And if it is an instruction that assumes the ISR has
happened (e.g. set a global flag), or that the ISR triggering event
has already occurred, you're hosed.


>> - When your ISR does not clear the IFG bit for the interrupt,
>> the ISR will be re-entered as soon as it exits.

> Note that clearing IFG is unnecessary if you're using a PxIV register
> to determine the interrupt cause.  These interrupt vector registers
> are not available on older families of MSP430.

Indeed. Reading the IV register is one way to clear the IFG flag.
Writing to TXBUF etc. is another. Or manually clearing it.
I was including all options when I wrote this.


>> - you enable porti.ie.pin1 in every loop. It stays enabled (unless the ISR 
>> disables it) and interrupts may
>> happen all the time (or after this point) independently of LPM4. You should 
>> clear GIE on exit of the ISR too,
>> so when main is awakened, no further interrupts are handled unless you want 
>> them again.

> If you do this, be aware of the side effects if you have other
> interrupt handlers (such as timers or UART activity) that also need to
> run.  Fundamentally you need to know whether interrupts will be
> normally enabled, or normally disabled, and design the control flow of
> your program accordingly.  Absent other information, my preference is
> to have the handler leave GIE unchanged.

I agree, knowing the rest of the applicaiton is vital 
when it comes to LPM and interrupt handling.
In any case.
However, clearing GIE before enabling the port interrupts and setting it
together with the LPM instruction is a possible way.
Entering LPM with GIE clear is not a good idea, so the previous state
of GIE is a don't care :)


>> That's one reason why bitfields for the many registers (especially ports) 
>> have been removed from the 'official' header files.

> Well, no, that had no bearing on the decision, at least for mspgcc.

I meant the TI header files. There ar eno bitfields defined.
But maybe they have never been.
IAR did include them into the io430 headers, but they are not
in the newer msp430 headers.


On Tue, Dec 6, 2011 at 5:53 PM, Wayne Uroda <wayne.ur...@grabba.com> wrote:

>> One thing that I have never done is use the on_exit macro - 
>> I use the wakeup keyword instead - I'm guessing there are 
>> potential problems with the wakeup keyword?

> The wakeup function attribute in mspgcc is equivalent to having
> "bic_status_register_on_exit(0xF0)" in your interrupt handler (and
> LPM4_bits is 0xF0).  There's nothing intrinsically wrong with it
> except that it's opaque, and will only do exactly that operation, so
> you couldn't (for example) clear GIE on exit using it.

Also, there is no way to conditionally exit LPM.
E.g. an RX function detecting the end of a transmission (e.g. CR/LF)
but silently runs if the transmission is not complete yet.
Or an ISR that has multiple sources and soem of them are completely
handled inside the ISR and only some need to wake up main.

The wakeup keyword will always reactivate main.

> Personally I never remember what "signal", "wakeup", "reentrant", and
> "critical" as function attributes mean exactly, and if I encounter
> them I have to go read the compiler source to remind me what they do.
> As far as I know they're also specific to mspgcc, so people who use
> IAR or CCS won't understand what you're doing either.

I would have to look for 'signal' too.
critical and reentrant are opposites. Where "critical" clears GIE on the
function entry and restores it at the end, "reentrant" will always enable
GIE on function entry and restore the previous state on exit.

However, limiting the critical section to the exact code where it is
required isnterad for the whole function, is usually the better way.
And "reentrant", well, it can cause havoc if you don't exactly know
what you do - inside as well as outside this function. :)



----- Ursprüngliche Nachricht -----
Von: Wayne Uroda
Gesendet am: 07 Dez 2011 03:10:56

> I personally only use the critical and wakeup keywords. 
> Of course putting dint and eint calls at the start and end of the function 
> is easy, but I prefer critical as it saves the current state of GIE on the 
> stack and pops it on exit (whereas hand coding dint eint 
> will always leave your function with interrupts enabled).

that's right. You may use inline assembly (which is what most of the 
intrinsics do anyway) to save the SR on the stack and restore it later.

> There is probably some easy macro I don't know about to push 
> and then pop the status register but if you push and then forget 
> to pop I imagine you might rip your hair out for a while 
> trying to work out what is going on :)

You're right. It is even worse. At least in MSPGCC 3.2.3, when you 
push something on the stack, this may mess-up the stack frame
when optimization is on.
As long as the SR is on the stack, all accesses to local
variables or stack parameters may be off by two bytes.
I'm not sure whether declaring the SP as clobbered in the
assembly instruction will help. I'm not sure whether I did this
when I encountered this problem. But maybe the optimizer will
not notice this when removing the frame pointer in favor of the
stack pointer under some circumstances.

I ended up with an 'atomic' macro.
It will count up a global variable and set GIE, taking the whole
code inside the brackets as parameter.
At the end, it decrements the global variable and if it reaches
zero, it sets GIE.
It's not much slower than a push/BIS/POP combo, but apparently
optimizer-safe, does not fill the stack on deeper nesting levels
and looks better (more obvious) in the source code.
If I could only replace the round brackets for the macro parameter
by curved brackets, so it looks like a do{} block :)


> Our platform is fully hand coded from the ground up 
> (custom C startup, custom linker scripts, custom ELF based tools) to allow 
> for custom bootloader / firmware loading. 

Sounds familiar. I too have own startup code (to have the watchdog 
always running) and customized linker files (for a custom bootloader,
or rather a boot-copier as it expects the new code already received
by the old firmware and sotred in a free flash section)
No custom ELF-bssed tools though (but the makefile doesn't look
much 'standard' anymore)
even own multiply functions, replacing the default ones. And assembly-
based multiply macros for fast and efficient inline multiplication
where needed. (e.g. 32x32->64). The C language does a bad job here by
default (only 32x32->32, or (32->64)x(32->64)->64 )

> So the critical and wakeup keywords will be the least of somebody's worries 
> should 
> they ever need to port the code to IAR ;)

:) If I could post my code (it belongs to my employer, so I cannot), 
most people would not only have a hard time to port it 
(especially the inline assembly parts), but even use it on mspgcc,
without additional classes about the framework design.

JMGross


------------------------------------------------------------------------------
Cloud Services Checklist: Pricing and Packaging Optimization
This white paper is intended to serve as a reference, checklist and point of 
discussion for anyone considering optimizing the pricing and packaging model 
of a cloud services business. Read Now!
http://www.accelacomm.com/jaw/sfnl/114/51491232/
_______________________________________________
Mspgcc-users mailing list
Mspgcc-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mspgcc-users

Reply via email to