2021-11-22 12:07 AM
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
__asm volatile
(
" tst lr, #4 \n"
" ite eq \n"
" mrseq r0, msp \n"
" mrsne r0, psp \n"
" ldr r1, [r0, #24] \n"
" ldr r2, handler2_address_const \n"
" bx r2 \n"
" handler2_address_const: .word prvGetRegistersFromStack \n"
);
void prvGetRegistersFromStack( uint32_t *pulFaultStackAddress )
{
/* These are volatile to try and prevent the compiler/linker optimising them
away as the variables never actually get used. If the debugger won't show the
values of the variables, make them global my moving their declaration outside
of this function. */
volatile uint32_t r0;
volatile uint32_t r1;
volatile uint32_t r2;
volatile uint32_t r3;
volatile uint32_t r12;
volatile uint32_t lr; /* Link register. */
volatile uint32_t pc; /* Program counter. */
volatile uint32_t psr;/* Program status register. */
r0 = pulFaultStackAddress[ 0 ];
r1 = pulFaultStackAddress[ 1 ];
r2 = pulFaultStackAddress[ 2 ];
r3 = pulFaultStackAddress[ 3 ];
r12 = pulFaultStackAddress[ 4 ];
lr = pulFaultStackAddress[ 5 ];
pc = pulFaultStackAddress[ 6 ];
psr = pulFaultStackAddress[ 7 ];
/* When the following line is hit, the variables contain the register values. */
for( ;; );
}
Also when I try to compile assembly code in Keil it's doesn't compile.
2021-11-22 01:57 AM
2021-11-22 07:22 AM
If you're working in Keil: https://www.keil.com/appnotes/files/apnt209.pdf
STM32G0 is Cortex M0+.
2021-11-22 07:30 AM
STM32CubeIDE has a Fault Analyzer.
2021-11-22 09:47 AM
>>Can somebody have a good technique how debug HardFault_Handler?
Read some books about how the MCU functions, and handles faults. And then unpack and look at what code actually faults. I personally find having as many registers visible in the diagnostic output helps pin the problem down, even in the field. A while(1) dying in silence tells no tales..
https://github.com/cturvey/RandomNinjaChef/blob/main/KeilHardFault.c
Read/Write to unsupported memory address spaces.
Unaligned memory access.
Invalid instructions, ie ARM (32-bit), FPU (not enabled)
>>Also when I try to compile assembly code in Keil it's doesn't compile.
Learn the expected syntax of the tools you have chosen, Keil, IAR and GNU/GCC have different expectations. Keil has plenty of documentation and history in the ARM space spanning back decades.
2021-11-22 10:22 AM
Keil compilers v5 (armcc) and v.6 (clang) have different syntax for asm in C code.
The snippet above looks like old armcc syntax.
2021-11-22 10:54 AM
>> Read/Write to unsupported memory address spaces.
>> Unaligned memory access.
>> Invalid instructions, ie ARM (32-bit), FPU (not enabled)
Another cause I've come across once is when I accidentally over-clocked an STM32 (I got a clock config register wrong whilst porting, causing it to try and run at double its specced speed) - that caused a hard fault a non-deterministic number of instructions after the clock & oscillator setup was completed.
2021-11-22 03:59 PM
In-line assembly has been a continual point of failure for porting between compilers
Several instructions are not available on the Cortex-M0(+)
2021-11-23 05:25 AM
Unfortunately, I'm working on a big legacy code and the dump of the internal ARM registers didn't help me too much to go to the root of the cause.
What I did, I put benchmarks inside the code with cyclic buffer and when the Hardfault happened, I have looked at this array and it gave me a good clue what cause it.