CODE
В голове инициализация векторов - такая:
VICIntEnClear = (uint32_t)-1; // Очистить все прерывания
VICSoftIntClear = (uint32_t)-1; // Очистить совтовые прерывания
#define VIC_CNTL_ENABLE_BIT 5
VICVectCntl0 = (1<<VIC_CNTL_ENABLE_BIT) | VIC_UART0; // Прерывание от USART0 - высший приоритет
VICVectAddr0 = (uint32_t)UART0_Handler;
VICIntEnable = (1<<VIC_TIMER0)|(1<<VIC_UART0); // Разрешить прерывание от таймера 0 и от USART0
VICIntSelect = (1<<VIC_TIMER0); // Прерывание от таймера 0 = FIQ
...
#define SHOW_INT VIC_SW // Âåêòîð ñîôòîâîãî ïðåðûâàíèÿ íà îáðàáîòêó êîììàíä
VICVectCntl15 = (1<<VIC_CNTL_ENABLE_BIT) | SHOW_INT; // Enable vector interrupt for context switcher
VICVectAddr15 = (uint32_t)ShowActive;
VICIntEnable = (1UL<<SHOW_INT);
VICVectAddr = 0; // Reset VIC logic
...
FIQ прерывание объявлено так
__fiq __arm void FIQ_Handler() // Отображение картинки Master, Slave
...
там вызов картинки
if(Flag.EnShow) VICSoftInt = (1<<SHOW_INT); // Выполнить прерывание
....
завершение так
VICVectAddr = 0;
}
....
Совтовое прерывание оформлено так
__arm __nested __irq static void ShowActive(void)// Исполнение комманд
...
Потом идёт кое какая критическая секция, где бы я не хотел иметь прерываний, тем не менее по JLINKу почемуто FIQ прерывания здесь разрешены
...
далее я разрешаю прерывания
...
__enable_interrupt();
...
из данного прерывания выхожу так
...
__disable_interrupt();
VICSoftIntClear = (1<<SHOW_INT); // Сбросить совтовое прерывание
VICVectAddr = 0;
// TST_CLR;
}
....
Что я вижу.
1) FIQ вызываются как положено
2) Ч/з нужное число прерываний FIQ устанавливается флаг совтового прерывания, и осуществляется переход на него.
3) при выходе из совтового прерывания возврат происходит не туда куда нужно
VICVectAddr = 0; => ставить в конце обработчика FIQа не нужно. FIQ работает в обход VICа. В конце обработчика нужно сбросить флаги прерывания периферии, которая вызвала FIQ. В данном случае флаги прерывания таймера 0. Если же поставить сброс VIC, то могут быть аномалии в работе проги. Т.к. если FIQ прервал IRQ, то после выхода из FIQ, VIC подумает что закончилось текущее IRQ и может вызвать повторно как текущее IRQ, так и IRQ с более низким приоритетом, прервав текущее (с более высоким).
static в заголовке прерывания никогда не ставлю. Честно говоря, даже не знаю зачем оно нужно.
(ЗЫ. Если кто знает - расскажите. Заодно встал сегодня на грабли в CCS3.3 который ругается когда переменная вне процедуры объявлена через static, а я её в хидере пытался через extern объявить, компилеру не понравилось вместе extern static ... Для меня этот статик загадочный какой-то. Только внутри процедуры знаю для чего он используется.)
Цитата
Потом идёт кое какая критическая секция, где бы я не хотел иметь прерываний, тем не менее по JLINKу почемуто FIQ прерывания здесь разрешены
Так и должно быть. Залетая в обработчик IRQ, проц запрещает только IRQ, а FIQ остаётся включённым, точнее каким и был раньше. Если нужна абсолютная критическая секция, то нужно "ручками" запрещать FIQ.
Цитата
3) при выходе из совтового прерывания возврат происходит не туда куда нужно
Очень может быть. Как уже написал раньше, сбросив VIC внутри FIQа процессор подумал, что SoftInt завершился и после этого могло вызваться любое другое прерывание, причём управление (сразу) могло не вернуться в SoftInt. Хотя в основную прогу управление вернутся не может пока не завершиться SoftInt.
На первый взгляд всё. Если после этого не заработает как надо, то почитаю ещё разок повнимательнее