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: David Brown
Subject: Re: [avr-gcc-list] "Volatile"
Date: Tue, 19 Apr 2005 08:48:49 +0200

>
> On Apr 18, 2005, at 1:40 AM, David Brown wrote:
>
> > Yes, it is the later - C has no concept of "atomic statement", so
> > anything
> > dependant on atomicity is going to be target-depedendant and
> > non-portable.
>
> Not terribly long ago I went digging thru GCC docs on the hope of
> finding an __attribute__ for quickly and cleanly applying an "atomic"
> property to a variable. Didn't find one. But knowing there were
> "packed" and similar attributes for structs, and the various things
> done for AVR registers, led me to suspect "atomic" or similar might
> exist.
>

What would making a variable "atomic" mean?  It's a meaningless concept.  A
statement or function can be "atomic", meaning that it cannot be split (or
*acts* as though it cannot be split) by anything else - interrupt functions,
peripherals, external hardware, other bus masters, etc.  When you are
talking about an "atomic" variable, do you mean a variable that can be read
or written as a single unit?  In that case, the variable is "atomic" if and
only if it is read or written as a single unit by the cpu - for 8-bit micros
that means 8-bit data, for 16-bit micros that means (generally) 16-bit and
8-bit data, and so on.

What would be very useful in avrgcc is a convenient way of making *code
sections* atomic.  Basically, this means recording the current state of
interrupts, disabling interrupts, then running the critical code, then
restoring the interrupts :

void atomicFunction(void) {
    unsigned char oldSREG = SREG;
    CLI();
    /* Critical code */
    SREG = oldSREG;
}

In the msp430 port of gcc, there is a function attribute doing exactly that:

void __attribute__((critical)) atomicFunction(void) {
    /* Critical code */
}

It would be very nice to see that as part of avrgcc, but I realise that
getting such a change implemented involves more paper work that programming
work!

If you want functions to atomically read or write a 16-bit variable, they
are easy to make, but best implemented as macros (using newer C standards
that allow variable declerations anywhere, and some neat gcc extensions):

#define atomicWrite(var, data) { \
    unsigned char oldSREG = SREG; CLI(); var = data; SREG = oldSREG; }

#define atomicRead(var) ({ \
    unsigned char oldSREG = SREG; CLI(); typeof (var) data = var; SREG =
oldSREG; \
    data; })

I haven't tried these, but they should work for any variables that can be
read or assigned directly, including bitfields, struct elements, and so on.







reply via email to

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