Install some code to catch hardware faults that prints the address via a UART. I expect you will find a your program is ending up in a non-existing fault handler so it looks dead to you.
There is also a bug, or at least I could never get it to work as documented, that you need to put this early in your code so you don't have to cycle power if you have FOPTS set for Flash and use NMI# as BOOT#:
/*
* Indicates the boot source, the boot source remains set until the
* next System Reset or software can write logic one to clear the
* corresponding mode bit. While either bit is set, the NMI input
* is disabled and the vector table is relocated to the ROM base
* address at 0x1C00_0000. These bits should be cleared by writing
* logic one before executing any code from either Flash or SRAM.
*/
if( 0U != (RCM_MR & RCM_FM_FORCEROM_MASK) )
{
RCM_FM = 0U;
RCM_MR = RCM_MR_BOOTROM_MASK;
}
This is what I use for hardware fault handler:
/** @(#)fault_hard_iprint.c <04-Oct-2013 13:17:45 Bob Paddock>
* \date Last Time-stamp: <29-May-2015 15:58:13 bob p>
*
* \file fault_hard_iprint.c
* \brief Hardware Fault Handler.
*
* This overrides the weak linkage of the empty function found in
* vectors.c.
*
* https://github.com/feabhas/CM3_Fault_Handler
* http://blog.feabhas.com/2013/02/developing-a-generic-hard-fault-handler-for-arm-cortex-m3cortex-m4/
* http://mcuoneclipse.com/2012/12/28/a-processor-expert-component-to-help-with-hard-faults/
*
* Split from _startup.c from Andrew Payne.
*
* Original code Copyright (c) 2012-2013 Andrew Payne <andy@payne.org>
*/
/*lint -save */
#include <stdio.h> /* fiprintf() */
#include <inttypes.h> /* PRIu32 */
/*
* If you don't want to use the PRI* macros, another approach for
* printing ANY integer type is to cast to intmax_t or uintmax_t and
* use "%jd" or %ju, respectively. This is especially useful for POSIX
* (or other OS) types that don't have PRI* macros defined, for
* instance off_t. -- http://stackoverflow.com/questions/3168275/printf-format-specifiers-for-uint32-t-and-size-t
*/
#include "compiler.h"
#include "fault_soft.h" /* Lockup with LED blink pattern after outputing message via fiprintf() */
#include "uart0.h"
#if 0
void HardFault_Handler_init( void );
void HardFault_Handler_init( void )
{
uart0_init( 115200 );
}
#endif
/* The register frame pushed onto the stack during exceptions: */
typedef struct {
uint32_t r0;
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r12;
uint32_t lr;
void *pc; /* Program counter is *after* the problem, the program counter has an odd address for ARM Thumb code */
uint32_t psr;
} hw_stackframe_t;
/* Handle hard faults: print debugging information and halt: */
void HardFault_Handler(void) __attribute__((naked));
void HardFault_Handler(void)
{
/* Set up arguments and invoke _HardFault_Handler(): */
asm("mov r0, lr\n" /* Arg 0 */
"mrs r1, psp\n" /* Arg 1 */
"mrs r2, msp\n" /* Arg 2 */
"b _hard_fault_handler\n");
}
void _hard_fault_handler( uint32_t const lr, void *psp, void *msp ) __attribute__(( naked, noreturn ));
void _hard_fault_handler( uint32_t const lr, void *psp, void *msp )
{
hw_stackframe_t *frame;
/* Find the active stack pointer (MSP or PSP): */
if( 0U != (lr & 0x4) )
{
frame = psp;
}
else
{
frame = msp;
}
#if 0 /* These registers are not on the M0+: */
/*
* Configurable Fault Status Register
* Consists of MMSR, BFSR and UFSR
*/
uint32_t volatile const _CFSR = (*((uint32_t volatile *)(0xE000ED28)));
uint32_t volatile const _HFSR = (*((uint32_t volatile *)(0xE000ED2C))); /* Hard Fault Status Register */
uint32_t volatile const _DFSR = (*((uint32_t volatile *)(0xE000ED30))); /* Debug Fault Status Register */
uint32_t volatile const _AFSR = (*((uint32_t volatile *)(0xE000ED3C))); /* Auxiliary Fault Status Register */
/*
* Read the Fault Address Registers. These may not contain valid values.
* Check BFARVALID/MMARVALID to see if they are valid values:
*/
uint32_t volatile const _MMAR = (*((uint32_t volatile *)(0xE000ED34))); /* MemManage Fault Address Register */
uint32_t volatile const _BFAR = (*((uint32_t volatile *)(0xE000ED38))); /* Bus Fault Address Register */
#endif
fiprintf(
stderr, "\r\n** HARD FAULT **\r\n pc=%p\r\n lr=0x%" PRIu32 "\r\n msp=%p\r\n psp=%p\r\n",
frame->pc, frame->lr, msp, psp
) ;
fault_soft_handler( 0x3F8UL); /* Blink LED and halt */
}
/*lint -restore */