Как стать автором
Обновить

Комментарии 10

Вызывать какие-либо функции из обработчика Hard Fault — не очень хорошая идея, поскольку Hard Fault может быть вызван записью в указатель стека адреса, который лежит за пределами оперативной памяти. Правильнее сохранить полученную информацию в __no_init переменных или bakup-регистрах, и записывать её в энергонезависимую память и выдавать в каком-то виде вовне уже после сброса.
Спасибо за статью.
А Вы не подскажете как поймать где именно в коде падает программа, если hardfault не ловится.
Пример: STM32WB55, используется FreeRTOS, непериодически программа останавливается (может через 5 секунд, может через 10 минут), hardfault и другие «сторожа» ОС не срабатывают. Падает в недрах prvPortStartFirstTask().
Но это частности.
И так, ни один хук не срабатывает, на момент останова регистр команд указывает на адрес 0x58001400 (иногда 0x58001412), по которому находятся регистры HSEM (аппаратного семафора).
Вот как поймать где именно падает программа?

Я нашел проблему только по очереди исключая использование применяемых аппаратных семафоров, в конечном итоге нашел один, если его не использовать, то все нормально.
Спасибо.
К сожалению, на расстоянии, ничего подсказать не могу, так как подобных проблем с 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 в собственных целях. Но это экзотика на грани эзотерики.

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