This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

sd_softdevice_enable halted (hard fault)

Hi,

I have the problem as described in the title, and I have already searched and looked every thread in this forum about this issue, but none of them seems could help.

The closest case is this one: https://devzone.nordicsemi.com/f/nordic-q-a/45838/sd_softdevice_enable-hardfault/180723#180723 , but in that thread problem was solved by adding 2 preprocessor definitions, not work for me.

My situation is : I'm writing a simplest code doing a single sd_softdevice_enable() call only, and the call never returns, if I tracked it I found the code got stuck at 0x8c8, according to the above thread, that's the hard fault handler address inside MBR.

I created the project from the scratch, but have all the settings set according to the ble_app_blank example in the SDK. Here are the settings I've configured:

Set to use the flash placement file and the xml file is copied from ble_app_blank example.

The segment placement macros are set to:

FLASH_PH_START=0x0

FLASH_PH_SIZE=0x80000

RAM_PH_START=0x20000000

RAM_PH_SIZE=0x10000

FLASH_START=0x26000

FLASH_SIZE=0x5a000

RAM_START=0x20002218

RAM_SIZE=0xdde8

copied Preprocessor definitions from the ble_app_blank:

BOARD_PCA10040

CONFIG_GPIO_AS_PINRESET

FLOAT_ABI_HARD

NO_VTOR_CONFIG

NRF52

NRF52832_XXAA

NRF52_PAN_74

NRF_SD_BLE_API_VERSION=6

S132

SOFTDEVICE_PRESENT

SWI_DISABLE0

INITIALIZE_USER_SECTIONS

set the Additional Load File[0] to s132_nrf52_6.0.0_softdevice.hex

my source code is as this:

// main cpp program

#include <stdio.h>
#include <nrf.h>
#include <nrf_sdm.h> // clock_lf_cfg_t


#define NRF_SDH_CLOCK_LF_SRC 1
#define NRF_SDH_CLOCK_LF_RC_CTIV 0
#define NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 0
#define NRF_SDH_CLOCK_LF_ACCURACY 7

uint32_t result;


void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
{
    printf("nrf sd error");
}

int main(void)
{
    nrf_clock_lf_cfg_t const clock_lf_cfg =
    {
        .source = NRF_SDH_CLOCK_LF_SRC,
        .rc_ctiv = NRF_SDH_CLOCK_LF_RC_CTIV,
        .rc_temp_ctiv = NRF_SDH_CLOCK_LF_RC_TEMP_CTIV,
        .accuracy = NRF_SDH_CLOCK_LF_ACCURACY
    };
    result = sd_softdevice_enable(&clock_lf_cfg, app_error_fault_handler);
    if (result == NRF_SUCCESS)
    {
        printf("successful");
    }
    else
    {
        printf("error");
    }
    while (1);
}

I modified the ble_add_blank example's main function like this:

/**@brief Function for application main entry.
*/
int main(void)
{
    bool erase_bonds;
    nrf_clock_lf_cfg_t const clock_lf_cfg =
    {
        .source = NRF_SDH_CLOCK_LF_SRC,
        .rc_ctiv = NRF_SDH_CLOCK_LF_RC_CTIV,
        .rc_temp_ctiv = NRF_SDH_CLOCK_LF_RC_TEMP_CTIV,
        .accuracy = NRF_SDH_CLOCK_LF_ACCURACY
    };

    sd_softdevice_enable(&clock_lf_cfg, app_error_fault_handler);

...

I let it call the sd_softdevice_enable() right at the beginning of the main() and it returns correctly. But my own code just got stuck in sd_softdevice_enable(). 

As instructed in the above thread, I compared the to .map files, and couldn't find any significant difference. The __reserved_ram_end__ and _app_ram_start__ were both 0x20002218 in two files, and __vectors and __vectors_end__ were both 0x26000 and 0x260dc .

My code goes to the main() when the debugging starts, so the vector tables must work correctly. The sd_softdevice_enable() call in  ble_app_blank example code and my code both jump to address 0x90c , I think which means my code has got the correct SVC call executed.

I believe there must be some compiler or linker settings missing in my code ? But I couldn't figure it out, can anybody help here? Thank you very much!

Jian

  • Thanks Bjorn,

    The content at 0x20000000 is always 0xA801BE00 (in 32bit format), so it must not be 'random'. The memory from 0x20000000 to 0x20000100 is as below, looks like some sort of code:

    A801BE00 F0009900 E7F9F993 304046EC 230F4685 20041C1A D3000852 1E40404A B404D1FA D5F51E5B 477046E5 9D04B5E0 1E7F2700 8816D41A 072E4075 598E0EB6 4075092D 0EB6072E 092D598E 072E4075 598E0EB6 4075092D 0EB6072E 092D598E 1C924075 D1E41E9B BDE01C28 F897F000 B5F1E7E1 2A102700 1E7FD40D C971D407 191B181B 199B195B D1F43A10 9800E00A F885F000 1E7FE7F3 680ED406 199B1D09 D1F81F12 BDF21C18 F0009800 E7F4F878 680AB5F2 688C684B 27002600 D40D1E7F 599D5991 D10442A9 1EA41D36 2000D1F6 199BBDF2 600B9900 BDF22001 F85FF000 B5F1E7EE 2A102700 1E7FD41C C971D40B D10C4283 D10D42A3 D10E42AB D10F42B3 D1F03A10

    I zipped my entire project folder and uploaded it here, and for your information my working environment is : Segger Embedded Studio 4.16 for Linux, the 'softdevice' subdirectory in 'nRF' is copied from nRF_SDK_15.0.0_a53641a. nRF_cpp_test.zip

    Thank you!

  • You had Debug > Debugger > Start From Entry Point Symbol set to Yes. It should be set to No, otherwise the Debugger will reset the device and jump directly to the application code without executing the MBR and SD first. 

    Best regards

    Bjørn 

  • Big Thanks Bjorn, the solutions is that simple! It works now!

    Regards,

    Jian

Related