Comments 13
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
bkpt // пошаговый возврат в жадную задачу
bx lr
b Infinite_Loop
.size Default_Handler, .-Default_Handler
правда наверно есть виды ошибок, при которых этот механизм тоже испортится.
как сказано выше. если это продакшн то надо сохранять все регистры где возможно и показывать их после перезагрузки.
Спасибо. Я о чём-то похожем читал в руководстве по отлову проблем в IAR EWARM. Однажды словил и сильно удивлялся отсутствия backtrace'a. Давно дело было… Так что хорошо что теперь есть и на русском. Статья однозначно достойна.
Что до критики в комментариях, то размещение кода внутри HardFaultHandler это в любом случае фол последней надежды. Не должна боевая программа сюда попадать. А раз попадает, то надо выжимать максимум. Всеми доступными способами.
Ну и ещё момент. При всей грозности этого обработчика, это только обработчик. И при желании из него можно нормально выйти. На этом можно строить защиту своего кода и сводить с ума дизассемблеры явно не ожидающие такого поведения.
И всё же… Если в рабочем режиме код падает в HardFault, то это очень и очень плохо. При чем не важно чей это косяк. Программиста, схемотехника, конструктора, трассировщика, монтажника, закупщика, ОТК или ещё кого. Если такое возникает, то просто жизненно необходимо пересмотреть производственный процесс и исключить косяки. Маскировка их пусть даже грамотно написанным обработчиком — смертный грех. Исключение только целенаправленное использование HardFaultHandler'a в собственных целях. Но это экзотика на грани эзотерики.
Я запустил прошивку под отладчиком и сразу сработал FaultISRHandler().
Смотрю регистр LR а там значение 0xFFFFFFF9. Но адрес 0xFFFFFFF9 не принадлежит Flash памяти (0...0x57FA8). Что тут можно предпринять для поиска причины зависания и исправления?
Что делать, если поймал HardFault?
достаточно под отладчиков внутри HardFault набрать команду bt (backtrace) и GDB отладчик покажет из какой функции вы свалились в HardFault
Я ловил HardFault на STM32F0xx в момент когда не сбрасывался флаг прерывания от DMA после посылки в UART и через 850 микросекунд контроллер сходил с ума.
Дебажил порядка часа, чтобы понять в чем проблема. В итоге нашел, что не сбрасывается и вуаля
Надо было всего лишь добавить это в код программы:
void DMA1_Channel2_3_IRQHandler(void)
{
DMA1->IFCR = 1<<DMA_IFCR_CTCIF2_Pos;
}
Что делать, если поймал HardFault?