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

No call of registered "flash write complete" callback function

Hi Team

I created an own interface layer using the mesh SDK's "flash_manager" to have a simple API for accessing my application flash area.

Now, I am facing the problem, that the my callback function "flash_write_complete_cb" is not called by the flash_manager. I expected to have such a call some milliseconds later after committing my allocated and filled entry buffer.

What I have checked so far:

  • the global flash_manager_init() is called before my flash manager usage
  • the functions flash_manager_add(), flash_manager_entry_count_get() flash_manager_entry_alloc(), flash_manager_entry_commit() did not throw any error
  • the behavior seems not to be a debugger (settings) issue: even in downloaded run mode, the callback function call is missing

Thanks for any replies!

Parents
  • Hello,

    So are you using the Mesh SDK, or have you ported this to another SDK? What version of the Mesh SDK did you get the flash_manager from?

    Did the flash manager work in any of the original examples?

    Best regards,

    Edvin

  • Hi

    I am using the Mesh SDK v3.0.0 with the included original flash manager. For reference, now, I tried the enocean switch example. Here, flash data storage is triggered by pressing button 1. When debugging this (unmodified) example, the callback function is called, but with the error code "FM_RESULT_ERROR_NOT_FOUND"... anyway, it could be a "user error". 

    Here you find the code snippets of my flash manager usage. It was implemented based on examples. Could it be a problem that I want to write-access the flash during initialization, before the start()-function is called in the main?

    Add the flash manager

        /* Get the start address of the flash area used by the mesh stack */
        const uint32_t * start_address;
        uint32_t allocated_area_size;
        RETURN_ON_ERROR(mesh_stack_persistence_flash_usage(&start_address, &allocated_area_size));
    
        /* Configure the application flash manager */
        flash_manager_config_t manager_config;
        manager_config.write_complete_cb = flash_write_complete_cb;
        manager_config.invalidate_complete_cb = NULL;
        manager_config.remove_complete_cb = NULL;
        manager_config.min_available_space = WORD_SIZE;
        manager_config.p_area = (const flash_manager_page_t *)((uint32_t)start_address - PAGE_SIZE * APP_FLASH_PAGE_COUNT);
        manager_config.page_count = APP_FLASH_PAGE_COUNT;       //page count set to 1
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "app page address: %d\n", manager_config.p_area);
    
        RETURN_ON_ERROR(flash_manager_add(&m_flash_manager, &manager_config));

    Init of the flash content

        /* Setup handle filter */
        fm_handle_filter_t handle_filter = {
            .mask = 0xffff,
            .match = m_entry_handle,
        };
    
        /* If there is not an entry yet, the default value is written */
        if (flash_manager_entry_count_get(&m_flash_manager, &handle_filter) == 0)
        {
            RETURN_ON_ERROR(prepare_flash_write_timer(timeout_ms));
            RETURN_ON_ERROR(app_flash_manager_write_u32(m_entry_handle, default_u32));
            RETURN_ON_ERROR(wait_flash_write());
            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "created default entry: %d\n", default_u32);
        }

    Allocate & commit the buffer for write

        /* allocate a buffer for writing to flash */
        fm_entry_t * p_entry = flash_manager_entry_alloc(&m_flash_manager, handle, sizeof(uint32_t));
        if (p_entry == NULL)
        {
            return NRF_ERROR_NO_MEM;
        }
    
        /* store the new data to the entry struct, then commit */
        uint32_t * p_u32 = (uint32_t *) p_entry->data;
        *p_u32 = new_u32;
        flash_manager_entry_commit(p_entry);
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "start write u32: %d\n", *p_u32);
    

Reply
  • Hi

    I am using the Mesh SDK v3.0.0 with the included original flash manager. For reference, now, I tried the enocean switch example. Here, flash data storage is triggered by pressing button 1. When debugging this (unmodified) example, the callback function is called, but with the error code "FM_RESULT_ERROR_NOT_FOUND"... anyway, it could be a "user error". 

    Here you find the code snippets of my flash manager usage. It was implemented based on examples. Could it be a problem that I want to write-access the flash during initialization, before the start()-function is called in the main?

    Add the flash manager

        /* Get the start address of the flash area used by the mesh stack */
        const uint32_t * start_address;
        uint32_t allocated_area_size;
        RETURN_ON_ERROR(mesh_stack_persistence_flash_usage(&start_address, &allocated_area_size));
    
        /* Configure the application flash manager */
        flash_manager_config_t manager_config;
        manager_config.write_complete_cb = flash_write_complete_cb;
        manager_config.invalidate_complete_cb = NULL;
        manager_config.remove_complete_cb = NULL;
        manager_config.min_available_space = WORD_SIZE;
        manager_config.p_area = (const flash_manager_page_t *)((uint32_t)start_address - PAGE_SIZE * APP_FLASH_PAGE_COUNT);
        manager_config.page_count = APP_FLASH_PAGE_COUNT;       //page count set to 1
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "app page address: %d\n", manager_config.p_area);
    
        RETURN_ON_ERROR(flash_manager_add(&m_flash_manager, &manager_config));

    Init of the flash content

        /* Setup handle filter */
        fm_handle_filter_t handle_filter = {
            .mask = 0xffff,
            .match = m_entry_handle,
        };
    
        /* If there is not an entry yet, the default value is written */
        if (flash_manager_entry_count_get(&m_flash_manager, &handle_filter) == 0)
        {
            RETURN_ON_ERROR(prepare_flash_write_timer(timeout_ms));
            RETURN_ON_ERROR(app_flash_manager_write_u32(m_entry_handle, default_u32));
            RETURN_ON_ERROR(wait_flash_write());
            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "created default entry: %d\n", default_u32);
        }

    Allocate & commit the buffer for write

        /* allocate a buffer for writing to flash */
        fm_entry_t * p_entry = flash_manager_entry_alloc(&m_flash_manager, handle, sizeof(uint32_t));
        if (p_entry == NULL)
        {
            return NRF_ERROR_NO_MEM;
        }
    
        /* store the new data to the entry struct, then commit */
        uint32_t * p_u32 = (uint32_t *) p_entry->data;
        *p_u32 = new_u32;
        flash_manager_entry_commit(p_entry);
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "start write u32: %d\n", *p_u32);
    

Children
  • Hello,

    I am terribly sorry for the late reply. I just tested the unmodified enocean example, and I could not replicate the FM_RESULT_ERROR_NOT_FOUND error. I just tested this example, no provisioners or servers connected. This return value is not received in the app_data_store_try() function, right? Can you specify in what function you get it?

    Is it possible to send the project (preferably the one that you initially mentioned).

    I want to see if I can reproduce it, and figure out why it is not working.

    Best regards,

    Edvin

  • Hi Edvin

    With the enocean example I just wanted to find out what I am doing wrong when using the flash manager. In the meantime I assume that it was a user fault of mine, when receiving the FM_RESULT_ERROR_NOT_FOUND, because I didn't deal a lot with this example.

    Anyway, after that, I continued to search in my own project where I had the Initial problem that the "write callback" function was not called. After diving deep into the source, I guess, I found the reason for that. I tried to write to flash during initialization. After committing the write packet, I waited for completion to read the data back before continuing the initialization code. As the Interrupts were not yet started at this time, the write only has been scheduled but never executed, and therefore, the callback function was not called.

  • Problem solved: By mistake I waited for Flash write completion during initialization, before Interrupts were enabled.

Related