Hi guys! There was a recent discussion on 'Freaks covering atomic blocks of code, ie. code blocks which for their duration have interrupts disabled:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=45041 Many different suggestions were made, from simple macros to more complex and fool-proof methods. I eventually came up with heavily modified versions of Darcy Watkin's macro posted at: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=37733&highlight=atomic+macro My macro allows for both atomic (interrupts disabled) and non-atomic (interrupts enabled) blocks of code to be easily made. Unlike conventional methods these macros are quite foolproof - the epilogue for each is run automatically on block exit regardless of the exit path. When compiled with -Os, it results in the smallest possible code. Two options are avaliable; ATOMIC_RESTORESTATE, where the previous interrupt enable flag status is restored, and ATOMIC_FORCEON (or ATOMIC_FORCEOFF for the non-atomic block) which forces the global flag state on block exit - desirable in some instances. Despite its simplicity, would it have an application for AVRLibC? Should I add DoxyGen comments and submit as a patch? ================================================ #ifndef ATOMIC_H #define ATOMIC_H #include <avr/io.h> #include <avr/interrupt.h> static inline void __iSeiParam(const uint8_t *s) { sei(); (void)s; } static inline void __iCliParam(const uint8_t *s) { cli(); (void)s; } static inline uint8_t __iSeiRetVal(void) { sei(); return 1; } static inline uint8_t __iCliRetVal(void) { cli(); return 1; } static inline void __iRestore(const uint8_t *s) { SREG = *s; } #define ATOMIC_BLOCK(exitmode) for ( exitmode, __ToDo = __iCliRetVal(); __ToDo ; __ToDo = 0 ) #define ATOMIC_RESTORESTATE uint8_t sreg_save __attribute__((__cleanup__(__iRestore))) = SREG #define ATOMIC_FORCEON uint8_t sreg_save __attribute__((__cleanup__(__iSeiParam))) = 0 #define NON_ATOMIC_BLOCK(type) for ( type, __ToDo = __iSeiRetVal(); __ToDo ; __ToDo = 0 ) #define NONATOMIC_RESTORESTATE uint8_t sreg_save __attribute__((__cleanup__(__iRestore))) = SREG #define NONATOMIC_FORCEOFF uint8_t sreg_save __attribute__((__cleanup__(__iCliParam))) = 0 #endif ================================================ _______________________________________________ AVR-libc-dev mailing list [email protected] http://lists.nongnu.org/mailman/listinfo/avr-libc-dev
