Hello, guys!
We are using nRF51822 SoC with nRF5 SDK v12.3.0 and s130 SoftDevice. For the devices in the wild, we would like to implement the following health monitoring strategy:
- Detect when the fault events happen (e.g. HardFaults, App Error Faults, Watchdog reset),
- Store the info about the fault event
- Report the info about the fault event(s) to the app over the BLE link, once the connection is established.
We have overwritten the weak implementations of the HardFault_Handler() and app_error_fault_handler() functions the following way (the implementations were taken from here):
void HardFault_Handler(void) { uint32_t *sp = (uint32_t *) __get_MSP(); // Get stack pointer uint32_t ia = sp[12]; // Get instruction address from stack // Store instruction address (ia) into the memory update_hardfault_metrics(ia); NVIC_SystemReset(); }
void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info){ // Store fault identifier (id) and program counter of the instruction that caused the fault update_error_fault_metrics(id, pc); NVIC_SystemReset(); }
As you can see, inside the HardFault_Handler() we take and store the instruction address (ia) that caused the HardFault whereas in the case of app_error_fault_handler() we take and store the fault identifier (id) as well as the program counter (pc) of the instruction that caused the fault.
To test our approach, we used the following helper functions that we call from within the code to artificially provoke the faults:
To provoke HardFault event:
static int illegal_instruction_execution(void) { uint32_t dummy = *(volatile uint32_t *) 0xFFFFFFFF; (void)dummy; }
To provoke App Error Fault event:
APP_ERROR_CHECK(1);
With those helper functions, we were able to detect the fault events but in both cases, instruction address (ia) and the program counter (pc) values are both equal to 0x00.
Do you have any idea why we don't get the proper address values?
Thanks in advance.
Sincerely,
Bojan.