On Thursday 19 January 2006 17:46, David Brown wrote: > There have already been a dozen answers pointing out the O/P's problem. I > thought you might like to know, however, that there is another way to do an > atomic read of such a counter without disabling interrupts, which can be > useful in some circumstances. If you have complicated and slow interrupt > routines, or high frequency interrupts, then it's probably not a great idea > as it is non-deterministic. > > unsigned short atomic_read_short(unsigned short *addr) { > unsigned short a, b; > a = (volatile)(*addr); > do { > b = (volatile)(*addr); > if (a == b) return a; > a = b; > }; > }
Yes, this is a very beautiful idea. Only one note: to force reading from '*addr' it is necessary a small correction. Original: do { b = (volatile)(*addr); if (a == b) return a; a = b; } while (1); produces an infinity loop: .L2: cp r24,r18 cpc r25,r19 breq .L7 movw r24,r18 rjmp .L2 and after correction: do { b = *(volatile unsigned short *)addr; if (a == b) return a; a = b; } while (1); works true: .L2: ld r18,Z ldd r19,Z+1 cp r24,r18 cpc r25,r19 breq .L7 movw r24,r18 rjmp .L2 Regards, Dmitry. _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list