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

HardFault_Handler() called when NRF_LOG_ENABLED is disabled

In my application when I disable NRF_LOG_ENABLED, HardFault_Handler() is getting called. To debug this issue I defined a HardFault_Handler() in my code and inserted a break point in it. Below is the backtrace

#0  HardFault_Handler () at main.c:165
#1  <signal handler called>
#2  0x0002b870 in fs_init () at ../../../../Tools/nrf_SDK/nRF5x/components/libraries/fstorage/fstorage.c:290
#3  0x0002af96 in fds_init () at ../../../../Tools/nrf_SDK/nRF5x/components/libraries/fds/fds.c:1621
#4  0x00023630 in pds_init () at ../../../../Tools/nrf_SDK/nRF5x/components/ble/peer_manager/peer_data_storage.c:334
#5  0x000245e2 in pm_init () at ../../../../Tools/nrf_SDK/nRF5x/components/ble/peer_manager/peer_manager.c:470
#6  0x00030744 in peer_manager_init (erase_bonds=false) at main.c:1453
#7  0x00030b04 in main () at main.c:1626

I guess something is breaking when fs_init() is called. Note that the application runs just fine when NRF_LOG_ENABLED is set to 1. I am clueless about reason that must be triggering this hard fault? Or how to debug this hardware fault?

  • Clean the project and recompile, you may have mixed old and new compiled object files.

  • This doesn't seem to be the case as I checked it with a clean build.

  • Which SDK version are you using? Which example for the SDK are your application built on? Could you try debugging using this method, to check if you get any error codes, or which call is fausing the hardfault?

  • Short answer

    This is a memory alignment issue and it got fixed by adding . = ALIGN(4) in my linker script.

    Long answer

    I debugged the code in GDB. Problem gets manifested in the below snippet from fstorage.c

    for (uint32_t i = 0; i < total_users; i++)
    {
        fs_config_t const * const p_config = FS_SECTION_VARS_GET(i);
    
        ==>if ((p_config->p_start_addr != NULL) &&
            (p_config->p_end_addr   != NULL))
        {
            configs_to_init--;
        }
    }
    

    When I step over from this point I end up in the HardFault_Handler(). After investigation, I found that FS_SECTION_VARS_GET(i) is not returning the correct address of fs_config. Then with objdum I checked the addresses of __start_fs_data and fs_config in the object file.

    When NRF_LOG_ENABLED = 1

    200029e4 g       .data  00000000 __start_fs_data
    200029e4 l     O .data  00000010 fs_config
    

    When NRF_LOG_ENABLED = 0

    2000202a g       .data  00000000 __start_fs_data
    2000202c l     O .data  00000010 fs_config
    

    You can see that when NRF_LOG_ENABLED = 0, __start_fs_data is not aligned with fs_config and hence the macro FS_SECTION_VARS_GET(i) returns an address where valid data doesn’t exist, causing a hardware fault.

    Resolution is to add . = ALIGN(4) in your linker file as show below.

    .data : AT(_sidata)
    {
    	. = ALIGN(4);
    	_sdata = .;
    
    	PROVIDE(__data_start__ = _sdata);
    	*(.data)
    	*(.data*)
    
    ==>	. = ALIGN(4);
    
    	PROVIDE(__start_fs_data = .);
    	KEEP(*(.fs_data))
    	PROVIDE(__stop_fs_data = .);
    	
    	. = ALIGN(4);
    	_edata = .;
    
    	PROVIDE(__data_end__ = _edata);
    } > SRAM
    

    I chose to fix it this way, if anyone knows of a better solution then please let me know.

Related