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

Check failed in nrf_fstorage_read()

Hi, 

I am trying to add nrf_storage to my project. The goal is to read-write-earse on flash. I have try exemple code name "flash_fstorage" and it work perfectly. 

So I decicde to add thoses functions in my project : 

static void fstorage_evt_handler(nrf_fstorage_evt_t * p_evt);

static const js_cfg_t g_def_cfg =
{
    .sof     = 0x00,
    .dev_eui = js_DEVICE_EUI,
    .app_eui = js_JOIN_EUI,
    .app_key = js_NWK_KEY,
    .dev_addr = js_DEVICE_ADDRESS,
    .nwkskey = js_NWK_S_ENC_KEY,
    .appskey = js_APP_S_KEY,
};

NRF_FSTORAGE_DEF(nrf_fstorage_t fstorage) =
{
    /* Set a handler for fstorage events. */
    .evt_handler = fstorage_evt_handler,

    /* These below are the boundaries of the flash space assigned to this instance of fstorage.
     * You must set these manually, even at runtime, before nrf_fstorage_init() is called.
     * The function nrf5_flash_end_addr_get() can be used to retrieve the last address on the
     * last page of flash available to write data. */
    .start_addr = 0x7F000,
    .end_addr   = 0x80000,
};

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.");
        NRF_LOG_FLUSH();
        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);
                         NRF_LOG_FLUSH();
        } 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);
                         NRF_LOG_FLUSH();
        } break;

        default:
            break;
    }
}

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))
    {
        //power_manage();
    }
}

void u_fs_init()
{
    ret_code_t rc;
    NRF_LOG_INFO("fstorage example started!");
    
    nrf_fstorage_api_t * p_fs_api;
    
    NRF_LOG_INFO("SoftDevice is present.");
    NRF_LOG_INFO("Initializing nrf_fstorage_sd implementation...");
    // Initialize an fstorage instance using the nrf_fstorage_sd backend.
    // nrf_fstorage_sd uses the SoftDevice to write to flash. This implementation can safely be
    // used whenever there is a SoftDevice, regardless of its status (enabled/disabled). 
    p_fs_api = &nrf_fstorage_sd;
    
    rc = nrf_fstorage_init(&fstorage, p_fs_api, NULL);
    APP_ERROR_CHECK(rc);
    
}

void u_fs_check_js_cfg(js_cfg_t *cfg)
{
    printf("%x\r\n",cfg->sof);
    if(cfg->sof != 0x55)
    {
        memcpy((uint8_t*)cfg,&g_def_cfg,sizeof(g_def_cfg));
    }
}

void u_fs_read_js_cfg(js_cfg_t *cfg)
{
    ret_code_t rc;
    rc = nrf_fstorage_read(&fstorage, fstorage.start_addr, cfg, sizeof(js_cfg_t));
    //APP_ERROR_CHECK(rc);
}

void u_fs_write_js_cfg(js_cfg_t *cfg)
{
    ret_code_t rc;
    
    rc = nrf_fstorage_erase(&fstorage, fstorage.start_addr, 1, NULL);
    NRF_LOG_INFO("erase %d", rc);
    APP_ERROR_CHECK(rc);
    wait_for_flash_ready(&fstorage);

    cfg->sof = 0x55;
    rc = nrf_fstorage_write(&fstorage, fstorage.start_addr, cfg, sizeof(js_cfg_t), NULL);
    NRF_LOG_INFO("write %d", rc);
    APP_ERROR_CHECK(rc);
    wait_for_flash_ready(&fstorage);
    printf("JS parameters configured successfully\r\n");
}

And in my main : 

typedef struct {
        uint8_t sof;
        uint8_t dev_eui[8];
        uint8_t app_eui[8];
        uint8_t app_key[16];
        uint32_t dev_addr;
        uint8_t nwkskey[16];
        uint8_t appskey[16];
} lora_cfg_t;

extern js_cfg_t     g_js_cfg;

void nRF_Js_init()
{
    //load Js configuration
    u_fs_init();
    memset((uint8_t*)&g_js_cfg,0,sizeof(g_js_cfg));
    u_fs_read_js_cfg(&g_js_cfg);
    u_fs_check_js_cfg(&g_js_cfg);
    js_init(&g_js_cfg);
    printf("js init success.\r\n");
    NRF_LOG_FLUSH();
}

But each time I try to read flash with "u_fs_read_js_cfg(js_cfg_t *cfg)", I have this error : "<error> nrf_fstorage: p_fs->p_api check failed in nrf_fstorage_read() with value 0x8." and if I try to erase : "<error> nrf_fstorage: p_fs->p_api check failed in nrf_fstorage_erase() with value 0x8." etc... !

