HardFault (inconsistent flags and how did I get here?)
Sometimes my modified version of the code for the STM32L152 EVAL PCB ran without the hard fault, othertimes it would end up in the HardFault_Handler. (Inconsistent flags though, sometimes INVALINSTR, sometimes STKERR, It was crazy).
Even though I implemented the suggested modifications to the HardFault handler from here: (don't forget to add #include <cross_studio_io.h>
http://blog.frankvh.com/2011/12/07/cortex-m3-m4-hard-fault-handler/
I did not arrive at an answer. However, when I made the variables that were accessed elsewhere static, that seemed to clear up the problem. I thought for sure that the compiler would not optimize something that I am passing its pointer to a function but I thought wrong.
here are the handler mods adjusted for Crossworks: (in my case from the stm32l1xx_it.c file)
// From Joseph Yiu, minor edits by FVH
// hard fault handler in C,
// with stack frame location as input parameter
// called from HardFault_Handler in file xxx.s
void hard_fault_handler_c (unsigned int * hardfault_args)
{
unsigned int stacked_r0;
unsigned int stacked_r1;
unsigned int stacked_r2;
unsigned int stacked_r3;
unsigned int stacked_r12;
unsigned int stacked_lr;
unsigned int stacked_pc;
unsigned int stacked_psr;
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]);
// remember to include #include <cross_studio_io.h>
debug_printf ("\n\n[Hard fault handler - all numbers in hex]\n");
debug_printf ("R0 = %x\n", stacked_r0);
debug_printf ("R1 = %x\n", stacked_r1);
debug_printf ("R2 = %x\n", stacked_r2);
debug_printf ("R3 = %x\n", stacked_r3);
debug_printf ("R12 = %x\n", stacked_r12);
debug_printf ("LR [R14] = %x subroutine call return address\n", stacked_lr);
debug_printf ("PC [R15] = %x program counter\n", stacked_pc);
debug_printf ("PSR = %x\n", stacked_psr);
debug_printf ("BFAR = %x\n", (*((volatile unsigned long *)(0xE000ED38))));
debug_printf ("CFSR = %x\n", (*((volatile unsigned long *)(0xE000ED28))));
debug_printf ("HFSR = %x\n", (*((volatile unsigned long *)(0xE000ED2C))));
debug_printf ("DFSR = %x\n", (*((volatile unsigned long *)(0xE000ED30))));
debug_printf ("AFSR = %x\n", (*((volatile unsigned long *)(0xE000ED3C))));
debug_printf ("SCB_SHCSR = %x\n", SCB->SHCSR);
while (1);
}
/**
* @brief This function handles Hard Fault exception.
* @param None
* @retval None
Kept the same name so no mod to the startup file is needed.
*/
void HardFault_Handler(void)
{
__asm__(".global HardFault_Handler");
__asm__(".extern hard_fault_handler_c");
__asm__("TST LR, #4");
__asm__("ITE EQ");
__asm__("MRSEQ R0, MSP");
__asm__("MRSNE R0, PSP");
__asm__("B hard_fault_handler_c");
/* Go to infinite loop when Hard Fault exception occurs */
while (1)
{}
}
-
Ok, Good basic info, but as this is hopefully a helper thread for those struggling with adjusting to ARM, GCC, and your IDE so we should do a thorough job of providing meaningfull answers.
There are GCC compiler options:
-fstack-check
-fstack-usage
-fcallgraph-info.Appear to be used heavily by the Keil (referenced in their documentation for understanding stack and heap issues) as well as other major IDE players that I checked today. The first two can be implemented on the C/C++ compiler options property (did not work for me on the C Only compiler options property).
I believe the first does not produce and output unless the stack exceeds the default or overridden value.
The second produces a .su file for each compiled source file.An example is:
//included in main
core_cm3.h:1014:22:NVIC_SetPriority 16 static
core_cm3.h:1139:26:SysTick_Config 16 static//now main
main.c:90:5:main 24 static
main.c:181:6:Test_Config 88 static
main.c:525:9:readUsartByte 24 static
main.c:548:9:writeUsartByte 16 static
main.c:576:6:clearUsart 16 static
main.c:589:6:USART1_IRQHandler 12 static
main.c:895:6:USART3_IRQHandler 12 static
main.c:1242:6:USART2_IRQHandler 12 static
main.c:1469:6:Test_SysTickConfig 8 static
main.c:1483:5:is_big_endian 16 static
main.c:1494:6:_WFE 4 staticI at the moment do not know how to implement the third option (fcallgraph-info), but am looking for help with this.
I could install doxygen and use vizgraph but I would like to stay within the IDE.
Is there a way to make those outputs part of my docking windows?
Please sign in to leave a comment.
Comments
4 comments