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

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

[avr-gcc-list] Re: FW: memcpy() : problem when passing destination point


From: David Brown
Subject: [avr-gcc-list] Re: FW: memcpy() : problem when passing destination pointer
Date: Thu, 12 Feb 2009 20:54:16 +0100
User-agent: Thunderbird 2.0.0.19 (Windows/20081209)

Michael wrote:

In both of these cases, "volatile" is insufficient because it does
not
imply "atomic". In the first case, you need an atomic

read-modify-write, and in the second you need an atomic read of a
wide
value. In both cases you can achieve that by enclosing the the
variable
access in a cli-sei pair. For example, the latter case can be fixed
by
changing the routine to something like


main() // or "int main(void)", yada yada

{

uint32_t ms; // does not need to be volatile


do{ cli(); ms = Milliseconds; sei(); } while (ms < SOME_LIMIT);

}


No, you can not. You need the macros in util/atomic.h because cli /
sei
are not memory barriers and accesses to variables done inside a pair

like that can be moved out by the compiler.


Just search the archives for previous discussions and examples...


Could a pair disabling a specific interrupt (rather than global
interrupts) also be susceptible to the compiler re-ordering it outside
the pair?
For instance, in this example I read a structure modified by a timer
ISR: ETIMSK &= ˜_BV(OCIE3A); memcpy(&tryconnect,&rtc,sizeof(struct datetime)); ETIMSK |= _BV(OCIE3A);

That will be safe (assuming the memcpy call accesses volatile data, or uses an external function call). The compiler will keep volatile accesses in order with each other, but may re-order non-volatile accesses or instructions around the volatile accesses. The sei() and cli() macros expand to a single assembly instruction, which does not involve a volatile memory access - therefore the compiler can re-order around them. The atomic.h macros include a "__asm__ volatile ("" ::: "memory")" memory barrier, which generates no code but counts as a volatile memory access, thus forcing an order on the accesses. Your specific interrupt disable is also a volatile access, so the code should be safe.





reply via email to

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