Dingo (20.10.2014 06:15 - 06:21, просмотров: 8213)
Чего-то после выходных не включусь.. Порт ATOMIC_BLOCK из AVR-LIBC. Есть там такая обёртка для атомарных операций:
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
ctr_copy = ctr;
}
Так хочется такой же функционал на Cosmic получить для stm8 (ой, что щас будет!... )
Лезу внутрь:
#define ATOMIC_BLOCK(type) for ( type, __ToDo = __iCliRetVal(); \
__ToDo ; __ToDo = 0 )
Потрошу дальше:
static __inline__ uint8_t __iCliRetVal(void)
{
cli();
return 1;
}
// ...
#define ATOMIC_RESTORESTATE uint8_t sreg_save \
__attribute__((__cleanup__(__iRestore))) = SREG
// ...
static __inline__ void __iRestore(const uint8_t *__s)
{
SREG = *__s;
__asm__ volatile ("" ::: "memory");
}
Как-то я результат всех этих манипуляций не могу повторить.
for ( uint8_t sreg_save __attribute__((__cleanup__(__iRestore))) = SREG, __ToDo=1 /* и запретили прерывания */ ;\
__ToDo = 1; __ToDo =0 )
{
// user code
}
Последние два оператора понятно что делают: выполняем блок один раз. А вот с первой частью чего-то въехать не могу uint8_t sreg_save __attribute__((__cleanup__(__iRestore))) = SREG, __ToDo=1 /* и запретили прерывания */. Чем там инициализируется и что? и как потом востановление регистра SREG происходит?
Вроде бы главное колдунство происходит здесь:
__attribute__((__cleanup__(__iRestore)))