Pull to refresh

Comments 12

Вызывать какие-либо функции из обработчика Hard Fault — не очень хорошая идея, поскольку Hard Fault может быть вызван записью в указатель стека адреса, который лежит за пределами оперативной памяти. Правильнее сохранить полученную информацию в __no_init переменных или bakup-регистрах, и записывать её в энергонезависимую память и выдавать в каком-то виде вовне уже после сброса.
UFO just landed and posted this here
К сожалению, на расстоянии, ничего подсказать не могу, так как подобных проблем с FreeRTOS не имел
По моему опыту, если каждый раз регистр PC указывает в разные части программы, и биты регистра HFSR указывают на разные причины ошибки, то первым делом необходимо проверить питание.
Самый простой способ узнать причину — остановиться, и вернуться. Остановка не работает в автономном режиме, там нужно ресетить девайс.
.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 это в любом случае фол последней надежды. Не должна боевая программа сюда попадать. А раз попадает, то надо выжимать максимум. Всеми доступными способами.


Ну и ещё момент. При всей грозности этого обработчика, это только обработчик. И при желании из него можно нормально выйти. На этом можно строить защиту своего кода и сводить с ума дизассемблеры явно не ожидающие такого поведения.

Боевая программа вполне может попадать в HardFaultHandler, если используется внешняя память, и в ней хранятся указатели или код — при электромагнитных воздействиях, более мощных, чем те, на которые расчитана плата, или банальном непропае, который проявляется со временем. Это было актуально, когда микроконтроллеры с сотнями килобайт ОЗУ были недоступны, и снова становится актуально с появлением STM32F730 и STM32H750 с малым объёмом встроенной flash-памяти, который можно компенсировать выполнением какой-то части программы напрямую из Quad SPI flash-памяти. Конечно, есть задачи, где такое абсолютно недопустимо, но далеко не все. Да и внутренняя память может читаться с ошибками — например при сбоях в сигналах синхронизации и выставленных по минимуму таймингах, хотя такое бывает нечасто. Хорошо, что в новых STM32 есть ECC.

И всё же… Если в рабочем режиме код падает в HardFault, то это очень и очень плохо. При чем не важно чей это косяк. Программиста, схемотехника, конструктора, трассировщика, монтажника, закупщика, ОТК или ещё кого. Если такое возникает, то просто жизненно необходимо пересмотреть производственный процесс и исключить косяки. Маскировка их пусть даже грамотно написанным обработчиком — смертный грех. Исключение только целенаправленное использование HardFaultHandler'a в собственных целях. Но это экзотика на грани эзотерики.

Грамотно написанный обработчик нужен в первую очередь не для маскировки, а наоборот, для выявления таких случаев, в основном на этапе внутреннего тестирования, но и в эксплуатации тоже. А во вторую очередь — для быстрого восстановления работы.

Я запустил прошивку под отладчиком и сразу сработал FaultISRHandler().
Смотрю регистр LR а там значение 0xFFFFFFF9. Но адрес 0xFFFFFFF9 не принадлежит Flash памяти (0...0x57FA8). Что тут можно предпринять для поиска причины зависания и исправления?

Что делать, если поймал HardFault?

достаточно под отладчиков внутри HardFault набрать команду bt (backtrace) и GDB отладчик покажет из какой функции вы свалились в HardFault

Sign up to leave a comment.

Articles