cancel
Showing results for 
Search instead for 
Did you mean: 

HardFault on STM32F746G-DISCO

MMett
Associate III

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?

1 ACCEPTED SOLUTION

Accepted Solutions

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
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

2 REPLIES 2

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
Up vote any posts that you find helpful, it shows what's working..
MMett
Associate III

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.