[Icc-430] Reading MSP-430 status register from C....

bailey at peak.org bailey at peak.org
Tue Apr 15 00:56:58 PDT 2008


Kris/Len,

    KRIS, you've got it exactly!  I'm keeping my fingers crossed hoping
that Richard can find a way to implement the SR access intrinsics:

unsigned short __get_SR_register(void);
unsigned short __get_SR_register_on_exit(void);

    With these, the problem yields to a clean and efficient solution.

    LEN, I also support your desire to get the asm<->C variable access
stuff fixed so that when future issues arise we have better tools to
tackle them with!

    Kirk Bailey
    bailey at peak.org

> Kirk Bailey (bailey at peak.org) wrote:
>
>  > For the current issue I need to read the GIE bit, but
>  > there are other situations where it is useful to be
>  > able to examine other status bits.
>  >
>  > Basically what I'm trying to do is implement two
>  > primitives:
>  >
>  > 1. Enter-Monitor (read current GIE status, set GIE to 0)
>  > This primitive is where I need to be able to read the
>  > SR, followed by a _DINT() /* or _BIC_SR(GIE) */.
>  > Depending on the application it may also be useful to
>  > isolate the GIE bit by itself in the saved copy to
>  > avoid over-writing some of the other flags in the SR
>  > during the later execution of the  "exit" primitive.
>  >
>  > 2. Exit-Monitor (restore saved GIE status)
>  > This translates into a _BIS_SR(saved_GIE_status)
>
> Yes we have the same issue with icc430. It's common in
> embedded programming to do what you describe. You need
> to make sure that interrupts are disabled during certain
> critical sections, but you don't want to lock out
> interrupts unnecessarily.
>
> If your function just enables interrupts explicitly at
> the end of each critical section, then you have to ensure
> that the function will never be called in a situation
> where interrupts are disabled and must stay disabled,
> because the function will explicitly enable them. This
> might be a workable approach as long as it's clearly
> documented and explained.
>
> But of course the cleanest solution is the traditional one:
>
>    push (or otherwise save) the status register
>    explicitly disable interrupts
>    do the critical stuff
>    restore the status register from the saved value.
>
> With this method it doesn't matter whether interrupts
> were disabled on entry to the function or not, because
> the code never enables them if they weren't already
> enabled, but only forces interrupts off during critical
> section(s).
>
> We have tried to convince icc430 to do this efficiently
> by defining an automatic local variable to hold the status
> register value, and accessing it using asm statements, but
> it doesn't work because the compiler thinks the local
> variable has no scope (because it is only accessed from
> asm statements and the compiler just passes those on to
> the assembler without looking at them) so the compiler
> will reuse the register allocated to the local variable
> for other variables. This was what we tried:
>
> void myfunction(void) {
>    auto saved_sr;
>    asm ("mov  r2,saved_sr");  /* Save SR */
>    /* Non-critical code can go here */
>    asm ("dint");
>    asm ("nop"); /* (if needed) */
>    /* Critical code */
>    asm ("mov  saved_sr,r2");  / Restore SR */
>    /* Non-critical code */
>    asm ("dint");
>    asm ("nop"); /* (if needed) */
>    /* Critical code */
>    asm ("mov  saved_sr,r2");
>    /* Non-critical code */
>    /* ... more if wanted ... */
>    /* Must exit with interrupt flag as on entry */
>    asm ("mov  saved_sr,r2");
>    /* Non-critical code */
>    return;
>    }
>
> This would be fairly efficient and would have the
> advantage that you only need to save the status register
> in the local variable _once_, near the start of the
> function (which would be an improvement over the common
> approach of pushing SR onto the stack before _each_ DINT
> and popping it after the critical section), but we have
> not been able to get it to work with icc430.
>
> At the moment we're using function calls to get and
> set the status register. This is inefficient, and
> ironically that inefficiency affects the very code
> that you want to be as efficient as possible. :-(
>
> I would appreciate a formally sanctioned way to deal
> with this common embedded programming situation.
>
> Kris
> --
> Kris Heidenstrom       Embedded systems designer / programmer
> kris at abbey.co.nz       Abbey Systems Ltd - Telemetry Specialists
> Wellington NEW ZEALAND  Voice +64-4-385-6611  Fax +64-4-385-6848
>
> _______________________________________________
> Icc-430 mailing list
> Icc-430 at imagecraft.com
> http://dragonsgate.net/mailman/listinfo/icc-430
>




More information about the Icc-430 mailing list