:::: MENU ::::

Hard Fault, MemManage Fault, Usage Fault, Bus Fault — Cortex-M3

Иногда при отлаживании программы можно увидеть как при зависании программы мы попадаем в HardFault_Handler. Давайте разберемся с причинами.

Если появляются ситуации, когда процессор не может правильно выполнить свою работу — то возникают отказы. Отказы можно наблюдать в обработчике прерывания отказов.

Процессор Cortex-M3 имеет следующие виды отказов:

  • тяжелые отказы (Hard Fault)
  • отказы системы управления памятью (MemManage Fault)
  • отказы программы (Usage Fault)
  • отказы шины (Bus Fault)

В startup файле от keil прерывания отказов:

HardFault_Handler\
                PROC
                EXPORT      HardFault_Handler          [WEAK]
                B       .
                ENDP
MemManage_Handler\
                PROC
                EXPORT      MemManage_Handler          [WEAK]
                B       .
                ENDP
BusFault_Handler\
                PROC
                EXPORT      BusFault_Handler           [WEAK]
                B       .
                ENDP
UsageFault_Handler\
                PROC
                EXPORT      UsageFault_Handler         [WEAK]
                B       .
                ENDP

Но если предварительно не разрешить прерывания для отказов, то при возникновении любого (Bus, Usage, MemManage, Hard Fault) отказа попадать будем в HardFaultHandler (по умолчанию HardFaultHandler всегда разрешен — запретить его можно в регистре FAULTMASK).

Для разрешения прерывания для других отказов:

SCB->SHCSR |= SCB_SHCSR_BUSFAULTENA;
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA;
SCB->SHCSR |= SCB_SHCSR_USGFAULTENA;

Рассмотрим причины отказов.

Hard Fault

Исключение Hard Fault может быть вызвано отказом программы, отказом шины или отказом системы управления памятью в том случае, если выполнение обработчиков указанных системных исключений невозможно. Также тяжёлый отказ может быть вызван отказом шины во время выборки вектора (чтения значения из таблицы векторов). Регистр состояния тяжёлого отказа HFSR контроллера NVIC позволяет определить, был ли вызван данный отказ выборкой вектора. Ecли нет, то обработчик исключения Hard Faultдолжен будет проверить содержимое других регистров xFSR для определения причины возникновения отказа (отказ Bus, Usage, MemManage).

HFSR

Bus Fault

Отказы шины возникают при получении сигнала ошибки во время обмена по шине АНВ. Обычно это происходит в следующих случаях:

  • При попытке обращения по недопустимому адресу (например, в вашем микроконтроллере RAM начинается с 0x20000000 и размером0x4000, а вы пытаетесь прочитать/записать 0x20004010 — адрес не задействован ни одной периферией микроконтроллера).
  • Если устройство не готово к обмену (например, при попытке обращения к динамическому ОЗУ до инициализации контроллера динамической памяти).
  • При попытке обмена с разрядностью, не поддерживаемой конечным устройством.

BFSR

Точный отказ — отказ , вызванный последней завершенной операцией(например, операция чтения вызовет точный отказ, поскольку команда чтения не может быть завершена до тех пор, пока не будут получены данные).

Неточный отказ — отказы, вызванный выполнением уже завершенной операции (запись с буферизацией), которая могла произойти несколько тактов назад.

В случае точного отказа шины адрес команды, вызвавшей ошибку, может быть определён из значения, сохранённого в стеке счётчика команд. Если при этом установлен бит BFARVALID регистра BFSR, то дополнительно можно будет определить адрес памяти, обращение к которому вызвало отказ шины. Значение данного адреса содержится в регистре адреса отказа шины BFAR (&(SCB->BFAR)) контроллера NVIC. ДЛЯ неточных отказов шины подобная информация недоступна, поскольку на момент получения сообщения об ошибке процессор мoг уже выполнить несколько других команд.

MemManage Fault

Отказы системы управления памятью мoгут быть вызваны обращением к памяти, конфликтующим с настройкам модуля MPU, или же некорректным обращением (например, при попытке выполнить код из области памяти, не имеющей такой возможности), которое может генерировать отказ даже в случае отсутствия модуля MPU. Наиболее частыми отказами, связанными с модулем MPU, являются:

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

MMFSR

Если MMFSR регистр показывает, что отказ произошёл при нарушении прав доступа во время обращения к данным (бит DACCVIOL) или к команде (бит IACCVIOL), то адрес команды, вызвавшей ошибку, может быть определён из значения счётчика команд, сохранённого в стеке. Если при этом установлен бит MMARVALID регистра MMFSR, то из регистра адреса отказа системы управления памятью MMFAR контроллера NVIC можно будет прочитать адрес памяти, обращение к которому вызвало отказ.

Usage Fault

Наиболее распространенной причиной возникновения отказов программы является попытка переключения процессора в режим ARM. Это может произойти при загрузке в PC нового значения со сброшенным младшим битом. Как правило это происходит при попытке перехода по команде BX или BLX по адресу, содержащемуся в регистре без предварительной установки младшего бита значения.

UFSR

Note: Более подробно об отказах можно прочитать в книге Ядро «Cortex-M3 компании ARM, полное руководство» стр. 154.