STM32 WWDG interrupt firing when not configured

16,316

Solution 1

So thanks to the kick in the pants by D Krueger. I was able to figure out that the HardFault_Handler was what was actually being called. So, anyone that stumbles on this post, verify which IRQ is truly being called by writing temporary functions to cover the likely culprits i.e. HardFault. The true issue for the IRQ call is a bad memory access by memcpy which I am on my way to solving next.

Solution 2

I had exactly the same error as OP (apparent WWDG interrupt, but actually the HardFault_Handler firing) when porting an example for the STM32F3 Discovery board to compile in CooCox CoIDE 1.7.7 with STM32Cube F3 libraries (v1.1.0). The code ran fine as long as I didn't try using any interrupts, but as soon as I turned on the SysTick timer interrupt, the HardFault exception tripped.

The problem was that I had neglected to include the stm32f3xx_it.h and stm32f3xx_it.c files in the project. Their absence wasn't causing any compiler warnings/errors. Once they were compiled & linked in, the code with interrupts ran fine.

Solution 3

I've had this problem due to the same root cause as awilhite. I'm using Atollic TrueStudio 8.0.0. I used it to start a project for STM32F030 and (probably manually) added libraries folder with stm32f0xx.h, which defines ADC1_IRQn (IRQ channel number used in NVIC setup).

And I implemented ADC1_IRQHandler(void) in my main.c (as I'm used to and it always worked so far -- x_IRQn -> x_IRQHandler)

But after 2 days frustration, I found out, that startup_stm32f0xx.s in my project defines ADC1_COMP_IRQHandler.

So, ultimately, my ADC interrupt handler was undefined and when the ADC generated the interrupt, the program crashed (WWDG interrupt).

I hope this helps to people like me, who think they did implement their handler but in fact, they did not.

Solution 4

I had a very similar problem when merging two projects generated separately by STM32CubeMX for an STM32F2XX processor. One project was using the Ethernet peripheral, while the other was not. Besides that one difference, the two projects used the same set of peripherals.

After integrating the two projects together by manually copying files, the application would end up in the WWDG_IRQHandler after starting the first task (when interrupts are enabled for the first time). I first confirmed that the WDGA bit of the WWDG register was indeed not set and, therefore, that the WWDG peripheral was disabled. Next, I verified that the interrupt vector table was initialized correctly. Finally, after several hours of digging, I realized that I had not defined the ETH_IRQHandler function in stm32f2xx_it.c, which provoked the Ethernet interrupt to be handled by the default handler, masking itself as the WWDG_IRQHandler -- likely due to optimization.

Solution 5

The core problem is that the Default Handler is called instead of another irq handler. I doubt that our situations are the same but here is my solution:

I was working on a c++ project, the same happened to me. This was the first time I made a project from scratch & with CMSIS. After some unsuccessful attempts I went through a generated project when I noticed that in the stm32xxxx_it.h the IRQ handler function prototypes are guarded by these:

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

With these guards the linker could find my own interrupt handler functions.

Share:
16,316

Related videos on Youtube

gettingSmarter
Author by

gettingSmarter

Updated on July 24, 2022

Comments

  • gettingSmarter
    gettingSmarter almost 2 years

    I have an application that I am porting from the Keil IDE to build with the GNU toolchain due to license issues. I have successfully be able to set up, build, flash and run the application on the device.

    The application on the GNU side is for some reason is getting stuck in the weak linked IRQ handler for the WWDG which is an infinite loop. The application does not enable the WWDG, and it is disabled at reset by default. I have also verified that the configuration registers are at their default startup values.

    The only difference, other than compilers, are the linker and startup files. However, both the startup files, and linker files used by both toolchains are defaults generated by STM.

    Any idea what may be causing this? I'm about at my wits end here.

    Using the stm32f103XX, let me know if any other information would be helpful.

    EDIT: Using the comments below I was able to ascertain that it is, in fact, the HardFault_Handler that is being triggered. I have included the backtrace output below if that may be of help

    GDB BT:

    0 HardFault_Handler ()

    1 (signal handler called)

    2 0x720a3de in ?? ()

    3 0x80005534 in foo ()

    Backtrace stopped: previous frame identical to this frame (corrupt stack?)

    2 things stand out to me, though im no gdb expert. 1) foo is not a function, it is a const array of chars and 2) 0x0720a3de is not a valid memory address the flash address range starts at 0x08000000

    • D Krueger
      D Krueger over 9 years
      Are you sure it's really the WWDG? Another while(1); may be sharing that code due to optimization. Does the map file show only the WWDG at that address?
    • gettingSmarter
      gettingSmarter over 9 years
      You may be on to something. It appears that in the .elf file all the default irq symbols point to the same address, which I suppose means it's just a coincidence that the WWDG_IRQ name is ues in the debugger. I will add stong link functions for the irq's so I can figure out which one exactly is the culprit.
    • Kyung Lee
      Kyung Lee about 5 years
      I got stuck in the HardFault_Handler too, I spend the whole day and night to figure out the reason, it turned out that I forgot to compile all peripheral files(stm32f10x_adc.o, stm32f10x_bkp.o, stm32f10x_can.o, stm32f10x_cec.o... misc.o) and link them, I feel I'm a fool🤦🏻‍♂️
  • Clifford
    Clifford over 9 years
    I am pretty sure that you will find that the bad memory access is not "by memcpy", but rather your call to memcpy.
  • gettingSmarter
    gettingSmarter over 9 years
    The final culprit turned out to be my failure to link with the correct options I was compiling with. I forgot to link with -mthumb and -mcpu=cortex-m3 options. So I was linking with the incorrect c libraries.
  • Matthieu
    Matthieu over 5 years
    What do you put in the "temporary functions" to know which one is called? LED on through GPIO? Breakpoint?
  • Matthieu
    Matthieu over 5 years
    Thanks to you I had only one day of frustration :) The startup_xxx.s defines the function names expected for interrupt vectors. When blindly copy-pasting sources from one project to another, it is easy to miss that part, when the original code is using ADC1_IRQHandler() but the STM32 is in fact calling ADC1_COMP_IRQHandler().
  • Hamza Hajeir
    Hamza Hajeir over 3 years
    Just the exact Issue I've
  • Hamza Hajeir
    Hamza Hajeir over 3 years
    I'm using platformio, I had to manually change stm32f1xx_it.c to stm32f1xx_it.cpp too. I don't know the header file doesn't catch the __cplusplus definition, and why it's compiled with C compiler. That could be a PlatformIO issue. or my lack of understanding... maybe.