STM32 прерывание прерывания WWDG, когда не настроено

У меня есть приложение, которое я портирую из Keil IDE для сборки с помощью цепочки инструментов GNU из-за проблем с лицензией. Я успешно смог установить, собрать, прошить и запустить приложение на устройстве.

Приложение на стороне GNU по какой-то причине застревает в слабосвязанном обработчике IRQ для WWDG, который представляет собой бесконечный цикл. Приложение не включает WWDG и по умолчанию отключено при сбросе. Я также проверил, что регистры конфигурации имеют начальные значения по умолчанию.

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

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

Используя stm32f103XX, дайте мне знать, будет ли полезна любая другая информация.

РЕДАКТИРОВАТЬ: Используя комментарии ниже, я смог убедиться, что это на самом деле HardFault_Handler, который запускается. Я включил вывод обратной трассировки ниже, если это может помочь

GDB BT:

0 HardFault_Handler()

1 (обработчик сигнала вызван)

2 0x720a3de в?? ()

3 0x80005534 в foo()

Backtrace остановлен: предыдущий кадр идентичен этому кадру (поврежденный стек?)

2 вещи выделяются для меня, хотя я не эксперт GDB. 1) foo не является функцией, это константный массив символов и 2) 0x0720a3de не является действительным адресом памяти, диапазон адресов флэш-памяти начинается с 0x08000000

Ответ 1

Так что благодаря удару в штаны D Krueger. Я смог понять, что HardFault_Handler был тем, что на самом деле вызывалось. Итак, любой, кто наткнулся на этот пост, проверяет, какой IRQ действительно вызван, написав временные функции, чтобы покрыть вероятных виновников, то есть HardFault. Истинной проблемой для вызова IRQ является плохой доступ к памяти с помощью memcpy, который я нахожусь на пути к решению следующего.

Ответ 2

У меня была точно такая же ошибка, как и OP (видимое прерывание WWDG, но на самом деле стрельба HardFault_Handler) при переносе примера для платы обнаружения STM32F3 для компиляции в CooCox CoIDE 1.7.7 с библиотеками STM32Cube F3 (v1.1.0). Код работал нормально, пока я не пытался использовать какие-либо прерывания, но как только я включил прерывание таймера SysTick, исключение HardFault сработало.

Проблема заключалась в том, что я пренебрег включением файлов stm32f3xx_it.h и stm32f3xx_it.c в проект. Их отсутствие не вызывало никаких предупреждений/ошибок компилятора. Как только они были скомпилированы и связаны, код с прерываниями прошел нормально.

Ответ 3

У меня была очень похожая проблема при объединении двух проектов, созданных отдельно STM32CubeMX для процессора STM32F2XX. В одном проекте использовалось периферийное устройство Ethernet, а другое - нет. Кроме того, одна разница, два проекта использовали один и тот же набор периферийных устройств.

После объединения двух проектов путем ручного копирования файлов приложение закончится в WWDG_IRQHandler после запуска первой задачи (когда прерывания будут включены в первый раз). Сначала я подтвердил, что бит WDGA регистра WWDG действительно не установлен, и поэтому периферийное устройство WWDG было отключено. Затем я проверил, что таблица векторов прерываний была правильно инициализирована. Наконец, после нескольких часов рытья я понял, что не определил функцию ETH_IRQHandler в stm32f2xx_it.c, что вызвало прерывание Ethernet, которое обрабатывается обработчиком по умолчанию, маскируя себя как WWDG_IRQHandler - вероятно, из-за оптимизации.

Ответ 4

У меня была эта проблема из-за той же самой причины, что и awilhite. Я использую Atollic TrueStudio 8.0.0. Я использовал его для запуска проекта для STM32F030 и (возможно, вручную) добавленных библиотек в папку с stm32f0xx.h, которая определяет ADC1_IRQn (номер канала IRQ, используемый в настройке NVIC).

И я реализовал ADC1_IRQHandler (void) в моем main.c(как я привык, и он всегда работал до сих пор - x_IRQn → x_IRQHandler)

Но после 2 дней разочарования я узнал, что startup_stm32f0xx.s в моем проекте определяет ADC1_COMP_IRQHandler.

Итак, в конечном счете, мой обработчик прерываний ADC был undefined, и когда ADC сгенерировал прерывание, программа потерпела крах (прерывание WWDG).

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

Ответ 5

Я немного подробнее расскажу о том, что привело меня сюда, и как я использую понимание @Mike, чтобы исправить это.

У меня был хорошо работающий проект на демонстрационном проекте в Eclipse SW4STM32, но источники и заголовки были разбросаны повсюду, поэтому я хотел, чтобы более "компактный" проект был проще в настройке и использовании в качестве основы для незначительных изменений (и проще в следуйте в Git).

Я создал пустой проект AC6, предназначенный для той же платы. Он сгенерировал драйверы HAL, startup_stm32.s и LinkerScript.ld. Затем я скопировал все .c и соответствующий .h из исходного проекта в мой новый проект (что само по себе было болезненно, потому что они были разбросаны по каталогам BSP, CMSIS, Components, Middlewares и т.д.). Все скомпилировалось и, казалось, работало, пока я не начал немного изменять.

В отладчике казалось, что все вызовы функций работали до основного цикла while(1) где я оказался в Default_Handler определенном в startup_stm32.s, по-видимому, из WWDG_IRQHandler. Фактически это был обработчик IRQ по умолчанию для неопределяемых пользователем обработчиков (WWDG_IRQHandler был первым объявленным, gdb сообщил об этом как об этом, как указано @D Krüger).

Я без особой удачи начал изучать параметры компилятора и компоновщика или скрипт компоновщика, пока не понял, что единственным файлом, который я не проверял, является startup_stm32.s, который действительно отличался.

Я слепо скопировал его и вуаля!

Объяснение, которое я мог бы дать, состоит в том, что STM32 вызывает обработчики IRQ, определенные в startup_stm32.s когда происходит прерывание, все они изначально указывают на Default_Handler() (позже переопределенный компоновщиком). Поэтому, если скопированный вами файл .c определяет обработчик с немного другим именем (но в соответствии с его собственным startup_xxx.s), вы в конечном итоге startup_xxx.s метод Default_Handler() (который представляет собой бесконечный цикл) вместо одного вы определили И все идет не так.

См. Https://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html для получения дополнительной информации.

NB. Я не рад слепо копировать-вставлять без полного понимания, но ограничения по времени и вехи обычно толкают вас на территории, которые вы не рады исследовать...

Ответ 6

Основная проблема заключается в том, что обработчик по умолчанию вызывается вместо другого обработчика irq. Я сомневаюсь, что наши ситуации одинаковы, но вот мое решение:

Я работал над проектом c++, то же самое случилось со мной. Это был первый раз, когда я сделал проект с нуля и с помощью CMSIS. После некоторых неудачных попыток я просмотрел сгенерированный проект, когда заметил, что в stm32xxxx_it.h прототипы функций-обработчиков IRQ защищены следующими:

extern "C"
{
    void TIM7_IRQHandler(void);
}

С этими охранниками компоновщик мог найти мои собственные функции обработчика прерываний.