Цитата(demiurg_spb @ Oct 17 2008, 21:51)

На мой взляд такое предположение не совсем удачно. Компилятор ничего не должен предполагать - это прерогатива программиста.
Если компилятор ничего не будет предполагать, он будет связан по рукам при оптимизации.
А прерогатива програмиста - управлять его предположениями.
Предполагает же он, что переменная не меняется, пока он сам её не поменяет? Предполагает. Пока программиcт не отобъёт эту предполагалку при помощи слова volatile.
С прерываниями - если нужно, чтобы данное прерывание всё выполнялось при разрешённых прерываниях, то
Код
ISR(INT0_vect,ISR_NOBLOCK)
{
}
и прерывания будут разрешены первой командой обработчика, потом будут
если надо для модификаций указателя стека запрещаться на пару команд.
Цитата(demiurg_spb @ Oct 17 2008, 21:51)

Иногда просто необходимо разрешать прерывания внутри обработчика прерывания.
Выход видится такой:
...
Может есть другие, более изящные варианты?
Где в документации можно прочесть об этом нюансе?
Если нужно разрешить на части обработчика, то других вариантов и нет. Чтобы не було проблем, обозначеннх
aesok, надо глянуть
<util/atomic.h>Код
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/atomic.h>
volatile uint8_t a, b;
ISR(INT0_vect)
{
++a;
NONATOMIC_BLOCK(NONATOMIC_FORCEOFF)
{ //+++ от сих
PORTB |= 0x02;
if( PINB & 0x01 ) return; // а тут запретятся перед уходом на эпилог
PORTB |= 0x04;
} //--- и до сих - прерывания разрешены
++b;
}
Это сделано на gcc-шном расширении C - атрибутах, приписывающих к переменным некие функции инициализации и очистки. По сути - конструкторы и деструкторы, выражаясь языком C++
Приведенный выше код эквивалентен С++ - ному
Код
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/atomic.h>
class noatomic_forceoff
{
public:
noatomic_forceoff() { sei(); }
~noatomic_forceoff() { cli(); }
};
volatile uint8_t a, b;
ISR(INT0_vect)
{
++a;
{
noatomic_forceoff na;
PORTB |= 0x02;
if( PINB & 0x01 ) return;
PORTB |= 0x04;
}
++b;
}
вплоть до сгенерированного компиляторами кодаavr-gcc -std=c99 -O2 -S -mmcu=atmega88
avr-g++ -O2 -S -mmcu=atmega88
CODE
__vector_1:
/* prologue: frame size=0 */
push __zero_reg__
push __tmp_reg__
in __tmp_reg__,__SREG__
push __tmp_reg__
clr __zero_reg__
push r24
/* prologue end (size=6) */
lds r24,a
subi r24,lo8(-(1))
sts a,r24
/* #APP */
sei
/* #NOAPP */
sbi 37-0x20,1
sbic 35-0x20,0
rjmp .L2
sbi 37-0x20,2
/* #APP */
cli
/* #NOAPP */
lds r24,b
subi r24,lo8(-(1))
sts b,r24
rjmp .L5
.L2:
/* #APP */
cli
/* #NOAPP */
.L5:
/* epilogue: frame size=0 */
pop r24
pop __tmp_reg__
out __SREG__,__tmp_reg__
pop __tmp_reg__
pop __zero_reg__
reti