Перейти к содержанию
    

Как определить по какому адресу возникло исключение HardFault ?

Товарищи,

есть проект на STM32H743 под FreeRTOS 2.0. Стал периодически улетать в HardFault. Где посмотреть по какому адресу возникло исключение ?

Перебрал все адреса, что находятся в стеке, они все ведут куда-то в дебри FreeRTOS'a. Но исключение же вызывает мой код. Как до него-то добраться ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И если используете буферы с байтовой адресацией, не пытайтесь достать из них 16- и 32-битные данные простым присваиванием с указателем., т.к. в этом случае указатель должен быть выровнен по 16- или 32-битной границе. Лучше использовать операции копирования.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

28 minutes ago, TOG said:

сть проект на STM32H743 под FreeRTOS 2.0.

Не совсем по теме. Но не слишком ли старая версия ОСРВ? Или это опечатка?

29 minutes ago, TOG said:

Где посмотреть по какому адресу возникло исключение ?

Рекомендую прочитать документацию по расшифровке этого события, т.к. там нельзя в двух словах дать ответ. Хотя бы по причине precise/imprecise события. Если не хочется вникать в серьёзную документацию от ARM, можно почитать популярную книгу Дж. Ю. У него Hard Fault целая глава посвящена.

31 minutes ago, TOG said:

Но исключение же вызывает мой код.

Не факт. Ваш код может способствовать этому. Но по факту исключение может вызывать и "идеальным" кодом ОСРВ. И адрес исключения будет именно в ОСРВ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 11/8/2023 at 11:50 AM, haker_fox said:

Не совсем по теме. Но не слишком ли старая версия ОСРВ? Или это опечатка?

Да, мой косяк, не туда посмотрел. FreeRTOS 10.3.1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Во-первых, сама IDE показывает информацию. Во-вторых, в программинг-мануале написано, в каких регистрах смотреть инфк. Главы Exception model и Fault handling в документе PM0253 на сайте st.com. 

Кстати говоря, HF может быть вызвано неверным использованием API RTOS, например попытка использовать дескриптор ещё не созданной или удаленной очереди. 

Информация о HF будет вести конечно к функционалу ядра RTOS. Косвенно, глядя в отладку можно определить, к чему именно относился участок кода RTOS на момент, предшествующий HF. И тогда уже просматривать ваш код на предмет ошибки. Скорее всего, это будет нарушение использование API

Изменено пользователем EdgeAligned

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как минимум, для начала в регистрах управления исключениями CPU нужно прочитать, отказ был точный или неточный.

В таком МК вероятность получить неточный отказ уже весьма выше, чем в его собратьях-предшественниках.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Посмотри тут. Тот же CubeIDE всё это аккуратно показывает в окне.

image.png.3c705cf5075d32ed49d8a5aa6d329d11.png

Изменено пользователем tonyk_av

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо всем за советы.

Был совершенно рабочий проект, потом добавил еще одну очередь(Queue) размером 19 байт и всё посыпалось. То HardFault, то разрушение стека. Может проработать несколько минут или несколько секунд и глюкануть.

Причем это разрушение стека больше напоминает полную порчу всей оперативки, там огромные области забиты 0xFF, а в других областях полный хаос(как после сброса питания).

У меня есть подозрение, что закончилась память выделенная FreeRTOS: TOTAL_HEAP_SIZE = 32768 байт.  Потому-что если я отключаю в программе совершенно безобидные функции, то глюки изчезают.

Есть ли способ понять, сколько там в куче свободного места ?

Проект сделан на: Keil ARM-MDK, CubeMX, TouchGFX.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, TOG said:

Есть ли способ понять, сколько там в куче свободного места ?

Это зависит только от менеджера кучи. Если используется "стандартный", то такого способа не существует. Есть вариант использовать статическую сборку FreeRTOS. Она это точно позволяет. И не использовать кучу вообще. Если, конечно же, она не требуется в других частях проекта.

1 hour ago, TOG said:

То HardFault

Скажите "Спасибо" Вселенной, что Hard Fault возникает. У Вас есть возможность проанализировать его. Обычно делают обработчик этого прерывания, который сохраняет или сразу пишет всю необходимую ифнормацию в консоль. Такой обработчик делается один раз в жизни, на него тратится один рабочий день. Но потом он много и много раз Вас спасает. Также плюс такого обработчика в том, что он может сохранить данные, например на флешку, или отправить их куда-нибудь по выделенному каналу связи. Но это уже некий эксклюзив, противопоставляемый среде отладки.

1 hour ago, TOG said:

Был совершенно рабочий проект

Не факт. Возможно, что проект уже был на грани того, чтобы посыпаться, просто не было достаточного количества энергии для этого в виде тестов или длительной эксплуатации. Но вот Вы добавили в проект что-то, и эта энергия появилась: проект посыпался.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, TOG said:

Есть ли способ понять, сколько там в куче свободного места ?

А доки на ОС пробовали читать?

size_t
	n = xPortGetFreeHeapSize();

log_printf( MsgCat::INF, "free heap size  ... %d\n", n );

 

Включите в ОС использование водяных знаков. Это когда память заполняется 0xAA и 0x55 для отслеживания её использования. В ОС есть функции отслеживания использования стэка и памяти. Почитайте и задействуйте.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кажись победил. Стек программы я отслеживал, а вот переполнение FreeRTOS'ного стека прошляпил. Я тупо смотрел на галочку CHECK_FOR_STACK_OVERFLOW = Option1 думая, что если будет переполнение, то она там в ловушке застрянет.

Однако обработчик переполнения стека оказался без "while(1) {}":

void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTaskName)
{
}

и программа просто выходила из него и продолжала работать разрушая стек и разнося все в хлам.

 

Есть ли в Keil MDK-ARM функции для отслеживания FreeRTOS задач и прочий функционал для отладки под ОС ?

У меня меню Debug / OS Support / System and thread viewer выдает пустое окошко. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, TOG said:

Я тупо смотрел на галочку CHECK_FOR_STACK_OVERFLOW = Option1 думая, что если будет переполнение, то она там в ловушке застрянет.

Сегодня программная ловушка сработала, завтра - нет. А Hard Fault Вы так и не научились отлаживать. А зря.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть хорошие инструменты для отладки RTOS, но они, все платные. Из бесплатного - то, что есть в CubeIDE.

Более того, vApplicationStackOverflowHook рекомендуется использовать только во время отладки. И оное имеет ряд ограничений. Подробности тут: FreeRTOS — стеки и проверка переполнения стека

 

Модератор: нецензурные слова не используются на форуме. Правила 2.1.б.

Изменено пользователем haker_fox
Нарушение правил 2.1.б

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...