|
From: | Dave Hansen |
Subject: | RE: [avr-gcc-list] memcpy() : problem when passing destination pointer |
Date: | Wed, 11 Feb 2009 12:15:31 -0500 |
From: address@hidden [...re: volatile use cases...] > fourth case: nasty situations where 'volatile' is only a part of the > solution but does not insure a correct result: > > For instance if ISR1 and ISR2 are *nested* ISRs, IsrCounter does not > correctly hold the count of interrupts: > > volatile uint8_t IsrCounter; > > ISR1() > { > IsrCounter++; > } > > ISR2() > { > IsrCounter++; > } > > Consider also memory locations larger than the MCU data processing unit > size (8 bits for AVR). > > The following code gives bad results on an AVR but works on a i386: > > volatile uint32_t MilliSeconds; > > ISR() > { > MilliSeconds++; > } > > main() > { > while(MilliSeconds < SOME_LIMIT) ... > } > 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); } Regards, -=Dave Stay up to date on your PC, the Web, and your mobile phone with Windows Live. See Now |
[Prev in Thread] | Current Thread | [Next in Thread] |