I don't really undertstand why, I have already try with differents flash addr like ".start_addr = 0x3e000, .end_addr = 0x3ffff,". But I have the same result. Maybe, I try to read-write-erase in a flash sector already use, but I don't know how to see that ?! (At this time I use a nRF52832-QFAA.

Thanks for your help

Sani300

Parents
  • Hi.

    If either nrf_fstorage_read() or nrf_fstorage_write() returns 0x8, this means that they have invalid state, as the API suggests:

    /**@brief   Function for reading data from flash.
     *
     * Copy @p len bytes from @p addr to @p p_dest.
     *
     * @param[in]   p_fs    The fstorage instance.
     * @param[in]   addr    Address in flash where to read from.
     * @param[in]   p_dest  Buffer where the data should be copied.
     * @param[in]   len     Length of the data to be copied (in bytes).
     *
     * @retval  NRF_SUCCESS                 If the operation was successful.
     * @retval  NRF_ERROR_NULL              If @p p_fs or @p p_dest is NULL.
     * @retval  NRF_ERROR_INVALID_STATE     If the module is not initialized.
     * @retval  NRF_ERROR_INVALID_LENGTH    If @p len is zero or otherwise invalid.
     * @retval  NRF_ERROR_INVALID_ADDR      If the address @p addr is outside the flash memory
     *                                      boundaries specified in @p p_fs, or if it is unaligned.
     */
    ret_code_t nrf_fstorage_read(nrf_fstorage_t const * p_fs,
                                 uint32_t               addr,
                                 void                 * p_dest,
                                 uint32_t               len);
    
    
    /**@brief   Function for writing data to flash.
     *
     * Write @p len bytes from @p p_src to @p dest.
     *
     * When using @ref nrf_fstorage_sd, the data is written by several calls to @ref sd_flash_write if
     * the length of the data exceeds @ref NRF_FSTORAGE_SD_MAX_WRITE_SIZE bytes.
     * Only one event is sent upon completion.
     *
     * @note The data to be written to flash must be kept in memory until the operation has
     *       terminated and an event is received.
     *
     * @param[in]   p_fs        The fstorage instance.
     * @param[in]   dest        Address in flash memory where to write the data.
     * @param[in]   p_src       Data to be written.
     * @param[in]   len         Length of the data (in bytes).
     * @param[in]   p_param     User-defined parameter passed to the event handler (may be NULL).
     *
     * @retval  NRF_SUCCESS                 If the operation was accepted.
     * @retval  NRF_ERROR_NULL              If @p p_fs or @p p_src is NULL.
     * @retval  NRF_ERROR_INVALID_STATE     If the module is not initialized.
     * @retval  NRF_ERROR_INVALID_LENGTH    If @p len is zero or not a multiple of the program unit,
     *                                      or if it is otherwise invalid.
     * @retval  NRF_ERROR_INVALID_ADDR      If the address @p dest is outside the flash memory
     *                                      boundaries specified in @p p_fs, or if it is unaligned.
     * @retval  NRF_ERROR_NO_MEM            If no memory is available to accept the operation.
     *                                      When using the @ref nrf_fstorage_sd, this error
     *                                      indicates that the internal queue of operations is full.
     */
    ret_code_t nrf_fstorage_write(nrf_fstorage_t const * p_fs,
                                  uint32_t               dest,
                                  void           const * p_src,
                                  uint32_t               len,
                                  void                 * p_param);
    

    Have you properly initialized the module? It is quite hard to tell from your code.

    Best regards,

    Andreas

Reply
  • Hi.

    If either nrf_fstorage_read() or nrf_fstorage_write() returns 0x8, this means that they have invalid state, as the API suggests:

    /**@brief   Function for reading data from flash.
     *
     * Copy @p len bytes from @p addr to @p p_dest.
     *
     * @param[in]   p_fs    The fstorage instance.
     * @param[in]   addr    Address in flash where to read from.
     * @param[in]   p_dest  Buffer where the data should be copied.
     * @param[in]   len     Length of the data to be copied (in bytes).
     *
     * @retval  NRF_SUCCESS                 If the operation was successful.
     * @retval  NRF_ERROR_NULL              If @p p_fs or @p p_dest is NULL.
     * @retval  NRF_ERROR_INVALID_STATE     If the module is not initialized.
     * @retval  NRF_ERROR_INVALID_LENGTH    If @p len is zero or otherwise invalid.
     * @retval  NRF_ERROR_INVALID_ADDR      If the address @p addr is outside the flash memory
     *                                      boundaries specified in @p p_fs, or if it is unaligned.
     */
    ret_code_t nrf_fstorage_read(nrf_fstorage_t const * p_fs,
                                 uint32_t               addr,
                                 void                 * p_dest,
                                 uint32_t               len);
    
    
    /**@brief   Function for writing data to flash.
     *
     * Write @p len bytes from @p p_src to @p dest.
     *
     * When using @ref nrf_fstorage_sd, the data is written by several calls to @ref sd_flash_write if
     * the length of the data exceeds @ref NRF_FSTORAGE_SD_MAX_WRITE_SIZE bytes.
     * Only one event is sent upon completion.
     *
     * @note The data to be written to flash must be kept in memory until the operation has
     *       terminated and an event is received.
     *
     * @param[in]   p_fs        The fstorage instance.
     * @param[in]   dest        Address in flash memory where to write the data.
     * @param[in]   p_src       Data to be written.
     * @param[in]   len         Length of the data (in bytes).
     * @param[in]   p_param     User-defined parameter passed to the event handler (may be NULL).
     *
     * @retval  NRF_SUCCESS                 If the operation was accepted.
     * @retval  NRF_ERROR_NULL              If @p p_fs or @p p_src is NULL.
     * @retval  NRF_ERROR_INVALID_STATE     If the module is not initialized.
     * @retval  NRF_ERROR_INVALID_LENGTH    If @p len is zero or not a multiple of the program unit,
     *                                      or if it is otherwise invalid.
     * @retval  NRF_ERROR_INVALID_ADDR      If the address @p dest is outside the flash memory
     *                                      boundaries specified in @p p_fs, or if it is unaligned.
     * @retval  NRF_ERROR_NO_MEM            If no memory is available to accept the operation.
     *                                      When using the @ref nrf_fstorage_sd, this error
     *                                      indicates that the internal queue of operations is full.
     */
    ret_code_t nrf_fstorage_write(nrf_fstorage_t const * p_fs,
                                  uint32_t               dest,
                                  void           const * p_src,
                                  uint32_t               len,
                                  void                 * p_param);
    

    Have you properly initialized the module? It is quite hard to tell from your code.

    Best regards,

    Andreas

Children
Related