Использование трассировки стека для отладки исключения неизвестной программы на 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 в первом примере), чтобы определить источник этого прерывания / исключения, которое
    поместило его в стек ?

  • Я ошибаюсь в этом? Я более чем счастлив отказаться от всего этого образа мышления.

Спасибо за любую помощь или понимание, и я дополню это более (краткой) информацией, когда я смогу растереть две клетки мозга вместе, чтобы это сделать.


person Community    schedule 28.03.2013    source источник


Ответы (1)


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

person Community    schedule 08.04.2013