[Top][All Lists]

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

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

From: David Brown
Subject: Re: [avr-gcc-list] "Volatile"
Date: Sun, 17 Apr 2005 15:27:37 +0200

Others have already given you some useful pointers about what "volatile"
really means, and how to get true atomic access (by disabling interrupts).
However, in the case of a simple flag, there is an easy way to get true
atomic access (which must still be combined with "volatile" as needed) -
keep your flag as a simple byte, and always set it directly.  You haven't
given any source for your Flags_Clear function, but I'm guessing you have a
byte containing many flags, either as a bitfield struct or with masks.  If
your flag is declared as "volatile unsigned char flag", then operations such
as "flag = 0" and "flag = 1" are atomic.



> 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
> >     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.
> Eric
> _______________________________________________
> AVR-GCC-list mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/avr-gcc-list

reply via email to

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