Использование трассировки стека для отладки неизвестной программной исключительной ситуации на Coldfire MCF5235 в GDB (Eclipse)
В какой-то момент в моем приложении C (работающем без работы, в режиме супервизора) при использовании контроллера CAN через стороннюю библиотеку произошла ошибка Illegal Instruction, которая обнаруживается в ISR; к этому моменту счетчик программ, адрес ошибки и адрес возврата в кадре стека исключений, доступном для ISR, были уже 0. Когда я впервые столкнулся с ним, я смог немного сделать резервную копию стека и увидел трассировку стека, подобную этой:
Thread [1] <main> (Suspended : Step)
0x0
0x41f42200
...
timerInterrupt() at timer.c:1,175 0x2432ec
0x41902210
...
main() at main.c:1,433 0x211a44
Где 0x40000000 - это IPSBAR для этого процессора.
Я запускал приложение несколько раз с известным состоянием, которое могло быстро воспроизвести эту проблему, обычно вплоть до той же самой трассировки стека / сохраненной инструкции, когда прерывание / исключение перед переходом к 0x0. Во время тестирования я заметил, что переход будет происходить только по инструкции после повторного включения прерываний после отключения или в части кода, где прерывания не маскировались. Итак, я подумал, что это должно быть пользовательское прерывание, вызывающее проблему, хотя я не был уверен, почему может показаться, что он пытается вызвать обработчик, который не был установлен, когда прерывание не было включено в маске. Я не уверен на 100% в значении адресов в диапазоне IPSBAR, которые предшествуют, и ISR, вызываемом, но, поскольку они одинаковы для каждого вызова этого ISR, я полагаю, что я мог бы использовать его, чтобы указать источник последнее прерывание / исключение.
Итак, я добавил обработчик прерываний по умолчанию ко всем векторам прерываний на контроллере прерываний 0 до того, как были добавлены обычные обработчики, и снова запустил приложение - и вот, точка прерывания, установленная в обработчике по умолчанию, была достигнута, когда сработало это подозрительное прерывание (например, стек выглядел так)
Thread [1] <main> (Suspended : Step)
__DefaultInterrupt() at interrupts.c
0x41f42200
...
timerInterrupt() at timer.c:1,175 0x2432ec
0x41902210
...
main() at main.c:1,433 0x211a44
Наблюдая за значением SWIACK0 в этой функции, я увидел, что источником прерывания было 100 (пользовательское прерывание 36, прерывание PIT0). Ну, это уже имеет ISR (timerInterrupt() в стеке выше). Затем я проверил область ОЗУ, в которой были сохранены указатели на функции ISR, чтобы увидеть, был ли поврежден указатель функции обработчика прерываний таймера, но не было изменений между временем, когда были установлены все обработчики прерываний, и моментом достижения точки останова в обработчике по умолчанию.
Я также заметил, что если я установлю уровень прерывания обработчика прерываний для контроллера CAN на 7 (то же самое прерывание обрабатывает все 18 источников прерываний FlexCAN), проблема не возникает. Я пока не уверен, что с этим делать, но проблема абсолютно указывает на то, что речь идет о CAN-библиотеке или контроллере.
РЕДАКТИРОВАТЬ - я не был уверен, в какой момент именно ISR обрабатывал прерывание, но я добавил отдельные обработчики к первоначально подозреваемым источникам прерываний, и это всегда источник 63 прерываний - который является неиспользованным прерыванием, согласно документации, и последний на контроллере прерываний 0.
РЕДАКТИРОВАТЬ 2: Мне пришло в голову, что активный источник прерывания в SWIACK0 на самом деле правильно, но может быть другая проблема, например, может быть переписан базовый адрес вектора. К сожалению, я не уверен, как читать его обратно, так как это значение только для записи. Сначала я думал, что источник прерываний для PIT0 был в этом регистре, потому что обработчик прерываний по умолчанию вызывался из обработчика прерываний таймера, но также указывалось, что прерывание таймера отсутствует в стеке. В справочном руководстве указано, что встроенное отладочное устройство можно использовать для считывания управляющих регистров и, следовательно, VBR, но я не вижу никакой информации в руководстве по отладке, чтобы сделать это.
Короче говоря, я хочу выяснить источник перехода в гиперпространство или какую информацию я могу использовать для его получения.
Что означает, что адреса в диапазоне IPSBAR помещаются в стек?
Так как адресуемые, кажется, полностью связаны с их источником, есть ли способ использовать значение в стеке (например, 0x41f42200 в первом примере), чтобы определить источник этого прерывания / исключения, которое
толкнул его в стек?Я иду по этому поводу совершенно неправильно? Я более чем счастлив
отказаться от любой и всей этой линии мышления.
Спасибо за любую помощь или понимание, и я дополню это более краткой информацией, когда я смогу натереть две клетки мозга, чтобы сделать это.
1 ответ
Решил проблему - оказалось, что с ошибками справился процессор.