avr-libc-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-libc-dev] Disable/Restore all Interrupts


From: Theodore A. Roth
Subject: Re: [avr-libc-dev] Disable/Restore all Interrupts
Date: Fri, 5 Sep 2003 00:25:39 -0700 (PDT)

On Thu, 4 Sep 2003, Sam de Jongh Hepworth wrote:

:)Hi
:)
:)avr-libc is great! I have writte two macros that help disable and restore
:)all interrupts. I think the cli(); and sei(); macros are a little
:)dangerous to use, please consider this;
:)
:)Before this code is executed all interrupts has been disabled. Now the
:)following code is executed;
:)
:)-- BEGIN --------------------------------
:)cli();
:)// do some work with all interrupts disabled...
:)sei();
:)-- END --------------------------------
:)
:)After executing the code all interrupts will be enabled! But they where
:)disabled before the code was executed :-(

The idiom I've seen for critical sections is similar to this:

  uint8_t sreg;

  sreg = SREG;
  cli();
  // do something.
  SREG = sreg;

I also use these macros in one of my projects (I may have nicked this 
straight out of avr-libc, can't remember though):

#if !defined(critical_Begin)
#define critical_Begin()                        \
    __asm__ __volatile__ (                      \
        "in __tmp_reg__, __SREG__"       "\n\t" \
        "push __tmp_reg__"               "\n\t" \
        "cli"                            "\n\t" \
        :: )
#endif

/* Restore SREG from the stack. */

#if !defined(critical_End)
#define critical_End() \
    __asm__ __volatile__ (                      \
        "pop __tmp_reg__"                "\n\t" \
        "out __SREG__, __tmp_reg__"      "\n\t" \
        :: )
#endif


Note that sei() has it's place. You can use it once to initially enable 
interrupts.

:)
:)My solution to this problem is;
:)
:)-- BEGIN --------------------------------
:)#define DISABLE_INTERRUPTS() {ubyte _save_int = SREG & flag(7); cli();
:)#define RESTORE_INTERRUPTS() (SREG |= _save_int);}
:)
:)DISABLE_INTERRUPTS();
:)// do some work with all interrupts disabled...
:)ENABLE_INTERRUPTS();
:)-- END --------------------------------
:)
:)The DISABLE_INTERRUPTS macro save the current state of SREG bit 7 and then
:)disabled interrupts. The RESTORE_INTERRUPTS macro restore SREG bit 7.
:)Nice!

I think that putting the opening and closing braces in separate macros is 
asking for trouble.

It's debatable whether saving and restoring only the I flag gains you 
anything.

Ted Roth





reply via email to

[Prev in Thread] Current Thread [Next in Thread]