Использование трассировки стека для отладки неизвестной программной исключительной ситуации на 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 ответ

Решение

Решил проблему - оказалось, что с ошибками справился процессор.

Другие вопросы по тегам