Цитата(zltigo @ Aug 17 2008, 18:10)

Рассуждай токмо о том, о чём понятия твои тебе сие дозволяют. Так: не зная законов языка ирокезского, можешь ли ты делать такое суждение по сему предмету, которое не было бы неосновательно и глупо? (с) Козьма Прутков. Афоризмы

Понятия дозволяют. Я законы языка
ирокез С ещё на PDP-11 изучал. И с работой setjmp/longjmp тогда же разбирался.
Цитата(aaarrr @ Aug 17 2008, 18:14)

Замечательно. А вы умеете готовить программы, которые будут нормально работать при вываливании из любой точки после прерывания в другую?
Чтобы из любой - это гораздо сложнее. Но Вас же не удивляет что любая (некооперативная) RTOS может передать управление другому процессу после того как текущий был прерван прерыванием?
Разбираемый сейчас случай попроще будет. Требуется поведение программы типа "всё бросить и вернуться на заранее подготовленные позиции", как раз для такого эти функции и предназначены.
В популярных учебниках тему setjmp/longjmp предпочитают не затрагивать, вот народ про них почти ничего и не знает.
Попробую рассказать что знаю, с некоторыми упрощениями.
Функция setjmp() всего лишь запоминает в специальном буфере содержимое нескольких регистров, указатель стека и счётчик команд (адрес возврата, лежащий в стеке). Эта информация потом, при исполнении longjmp(), позволяет восстановить состояние программы таким, словно только что произошел возврат из setjmp(). Отличается только возвращаемое значение, setjmp() возвращает 0, а longjmp() возвращает свой второй аргумент. Это позволяет понять откуда попало управление в этот раз.
Разумеется, восстанавливается далеко не всё, скажем если программа успела изменить глобальные переменные то эти изменения не будут откачены назад, ну так это-то уже в руках программиста, и он может это предусмотреть, если бывает нужно "прибрать за собой".
Поскольку longjmp() переставляет указатель стека на прежнее место, то существует естественное ограничение на её применение: состояние той части стека, которая существовала на момент возврата из setjmp() не должно изменяться до выполнения longjmp(). Другими словами,
не должно быть выхода из функции или блока, содержащего setjmp().
А с учетом архитектуры AVR и имеющейся реализации этих функций не вижу никаких препятствий для примения longjmp() прямо из обработчика прерывания.
Реализацию в CodeVision надо проверить, но скорее всего и там будет работать. Примерно так (для IAR):
Код
jmp_buf jbuf;
int foo()
{
if( setjmp( jbuf ) )
{
// исполняется только после перехода по longjmp()
//если переход делать прямо из обработчика, то прерывания останутся запрещёнными
__enable_interrupt();
afterINT();
}
else
{
// исполняется после возврата из setjmp()
}
for(;;)
{
loop();
//........
}
}
#pragma vector=INT0_vect
__interrupt void INT0_isr(void)
{
longjmp( jbuf, 1);
}
Russia est omnis divisa in partes octo.