----- 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