2022-01-25 08:01 AM
I'm exploring STM32F051 using STM32CUBE IDE without use of HAL or lower level support routines (i.e., upon entry at reset vector, manually configure peripheral registers and go - so far so good 🙂
I wish to cause a reset from within hard fault handler (void HardFault_Handler(void)). I am trying to use NVIC_SystemReset() but this may not be the correct approach.
I've verified that HardFault_Handler(void) is being entered and whatever code I put there executes, however, upon exit (from the handler) the triggering event (a deliberately set up access to an invalid memory-space address) evidently recurs, creating a loop.
NVIC_SystemReset() does not compile (GCC under STM32CubeIDE 1.8.0.) The error reported by the compiler is:
./Src/main.c: In function 'HardFault_Handler':
../Src/main.c:260:2: warning: implicit declaration of function 'NVIC_SystemReset' [-Wimplicit-function-declaration]
Is NVIC_SystemReset() the correct way to cause a reset (cause the CPU to return to initial state and proceed as if reset line were temporarily actuated)? If so, am I missing a .h file?
If there's another mechanism to accomplish a reset in software, I'm happy to use it, but as a beginner I've not yet made it that far in my learning curve.
I found a very similar question asked in the ARM community (URL below) which piqued my interest, however, I'm not far enough along in my learning curve to know how to do this (modify return address at SP+18 to cause the offending instruction to be skipped), so I'd settle for a reset at this point.
Thanks!
Solved! Go to Solution.
2022-01-25 08:55 AM
NVIC_SystemReset() is part of CMSIS, it comes in core_cm0.h header. You may also look at its <10 lines implementation and handcraft your own version.
Its not uncommon to use a watchdog for reset. Then, the fault handler can so some logging... and then sit in a while loop until the watchdog reboots.
2022-01-25 08:50 AM
Yes you're missing a definition. It's in core_cm0.h which should be included within stm32f0xx.h. A project generated by CubeMX will show the correct includes and #defines necessary to get it.
You can also try HAL_NVIC_SystemReset as well, which is equivalent.
You can also just define it prior to HardFault_Handler, which will work if it's being compiled somewhere.
void NVIC_SystemReset();
void HardFault_Handler(void)
{
...
}
2022-01-25 08:55 AM
hi there!
Since you are not using HAL, you have either to include "core_cm0.h" include, where the NVIC_SystemReset() function is declared, or copy it from there by yourself.
2022-01-25 08:55 AM
NVIC_SystemReset() is part of CMSIS, it comes in core_cm0.h header. You may also look at its <10 lines implementation and handcraft your own version.
Its not uncommon to use a watchdog for reset. Then, the fault handler can so some logging... and then sit in a while loop until the watchdog reboots.
2022-01-25 09:48 AM
I did find the reset function in core_cm0.h, it's not looking like I can get (any of) it to compile without a long time spent resolving dependencies.
I was easily able to start the watchdog timer IWDG inside my HardFault_Handler code, and that worked on the first try (and provides useful experience with this component!)
Thanks very much for the helpful discussion and recommendations, I'm back to the project now with this solved.
2022-01-25 10:05 AM
Sorry, but handle hardfault this way is .... When your code once go to hardfault, it repeat after reboot and your code will catch 22
2022-01-25 10:24 AM
Thank you, MM.. 1 - I agree, that is exactly what I found when I just exited hard fault handler without any other work - a loop condition - because the classification of this cause was systemic - a software error (deliberate experiment to see what happens in hard fault event).
This solution (watchdog timer) would not fix the root cause of a systemic fault like software error, but would recover from transient fault, if reset is acceptable response to transient fault. That decision is not defined now, I am still learning basics of STM32F0 by experimentation.