Диагностика Imprecise Bus Faults в микроконтроллерах Cortex-M3/M4/M4F

При разработке программ для систем на микроконтроллерах серий Cortex-M3/M4/M4F программисты, бывает, сталкиваются с исключениями ядра, когда программа останавливается в бесконечном цикле в обработчике FaultISR. Как правило, попадая в этот обработчик вы уже не можете определить что произошло, т.к. стек вызовов в отладчике уже не отображается. Еще хуже, если в регистре Fault Status появится ошибка Imprecise Bus Error. Вот про диагностику этой ошибки я и расскажу.

Разрабатывая проект на микроконтроллере TI Tiva под управлением FreeRTOS я столкнулся с подобной ситуацией, когда, в результате тестирования, программа стала попадать в исключение. Падение было плавающим, т.е. момент возникновения неисправности проявлялся через случайное время после старта программы.Imprecise Bus Fault

Фирма Texas Instruments выпустила документ Diagnosing Software Faults in Stellaris ® Microcontrollers в котором содержится мого интересной информации для диагностики программных проблем. Но про Imprecise Bus Error вообще мало информации. Написано лишь, что это асинхронная ошибка и в регистре адреса не содержится точного адреса инструкции вызвавшей ошибку. В моем случае все шаги по поиску неисправности описанные у TI для Imprecise Bus Fault привели лишь в функцию vPortStartFirstTask(), эта функция запускает задачи во FreeRTOS. Тупик? Не совсем.

Плотный поиск в интернете навел меня на форум Freescale и документ A Way to Detect Imprecise Hard Fault Source. Там я и нашел более полное описание ошибки Imprescise Bus Fault и интересный способ ее диагностики. Итак, по порядку. Микроконтроллеры Cortex имеют WriteBuffer для инструкций и выполнение следующей инструкции начинается до завершения предыдущей. Это увеличивает производительность, но усложняет отладку. В случае Imprescise Bus Fault ошибку вызвыает предыдущая инструкция, когда регистр PC уже указывает на следующую в очереди команду.

К счастью, разработчики ядра Cortex, предусмотрели возможность отключения этого буфера. У микроконтроллера Kinetix фирмы Freescale это производится в регистре Auxiliary Control путем установки бита DISDEFWBUF. В моем случае у микроконтроллера Tiva TM4C1294NCPDT фирмы Texas Instruments тоже есть регистр Auxiliary Control, только бит называется DISWBUF. Думаю, что и у микроконтроллеров других производителей есть что то подобное.

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

После запуска программы я опять получил ошибку, но на этот раз это была Precise Bus Fault, что мне и было нужно. На скриншоте видно что регистр NVIC_FAULT_STAT имеет значение 0x0008200 - это и есть Precise Bus Fault. При этом в регистре NVIC_FAULT_ADDR содержится адрес инструкции вызвавшей ошибку 0х00005369. Можно посмотреть дизассемблером по этому адресу.

Это была функция xQueueGenericSend(), которая отдавала Mutex прсле использования общего ресурса. В моем случае оказалось что портился объект Mutex, а проблема была в не проинициализированном локальном указателе.

Я надеюсь что эта техника перевода Imprecise Bus Fault в Precise Bus Fault поможет кому-нибудь еще.

Комментарии

Отправить комментарий

Содержание этого поля является приватным и не предназначено к показу.
  • Syntax highlight code surrounded by the {syntaxhighlighter SPEC}...{/syntaxhighlighter} tags, where SPEC is a Syntaxhighlighter options string or "class="OPTIONS" title="the title".
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступны HTML теги: <a> <p> <span> <s> <strike> <div> <h1> <h2> <h3> <h4> <h5> <h6> <img> <map> <area> <hr> <br> <br /> <ul> <ol> <li> <dl> <dt> <dd> <table> <caption> <tbody> <tr> <td> <em> <b> <u> <i> <strong> <del> <ins> <sub> <sup> <quote> <blockquote> <pre> <address> <code> <cite> <embed> <object> <param> <strike>
  • Использовать как разделитель страниц.

Подробнее о форматировании