我有一个应用程序,我从Keil IDE移植到由于许可证问题而使用GNU工具链构建。我已经成功地在设备上设置,构建,刷新和运行应用程序。
GNU端的应用程序由于某种原因被卡在WWDG的弱链接IRQ处理程序中,这是一个无限循环。应用程序未启用WWDG,默认情况下在重置时禁用。我还验证了配置寄存器的默认启动值。
除了编译器之外,唯一的区别是链接器和启动文件。但是,两个工具链使用的启动文件和链接器文件都是STM生成的默认值。
知道可能导致这种情况的原因吗?我在这里结束了我的智慧。
使用stm32f103XX,如果有任何其他信息有用,请告诉我。
编辑: 使用下面的评论,我能够确定它实际上是正在触发的HardFault_Handler。 如果可能有帮助,我已经在下面包含了回溯输出
GDB BT:
0 HardFault_Handler()
1(称为信号处理程序)
2 0x720a3de在? ()
foo()中的3 0x80005534
Backtrace已停止:前一帧与此帧相同(损坏的堆栈?)
有两件事对我很突出,虽然我没有gdb专家。 1)foo不是函数,它是一个const数组的字符和2)0x0720a3de不是一个有效的内存地址,闪存地址范围从0x08000000开始
答案 0 :(得分:8)
感谢D Krueger穿着裤子。我能够发现HardFault_Handler实际上是被调用的。因此,任何偶然发现这篇文章的人,通过编写临时函数来覆盖可能的罪魁祸首,即HardFault,来验证哪个IRQ真正被调用。 IRQ调用的真正问题是memcpy的内存访问不良,我正在寻找下一步的解决方案。
答案 1 :(得分:4)
当移植STM32F3 Discovery板的示例以便在CooCox CoIDE 1.7.7中使用STM32Cube F3库(v1.1.0)进行编译时,我出现了与OP完全相同的错误(明显的WWDG中断,但实际上是HardFault_Handler触发)。只要我没有尝试使用任何中断,代码运行正常,但是当我打开SysTick定时器中断时,HardFault异常就会跳闸。
问题是我忽略了在项目中包含stm32f3xx_it.h和stm32f3xx_it.c文件。他们的缺席不会导致任何编译器警告/错误。一旦他们被编译和&在链接中,带有中断的代码运行良好。
答案 2 :(得分:2)
在合并由STM32CubeMX为STM32F2XX处理器单独生成的两个项目时,我遇到了类似的问题。一个项目是使用以太网外围设备,而另一个项目则没有。除了这一点之外,这两个项目使用了相同的外围设备。
通过手动复制文件将两个项目集成在一起后,应用程序将在启动第一个任务后(第一次启用中断时)在WWDG_IRQHandler中结束。我首先确认WWDG寄存器的WDGA位确实未设置,因此WWDG外设被禁用。接下来,我验证了中断向量表已正确初始化。最后,经过几个小时的挖掘,我意识到我没有在stm32f2xx_it.c中定义ETH_IRQHandler函数,这导致以太网中断由默认处理程序处理,将自己屏蔽为WWDG_IRQHandler - 可能是由于优化。
答案 3 :(得分:2)
由于与awilhite相同的根本原因,我遇到了这个问题。我使用的是Atollic TrueStudio 8.0.0。我用它来启动STM32F030的项目,并且(可能是手动)用stm32f0xx.h添加了库文件夹,它定义了ADC1_IRQn(NVIC设置中使用的IRQ通道号)。
我在main.c中实现了ADC1_IRQHandler(void)(因为我已经习惯了它到目前为止一直工作 - x_IRQn - > x_IRQHandler)
但经过2天的挫折,我发现,我的项目中的startup_stm32f0xx.s定义了ADC1_COMP_IRQHandler。
因此,最终,我的ADC中断处理程序未定义,当ADC产生中断时,程序崩溃(WWDG中断)。
我希望这对像我这样的人有帮助,他们认为他们确实实现了他们的处理程序,但事实上,他们没有。
答案 4 :(得分:1)
我将详细介绍导致我进入这里的原因,以及如何使用@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报告,如@DKrüger所示)。
我没有太多运气就开始研究编译器和链接器选项或链接器脚本,直到我意识到我没有检查的唯一文件是startup_stm32.s
,而 确实有所不同。
我盲目地粘贴并粘贴了!
我可以给出的解释是,发生中断时,STM32会调用startup_stm32.s
中定义的 IRQ处理程序,所有这些处理程序最初都指向Default_Handler()
(后来被{链接器)。因此,如果您复制的.c
文件定义的处理程序的名称稍有不同(但与它自己的startup_xxx.s
一致),则最终将调用Default_Handler()
(这是一个无限循环),而不是您定义的循环。结果出了问题。
有关更多信息,请参见https://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html。
我不愿意在不完全了解的情况下盲目复制粘贴,但是时间限制和里程碑通常会将您推向您不愿意探索的地区...
答案 5 :(得分:0)
核心问题是调用了默认处理程序而不是另一个irq处理程序。我怀疑我们的处境是否相同,但这是我的解决方案:
我当时在做一个c ++项目,同样的事情也发生在我身上。这是我第一次从零开始并使用CMSIS创建项目。经过一些不成功的尝试之后,我经历了一个生成的项目,当我注意到在stm32xxxx_it.h
中,IRQ处理程序函数原型受到以下方面的保护:
extern "C"
{
void TIM7_IRQHandler(void);
}
有了这些保护措施,链接器可以找到我自己的中断处理程序函数。
答案 6 :(得分:0)
就我而言,我有一个用GCC程序集编写的函数,该函数是从ARM程序集移植而来的。在将.thumb_func
行添加到汇编文件后,问题消失了。
我遇到此错误:
(gdb) c
+c
Continuing.
Program received signal SIGINT, Interrupt.
WWDG_IRQHandler () at ...startup_stm32f40_41xxx.s:121
(gdb) bt
#0 WWDG_IRQHandler () at ...startup_stm32f40_41xxx.s:12
#1 <signal handler called>
#2 RTOS_SysTick_Handler () at ...osKernel.s:18
#3 <signal handler called>
#4 0x0800021a in task0 () at ...main.cpp:10
#5 0x08000214 in frame_dummy ()
#6 0x00000000 in ?? ()
RTOS_SysTick_Handler
是用汇编语言编写的函数,WWDG_IRQHandler
总是在该函数的任何第一条汇编指令之前进行尝试(尝试了不同的指令,并且没有任何改变)。
我正在对C代码进行一些调整,在某个时候,我遇到了另一个处理程序:UsageFault
,这使我进入了.thumb_func
提示:ARM Cortex M4 SVC_Handler "UsageFault"。
答案 7 :(得分:-1)
将加我的5美分。我在stm32h7上遇到了这个问题,但是对我来说,原因是当TIM16用作时基源时,多维数据集“忘记了”添加TIM16_IRQHandler。它不是在一开始就发生的,而是在几次代码重新生成之后发生的。看起来像多维数据集中的错误,因为TIM16仍然被设置,但是中断处理程序被删除了。因此切换到TIM17并解决了该问题。