avr-gcc-list
[Top][All Lists]
Advanced

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

Re: [avr-gcc-list] "Volatile"


From: E. Weddington
Subject: Re: [avr-gcc-list] "Volatile"
Date: Fri, 15 Apr 2005 15:15:19 -0600
User-agent: Mozilla Thunderbird 1.0.2 (Windows/20050317)

Keith Gudger wrote:

Those of us on this list all know the "volatile" drill - it's FAQ #1.
This is sort of the same issue, and I'm wondering if the code that "got
me" is as obvious as the other volatile stuff.

I have a volatile variable, "Flags", that is set and cleared in many
routines, including an interrupt.  Here is the disassembly for the
Flags_Clear function:

00000f3e <Flags_Clear>:
f3e: 98 2f mov r25, r24 f40: 90 95 com r25
    f42:       80 91 a4 00     lds     r24, 0x00A4
    f46:       89 23           and     r24, r25       ; <- interrupt here
    f48:       80 93 a4 00     sts     0x00A4, r24
    f4c:       08 95           ret

The interrupt occured right before f46, and set the flag.  The interrupt
pushed and popped r24 & r25's values, so when the interrupt returned to
f46, the flags were restored to their *previous* state (the flag unset!
Ack!  I'm screwed!)

Two questions:  1)  Is this something I should have learned in Embedded
101?  If so, I"ll slink quitely away...

Well it's probably embedded 201....

  and if not..  2)  How would the
experts on this list have prevented this?
See theory on "critical sections". Essentially, any operation that you want to have happen "atomically" you place in a critical section. The critical section is a section where nothing should disturb or otherwise interrupt it. So, for the AVR you disable global interrupts before and enable global interrupts after the section. This is really important when you have a single C statement that compiles to multiple assembly instructions. You get the false security of thinking that the operation is atomic because there is only one C statement. In reality, you can get an interrupt in the middle of the operation because the compiler generates multiple assembly instructions. The interrupt finishes, it goes back to your operation with corrupted values.

HTH
Eric




reply via email to

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