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

Andrew Kalman aek at pumpkininc.com
Tue Apr 15 09:41:30 PDT 2008


In IAR EW430, Salvo 4 uses:

static istate_t s;

void OSDisableHook(void)
{
   s = __get_interrupt_state();
   __disable_interrupt()'
}

void OSEnableHook(void)
{
   __set_interrupt_state(s);
}

Works for all situations (including functions called from ISR).

--Andrew


>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
>>
>
>
>_______________________________________________
>Icc-430 mailing list
>Icc-430 at imagecraft.com
>http://dragonsgate.net/mailman/listinfo/icc-430


-- 
  ______________________________________
   Andrew E. Kalman, Ph.D.   aek at pumpkininc.com



More information about the Icc-430 mailing list