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

Cortex-M4 не попадает в обработчик HardFault.

STM32WLE5, FPU, MPU не используются, программа работает под scmRTOS. Программа в целом работает - LoRaWAN крутится, радиочасть работает, AES аппаратный, I2C, RTC, DMA. Во время ожидания окончания обмена по I2C + DMA, обработки AES + DMA, передачи в радиочасть через SPI + DMA ядро свободное время проводит в SLEEP, в остальных паузах, когда периферия не нужна - в режиме STOP2 ожидает RTC alarm или EXTI от радио либо кнопки. Тактирование ядра и I2C от MSI, радио от HSE, RTC - от LSE. На всех неиспользуемых векторах прерываний и исключений висят заглушки в виде пустого цикла. В том числе на NMI, исключении HardFault и прочих Fault. 
Есть кнопка, по нажатию на которую срабатывает прерывание EXTI, ядро выводится из STOP2/SLEEP и выполняет необходимые действия. Однако в редких случаях после нажатия на кнопку (ядро при этом было в STOP2) все виснет. Если отладчиком (openocd) остановить ядро, то отладчик пишет "current mode: Handler HardFault", в LR записано 0xFFFFFFF1, а в PC - 0xFFFFFFFC, то есть он не зациклен в обработчике HardFault, а пытался исполнять что-то из несуществующих адресов. При этом SCB->ICSR.VECTACTIVE = 3, в SCB->CFSR только IACCVIOL = 1, SCB->HFSR.FORCED = 1, SCB->SHCSR = 0.
Подумал, что может флеш не успевает проснуться и из таблицы векторов вычитывается неправильный адрес обработчика - перенес в ОЗУ таблицу векторов и все обработчики fault. Ничего не поменялось. 
Судя по IACCVIOL исключение MemManage возникло при попытке выполнить инструкцию из не предназначенной для инструкций области адресного пространства, но, поскольку SCB->SHCSR.MEMFAULTENA = 0 происходит эскалация до HardFault. Если сделать SCB->SHCSR.MEMFAULTENA = 1, то после остановки вся память SRAM1 оказывается забита нулями, а SRAM2 в конце которой находится вершина стека - значением 0xFFFFFFFD, несмотря на то, что эти памяти соприкасаются. Стековый кадр, сохраненный на входе в исключение - тоже одни нули. 

У меня закончились идеи, как искать причину этого поведения.
Собственно вопрос: как так может быть, что ядро находится в HardFault, но при этом не выполняет обработчик HardFault?
 

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


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

11 минут назад, Сергей Борщ сказал:

Собственно вопрос: как так может быть, что ядро находится в HardFault, но при этом не выполняет обработчик HardFault?

Например, в lockup-state. Правда, в этом случае, в PC должно быть 0xFFFFFFFE.

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


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

Хм. Понаблюдал пристальнее - когда попадаю в это состояние, и из флеша и из ОЗУ читается какой-то мусор - одно и тоже 32-битное число из всех ячеек каждой области (Flash, SRAM1, SRAM2). После сброса из ОЗУ читается нормальное содержимое предыдущего сеанса, из флеш - записанный образ прошивки. Видимо что-то отключением питания этих узлов намудрил.

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


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

1 hour ago, Сергей Борщ said:

. . .  Однако в редких случаях после нажатия на кнопку (ядро при этом было в STOP2) все виснет. . . . 

Сделать из редкого сбоя устойчивый отказ - вместо кнопки подать меандр. Возможно возникающая ошибка или "коррелированная" (как раз и вопрос, с чем), а не исключено что и время-зависимая (если в режиме отладки теряется реалтайм).

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


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

17 часов назад, k155la3 сказал:

Сделать из редкого сбоя устойчивый отказ

Я могу устойчиво вызвать сбой кнопкой.

 

Все чудесатее и чудесатее. Если в SCB->SHCSR включить все возможные исключения (MEMFAULTENA, BUSFAULTENA, USGFAULTENA), то взводится MEMFAULTACTA и в PWR->SR2 наблюдаю 0 в FLASHRDY. 

image.png.f33a6617aace2943dee1c83b1fdc59e3.png

Но я не использую LPRun и не могу в документации найти ничего про software controlled Flash power down.

Добавлено: когда наблюдаю 0 в FLASHRDY из ОЗУ тоже читается чушь - из SRAM1 читаются нули, из SRAM2 - 0xFFFFFFFD. После сброса из этих же областей ОЗУ читаются нормальные данные предыдущей сессии.

 

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


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

Еще интереснее - System Flash, OTP area, Option bytes, регистры GPIO, SYSCFG,  DMA, CRC, ADC, (LP)TIM,  I2C, RTC, IWDG, WWDG, USART, LPUART, SPI1, SPI2 тоже не читаются в этом странном состоянии (из всех читается одно и то же число). А регистры PWR, RCC, EXTI, SUBGHZSPI, NVIC,  DBGMCU, SCB, STK - читаются.

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


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

В общем, разобрался. Из-за ошибки иногда вместо Sleep отправлял ядро в Stop2, при этом останавливался таймер, который должен был разбудить и все это выглядело как зависание. А вся котовасия с IACCVIOL происходила уже когда я пытался остановить спящее ядро отладчиком, даже несмотря на установленный DBGMCU->CR.DBG_STOP - что-то у них там все-таки недоработано.

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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