Skip to main content
MMett
Associate III
Jun 26, 2019 12:00 PM UTC
Solved

HardFault on STM32F746G-DISCO

I have a problem with a hardfault in my system that I cannot resolve. The problem occurred while operating the display. When I change the transparency value, hardfaults suddenly occur (BSP_LCD_SetTransparency). But elsewhere in the program.

Now I have a hardfault function that should give me information about the cause. Unfortunately I don't know how to interpret the registers.

This is the function in which the debugger jumps:

void HardFault_HandlerC(unsigned long *hardfault_args){
 
	volatile unsigned long stacked_r0 ;
	volatile unsigned long stacked_r1 ;
	volatile unsigned long stacked_r2 ;
	volatile unsigned long stacked_r3 ;
	volatile unsigned long stacked_r12 ;
	volatile unsigned long stacked_lr ;
	volatile unsigned long stacked_pc ;
	volatile unsigned long stacked_psr ;
	volatile unsigned long _CFSR ;
	volatile unsigned long _HFSR ;
	volatile unsigned long _DFSR ;
	volatile unsigned long _AFSR ;
	volatile unsigned long _BFAR ;
	volatile unsigned long _MMAR ;
 
	stacked_r0 = ((unsigned long)hardfault_args[0]) ;
	stacked_r1 = ((unsigned long)hardfault_args[1]) ;
	stacked_r2 = ((unsigned long)hardfault_args[2]) ;
	stacked_r3 = ((unsigned long)hardfault_args[3]) ;
	stacked_r12 = ((unsigned long)hardfault_args[4]) ;
	stacked_lr = ((unsigned long)hardfault_args[5]) ;
	stacked_pc = ((unsigned long)hardfault_args[6]) ;
	stacked_psr = ((unsigned long)hardfault_args[7]) ;
 
	 // Configurable Fault Status Register
 
	 // Consists of MMSR, BFSR and UFSR
 
	_CFSR = (*((volatile unsigned long *)(0xE000ED28))) ;
	// Hard Fault Status Register
	_HFSR = (*((volatile unsigned long *)(0xE000ED2C))) ;
	// Debug Fault Status Register
	_DFSR = (*((volatile unsigned long *)(0xE000ED30))) ;
	// Auxiliary Fault Status Register
	_AFSR = (*((volatile unsigned long *)(0xE000ED3C))) ;
	// Read the Fault Address Registers. These may not contain valid values.
	// Check BFARVALID/MMARVALID to see if they are valid values
	// MemManage Fault Address Register
	_MMAR = (*((volatile unsigned long *)(0xE000ED34))) ;
	// Bus Fault Address Register
	_BFAR = (*((volatile unsigned long *)(0xE000ED38))) ;
	__asm("BKPT #0\n") ; // Break into the debugger
}

What do the registers mean, or where can I find the information about them?

This topic has been closed for replies.
Tesla DeLorean
Tesla DeLoreanBest answer
Guru
Jun 26, 2019 12:28 PM UTC

The Technical Reference Manual (TRM) for the core might be a good starting point, with the books by Joseph Yiu providing a secondary perspective. ST has some Programming Manuals.

I would start perhaps by looking at the code at and immediately prior to stacked_pc, and what r0-r3, and r4-r12 might be doing there. The pointers they are using, etc.

Is the faulting address consistent? Is the fault precise, or not? Precise tends to indicate a read, where as imprecise suggests a buffered write, ie the last STR

Most frequently you're looking for out-of-bounds memory accesses, like the old 68K processors address decoding is acknowledged, and faults when nobody claims it. You have the potential for stack overflow, or alignment issues. A lot of the GNU linker scripts set the stack address wrong. You can also get alignment faults on multi-register reads/writes to memory, often with 64-bit doubles in byte aligned structures via LDRD/STRD.

Stuff that is highly random may come from interrupt handlers, if they trash the stack they might break the context they return too.

Auto/local variables are not cleared/initialized by default. String functions need NUL termination. Malloc can return NULL.

Instrument the code so could can understand the path to failure.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..

2 replies

Tesla DeLorean
Tesla DeLoreanBest answer
Guru
Jun 26, 2019 12:28 PM UTC

The Technical Reference Manual (TRM) for the core might be a good starting point, with the books by Joseph Yiu providing a secondary perspective. ST has some Programming Manuals.

I would start perhaps by looking at the code at and immediately prior to stacked_pc, and what r0-r3, and r4-r12 might be doing there. The pointers they are using, etc.

Is the faulting address consistent? Is the fault precise, or not? Precise tends to indicate a read, where as imprecise suggests a buffered write, ie the last STR

Most frequently you're looking for out-of-bounds memory accesses, like the old 68K processors address decoding is acknowledged, and faults when nobody claims it. You have the potential for stack overflow, or alignment issues. A lot of the GNU linker scripts set the stack address wrong. You can also get alignment faults on multi-register reads/writes to memory, often with 64-bit doubles in byte aligned structures via LDRD/STRD.

Stuff that is highly random may come from interrupt handlers, if they trash the stack they might break the context they return too.

Auto/local variables are not cleared/initialized by default. String functions need NUL termination. Malloc can return NULL.

Instrument the code so could can understand the path to failure.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
MMett
MMettAuthor
Associate III
Jun 27, 2019 5:54 PM UTC

Thank you so much for this short version. In fact, she helped me, although I still don't know exactly where the problem lies. Definitely but on the display. As soon as I deactivate the display, everything works. Unfortunately I don't have the time to follow the problem any further. I will have to do without the display in my project. My guess is a problem with the stack is, because the program is always crashed in a function, which contains larger arrays.