В « Компоненте Processor Expert для помощи в сложных сбоях » я использую обработчик C с некоторым кодом сборки, созданным с помощью Processor Expert, чтобы помочь мне в отладке сложных ошибок в ARM Cortex-M. Вдохновленный здесь сценарием GNU GDB , у меня теперь есть альтернативный способ. Поскольку этот подход использует подход командной строки GDB, он работает как с Eclipse GUI, так и с использованием GDB только в режиме командной строки :-).
— скрипт GDB для отладки ARM Hard Faults
Идея заключается в следующем:
- Установите точку останова в обработчике исключений серьезных сбоев
- При возникновении серьезного сбоя ЦП вызовет обработчик исключений сбоя, а отладчик остановит цель.
- Выполните скрипт / команду armex (исключение ARM) в GDB, чтобы выгрузить составленные регистры, чтобы показать счетчик программ, где произошла проблема.
Скрипт .gdbinit
Есть несколько способов расширить GDB с помощью собственных команд. Один простой способ — добавить дополнительные функции в скрипт .gdbinit, который загружается GDB при запуске.
Я добавил следующее в мой файл .gdbinit, чтобы определить мою команду ‘armex’:
define armex
printf "EXEC_RETURN (LR):\n",
info registers $lr
if $lr & 0x4 == 0x4
printf "Uses MSP 0x%x return.\n", $MSP
set $armex_base = $MSP
else
printf "Uses PSP 0x%x return.\n", $PSP
set $armex_base = $PSP
end
printf "xPSR 0x%x\n", *($armex_base+28)
printf "ReturnAddress 0x%x\n", *($armex_base+24)
printf "LR (R14) 0x%x\n", *($armex_base+20)
printf "R12 0x%x\n", *($armex_base+16)
printf "R3 0x%x\n", *($armex_base+12)
printf "R2 0x%x\n", *($armex_base+8)
printf "R1 0x%x\n", *($armex_base+4)
printf "R0 0x%x\n", *($armex_base)
printf "Return instruction:\n"
x/i *($armex_base+24)
printf "LR instruction:\n"
x/i *($armex_base+20)
end
document armex
ARMv7 Exception entry behavior.
xPSR, ReturnAddress, LR (R14), R12, R3, R2, R1, and R0
end
Вы можете разместить файл .gdbinit где угодно. Я разместил его там, где мой GDB находится внутри студии дизайна Freescale Kinetis (C: \ Freescale \ KDS_3.0.0 \ toolchain \ bin).
Чтобы убедиться, что GDB находит .gdbinit, я указываю путь к нему в настройках рабочей области Eclipse:
— Командный файл GDB в настройках Eclipse Workspace
Отладка Hard Fault
Чтобы отладить серьезную ошибку, я установил точку останова в моем обработчике прерывания жесткого сбоя, чтобы остановить отладчик при возникновении ошибки:
— остановился по грубой вине
Чтобы выяснить, где возникла проблема, я теперь использую команду ‘armex’ в консоли gdb:
Используйте меню «треугольник» консоли, чтобы перейти к представлению arm-none-eabi-gdb
Команда armex в консоли GDB
Команда armex перечисляет составленные регистры (так же, как и мой обработчик, показанный в « Отладка аппаратных ошибок в ARM Cortex-M »). Важной информацией является либо инструкция возврата, либо информация инструкции LR. Я могу ввести этот адрес в окне разборки, чтобы узнать, где возникла проблема:
Разборка Вид на причину жесткой ошибки
В приведенном выше примере LR (регистр связи или адрес возврата) был 0xbd2 (0xbd3 с установленным битом большого пальца). В представлении разборки это адрес, по которому обработчик должен вернуться, поэтому проблема должна быть как раз перед этим. При проверке ассемблерного кода есть косвенный регистр ветки
blx r3
Сложенный регистр показывает
R3 0x0
Что вызывает серьезную ошибку. Если проблема не так ясна, просто установите точку останова вокруг этого местоположения и перезапустите приложение, чтобы отладить то, что происходит до того, как произойдет сбой. С этим должно быть легко надеяться найти и решить проблему.
Резюме
Теперь у меня есть еще один способ отладки моих серьезных сбоев: использование моей собственной команды gdb для сброса накопленных регистров. Преимущество этого подхода в том, что ему не нужны никакие дополнительные ресурсы для цели (без дополнительного обработчика в коде и без переменных) по сравнению с моим более ранним решением. И дополнительное преимущество теперь в том, что я знаю, как расширить GDB с помощью своих пользовательских команд :-).