HardFault in SoftDevice @ 0x20B55

Hi

I have a hardfault which was triggered at address 0x20B55. The memory region from the SoftDevice is from 0x1000 – 0x26633.

Can you tell me what is the root cause of this HardFault? I have no access to this region because its inside of the softdevice.

I found this, but the I don't know the root cause to fix the problem asap.

HardFault Status Register (HFSR) - 0xE000ED2C

This registers explains the reason a HardFault exception was triggered.

There’s not too much information in this register but we will go over the fields real quickly

  • DEBUGEVT- Indicates that a debug event (i.e executing a breakpoint instruction) occurred while the debug subsystem was not enabled
  • FORCED- This means a configurable fault (i.e. the fault types we discussed in previous sections) was escalated to a HardFault, either because the configurable fault handler was not enabled or a fault occurred within the handler.
  • VECTTBL- Indicates a fault occurred because of an issue reading from an address in the vector table. This is pretty atypical but could happen if there is a bad address in the vector table and an unexpected interrupt fires.

Parents
  • Hi,

    What SoftDevice variant and version are you using?

  • nRF5 SDK v17.1.0 with s140_nrf52_7.2.0_softdevice.hex

  • this is called from a app_timer_create with interrupt priority 6.

    // <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
    // <0=> 0 (highest) 
    // <1=> 1 
    // <2=> 2 
    // <3=> 3 
    // <4=> 4 
    // <5=> 5 
    // <6=> 6 
    // <7=> 7 
    
    #define APP_TIMER_CONFIG_IRQ_PRIORITY 6
    
    ret_code_t app_timer_init(void)
    
    #define SWI_IRQ_PRI             APP_TIMER_CONFIG_IRQ_PRIORITY               /**< Priority of the SWI  interrupt (used for updating the timer list). */
    
    NVIC_ClearPendingIRQ(SWI_IRQn);
    NVIC_SetPriority(SWI_IRQn, SWI_IRQ_PRI);
    NVIC_EnableIRQ(SWI_IRQn);

  • Dominik Eugster said:

    this is called from a app_timer_create with interrupt priority 6.

    Ok, good.

    Is this consistent? Does it always happen when you call sd_ble_gatts_value_set()?

    Could you show your code that calls sd_ble_gatts_value_set() ?

  • No, it's not alway happening. It happens during runnning realease without debugger every some days which makes it really difficult to get the root-cause. Its running in a mesh struct of 28 devices connected over the BLE-mesh.

    uint32_t common_ble_gatt_custon_name_write(ble_cus_t* p_cus, uint8_t* p_msg, uint8_t len)
    {
    	BLE_CUS_PRINTF("-- ble gatt custom name write\r\n");
    
    	if (p_cus == NULL)
    	{
    		return NRF_ERROR_NULL;
    	}
    
    	uint32_t err_code = NRF_SUCCESS;
    	ble_gatts_value_t gatts_value;
    	// Initialize value struct.
    	memset(&gatts_value, 0, sizeof(gatts_value));
    	gatts_value.len     = len;
    	gatts_value.offset  = 0;
    	gatts_value.p_value = p_msg;
    	// Update database.
    	err_code = sd_ble_gatts_value_set(p_cus->conn_handle,
    	                                  p_cus->custom_value_2_handles.value_handle,
    	                                  &gatts_value);
    	return err_code;
    }
    
    .... 
    
    uint32_t common_ble_gatt_custon_uart_write(ble_cus_t* p_cus, uint8_t* p_msg, uint8_t len)
    {
    	if (p_cus == NULL)
    	{
    		return NRF_ERROR_NULL;
    	}
    
    	//BLE_CUS_PRINTF("-- ble gatt custom uart write\r\n");
    	BLE_CUS_PRINTF("send msg size %d, 0x", len);
    
    	for (uint8_t i = 0; i < len; i++)
    	{
    		BLE_CUS_PRINTF("%02X", p_msg[i]);
    	}
    
    	//BLE_CUS_PRINTF("\r\n");
    	BLE_CUS_PRINTF(" - ");
    	uint32_t err_code = NRF_SUCCESS;
    	ble_gatts_value_t gatts_value;
    	// Initialize value struct.
    	memset(&gatts_value, 0, sizeof(gatts_value));
    	gatts_value.len     = len;
    	gatts_value.offset  = 0;
    	gatts_value.p_value = p_msg;
    	// Update database.
    	err_code = sd_ble_gatts_value_set(p_cus->conn_handle,
    	                                  p_cus->custom_value_1_handles.value_handle,
    	                                  &gatts_value);
    
    	if (err_code != NRF_SUCCESS)

  • Hi,

    1) I don't see anything wrong with the common_ble_gatt_custon_name_write() function itself. Could you show the code where you call common_ble_gatt_custon_name_write() ?

    2) Could you also post the code used when adding/init this characteristic?

  • Hi

    We found an Array overflow after the ringbuffer handlig on our side before calling:

    uint32_t common_ble_gatt_custon_uart_write(ble_cus_t* p_cus, uint8_t* p_msg, uint8_t len)

    We are testing this, but it looks like this was the problem of the HardFault, keep you posted.

    Regard's

Reply Children
Related