[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.
mvh.,
David
> 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
>
>
> _______________________________________________
> AVR-GCC-list mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
>
- [avr-gcc-list] "Volatile", Keith Gudger, 2005/04/15
- Re: [avr-gcc-list] "Volatile", E. Weddington, 2005/04/15
- Re: [avr-gcc-list] "Volatile",
David Brown <=
- Re: [avr-gcc-list] "Volatile", Jeff Epler, 2005/04/17
- Re: [avr-gcc-list] "Volatile", David Brown, 2005/04/18
- Re: [avr-gcc-list] "Volatile", Graham Davies, 2005/04/18
- Re: [avr-gcc-list] "Volatile", David Brown, 2005/04/18
- Re: [avr-gcc-list] "Volatile", Keith Gudger, 2005/04/18
- Re: [avr-gcc-list] "Volatile", David Brown, 2005/04/18
- Re: [avr-gcc-list] "Volatile", David Kelly, 2005/04/18
- Re: [avr-gcc-list] "Volatile", David Brown, 2005/04/19
- RE: [avr-gcc-list] "Volatile", stevech, 2005/04/20
- Re: [avr-gcc-list] "Volatile", Colin Paul Gloster, 2005/04/20