cancel
Showing results for 
Search instead for 
Did you mean: 

HardFault with unsigned short

lorenzo meneghello
Associate II
Posted on November 17, 2017 at 15:03

Hi all,

I'm working on my program to adapt it with the STM32F072C8, the program works on the LPC1115 and after I've translated for the ST, I found a problem.. I've this array ( unsigned short Example[254] ) but when I run the program goes on hard fault.. but if I change the array in unsigned int it works.

Any idea?

Thanks.

4 REPLIES 4
David SIORPAES
ST Employee
Posted on November 17, 2017 at 15:16

Make sure your accesses are aligned as Cortex-M0 does not support unaligned ones: 

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/BABFAIGG.html

Posted on November 17, 2017 at 17:12

The Hard Fault mechanism provides details of exactly what failed, you need to review the offending instructions to understand the fault. Look at the assembler at the fault along with the register content. A routine with a while(1) loop is not useful. Describing a variable declaration lacks any context as to the use or point of failure.

The M0 has a smaller instruction set so correct target is important. As David indicates it is also highly intolerant of misaligned memory access. If you cast this to an unsigned long pointer/access failure is quite likely.

If this is a local/auto variable make sure you have a big enough stack to hold the array.

Look EXPLICITLY at the code which is failing.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
valentin
Senior
Posted on November 18, 2017 at 07:02

You could try this hardfault handler. It reads the CPU registers and saves them in a bunch of variables.

The PC variable contains the program counter and points to the code address that failed (actually, one after it).

Using the disassembly, you can then at least get an idea of where the problem happened.

Add/change this in your stm32fxx_it.c :

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. */
__unused volatile uint32_t r0;
__unused volatile uint32_t r1;
__unused volatile uint32_t r2;
__unused volatile uint32_t r3;
__unused volatile uint32_t r12;
__unused volatile uint32_t lr; /* Link register. */
__unused volatile uint32_t pc; /* Program counter. */
__unused 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. */
Error_Handler();
}
/**
 * @brief This function handles Hard fault interrupt.
 */
void HardFault_Handler(void) {
/* USER CODE BEGIN HardFault_IRQn 0 */
__asm volatile
(
' tst lr, #4 
'
' ite eq 
'
' mrseq r0, msp 
'
' mrsne r0, psp 
'
' ldr r1, [r0, #24] 
'
' ldr r2, handler2_address_const 
'
' bx r2 
'
' handler2_address_const: .word prvGetRegistersFromStack 
'
);
/* USER CODE END HardFault_IRQn 0 */
while (1) {
}
/* USER CODE BEGIN HardFault_IRQn 1 */
/* USER CODE END HardFault_IRQn 1 */
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Posted on November 18, 2017 at 18:56

 ,

 ,

If you have printf() working, this one

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