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

nrf_fstorage_init() gives hard fault

Hi!

Working on project based on nRF52810. Everything was fine until I began to work on part to save setting in flash memory. 

I've used flash_fds example SDK 16.0 as starting point. I don't use softdevice so I choosed nvmc option.

This is my code to test library functionality:

NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage) = {
    .evt_handler = fstorage_evt_handler,
    .start_addr = 0x27000,
    .end_addr   = 0x28000,
};      


static void print_flash_info(nrf_fstorage_t * p_fstorage) {
    NRF_LOG_INFO("========| flash info |========");
    NRF_LOG_INFO("erase unit: \t%d bytes",      p_fstorage->p_flash_info->erase_unit);
    NRF_LOG_INFO("program unit: \t%d bytes",    p_fstorage->p_flash_info->program_unit);
    NRF_LOG_INFO("==============================");
}

static uint32_t nrf5_flash_end_addr_get()
{
    uint32_t const bootloader_addr = BOOTLOADER_ADDRESS;
    uint32_t const page_sz         = NRF_FICR->CODEPAGESIZE;
    uint32_t const code_sz         = NRF_FICR->CODESIZE;

    return (bootloader_addr != 0xFFFFFFFF ?
            bootloader_addr : (code_sz * page_sz));
}

void wait_for_flash_ready(nrf_fstorage_t const * p_fstorage)
{
    /* While fstorage is busy, sleep and wait for an event. */
    while (nrf_fstorage_is_busy(p_fstorage))
    {
    }
}    

static void fstorage_evt_handler(nrf_fstorage_evt_t * p_evt) {
    if (p_evt->result != NRF_SUCCESS) {
        NRF_LOG_INFO("--> Event received: ERROR while executing an fstorage operation.");
        return;
    }
    switch (p_evt->id) {
        case NRF_FSTORAGE_EVT_WRITE_RESULT: {NRF_LOG_INFO("--> Event received: wrote %d bytes at address 0x%x.", p_evt->len, p_evt->addr);} 
                                            break;
        case NRF_FSTORAGE_EVT_ERASE_RESULT: {NRF_LOG_INFO("--> Event received: erased %d page from address 0x%x.", p_evt->len, p_evt->addr);} 
                                            break;
        default: break;
    }
}

 
void main () {
    uint32_t err_code;
    err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);
    NRF_LOG_DEFAULT_BACKENDS_INIT();
    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_HFCLKSTART = 1;
    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
    //err_code = radio_init(settings.networkID, radioPacketReceived);
    //APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);
    nrf_drv_clock_lfclk_request(NULL);
    app_timer_init();

    const app_uart_comm_params_t comm_params = {
          RX_PIN_NUMBER,          
          TX_PIN_NUMBER,
          RTS_PIN_NUMBER,         
          CTS_PIN_NUMBER,
          UART_HWFC,              
          false,
          NRF_UART_BAUDRATE_9600
    };

    APP_UART_FIFO_INIT(&comm_params,
                         UART_RX_BUF_SIZE,  
                         UART_TX_BUF_SIZE,
                         uartErrorHandle,
                         APP_IRQ_PRIORITY_LOWEST,
                         err_code);
    APP_ERROR_CHECK(err_code);

    nrf_gpio_cfg_input(BUTTON_1, NRF_GPIO_PIN_PULLUP);
    nrf_gpio_pin_write(BUZZER, 0);
    nrf_gpio_cfg_output(ROW1);
    nrf_gpio_cfg_output(ROW2);
    nrf_gpio_cfg_output(ROW3);
    nrf_gpio_cfg_output(COIN_CTRL);
    nrf_gpio_cfg_output(BUZZER);

    nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
    spi_config.mosi_pin = DATA_PIN;
    spi_config.sck_pin  = SCK_PIN;
    spi_config.irq_priority  = SPI_DEFAULT_CONFIG_IRQ_PRIORITY;
    spi_config.frequency = NRF_DRV_SPI_FREQ_8M;

    // FLASH PART    
    static uint32_t m_data          = 0xBADC0FFE;
    static char     m_hello_world[] = "hello world";

    nrf_fstorage_api_t * p_fs_api;
    p_fs_api = &nrf_fstorage_nvmc;
    err_code = nrf_fstorage_init(&fstorage, p_fs_api, NULL);
    APP_ERROR_CHECK(err_code);
    print_flash_info(&fstorage);
    
    (void) nrf5_flash_end_addr_get();
    /* Let's write to flash. */
    NRF_LOG_INFO("Writing \"%x\" to flash.", m_data);
    err_code = nrf_fstorage_write(&fstorage, 0x2e000, &m_data, sizeof(m_data), NULL);
    APP_ERROR_CHECK(err_code);
    wait_for_flash_ready(&fstorage);
    NRF_LOG_INFO("Done.");

    NRF_LOG_INFO("Writing \"%s\" to flash.", m_hello_world);
    err_code = nrf_fstorage_write(&fstorage, 0x2f000, m_hello_world, sizeof(m_hello_world), NULL);
    APP_ERROR_CHECK(err_code);

    wait_for_flash_ready(&fstorage);
    NRF_LOG_INFO("Done.");
    
    uint8_t arr[20];
    err_code = nrf_fstorage_read(&fstorage, 0x2f000, &arr[0], 15);
    APP_ERROR_CHECK(err_code);

    wait_for_flash_ready(&fstorage);
    NRF_LOG_INFO(arr);
    
    while (1)
    {}
}

I left initialization code of other peripheral in case if it can interfere with storage. Also product uses ESB radio.

I'm using Segger studio and I added in flash_placement.xml file this lines of code: 

    <ProgramSection alignment="4" load="Yes" name=".fs_data" />
    <ProgramSection alignment="4" keep="Yes" load="No" name=".fs_data_run" address_symbol="__start_fs_data" end_symbol="__stop_fs_data" />

With debugger I found that program goes into Hard fault at the end of nrf_fstorage_init(&fstorage, p_fs_api, NULL) function. 

I don't have any idea why this is happening. Hopefully somebody will give a tip. 

Related