Доброго времени суток. Думаю, вопросы буду генерировать периодически, поэтому завожу такого рода тему.
Итак, имею проект на AT91SAM7A3 (портировал :
-использование Periodic Interval Timer (прерывание 10 Гц)
-использование USART1 (самодельный софтварный кольцевой буфер)
-использование External IRQ2 (внешний генератор, по этому прерыванию посылаем в USART1 пачку данных)
-частичное использование PORTA/PORTB для эмуляции работы с внешней памятью (ALE, RD, WR, ADR, DATA).
В целом, вроде как всё работает. Но наблюдаются странности:
- после запуска генеработа (200 Гц) довольно быстро (1-2 секунды) проц перестаёт работать с основной программой (main, вне прерываний), - реагирует только на сами прерывания. Но! может и стабильно поработать несколько минут.
- при небольших и непринципиальных изменениях кода прога может вываливаться в Abort'ы. Судя по состоянию регистров, происходит нечто странное. Опять же всё совсем неоднозначно. Например, в регистре должно быть 0xFFFFFC40, а при аборте там оказывается 0xDFFFFC40 или 0x1FFFFC40 или ещё что-то похожее (то есть идёт порча 1-2 старших бит). А может вообще затираться на что-то вроде 0x00000005. Если компиляция приводит к регулярным абортам, и я пытаюсь через JTAG пошагово отследить программу, то никаких абортов не происходит. В симуляторе кейловском прога работает как швейцарские часы.
Компилирую код с оптимизаций -O0.
Стек делаю большой, в map-файле всё выглядит цивильно.
Все переменные, встречающиеся как вне прерываний, так и внутри них, объявлены как volatile.
IRQ-пре-обработчик заимствовал из кейловских примеров:
на все прерывания сначала вызывается ASM-обработчик, который уже потом прыгает в сишный обработчик, определённый в AIC.
Я уже голову сломал, кучу вариантов перепробовал, начал шаманить в общем. Прошу оценить код со стороны, может кто-то что-то заметит.
SAM7.s - стартап
AIC_interrupts.s - начальный обработчик прерываний.
interrupts.c - сишные обработчики прерываний
usart_with_sw_buf.c/h - функции работы с USART.
init.c - инициализация прерываний