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

Writing to flash in a mesh application

I would like to use the flash in legacy way. My application collects data in small chunks and I would like to store it in a continuous area.

The recommended flash manager is not suitable, because the data stored with header. This is not what I need.

The fsorage works fine as long as the mesh stack is not started. After start I get timeout because of the well known timeslot problem. Can I somehow pause the mesh before the flash operation?

The nrf_nvmc and nrfx_nvmc does not work, I get application memory access error. I tried to write to addr 0x4A000. My linker file don't use this area. Why do I get this error?

Is there any way to use some part of the flash as a continuous storage area?

Parents
  • Hi,

    I am sorry for the late reply. It is technically possible to use fstorage/FDS from the nRF5 SDK but not recommended. It has to do with time requirements in the mesh stack, and fstorage (which FDS builds on top of) can come into conflicts with mesh activity.

    It's recommended to use Flash manager instead. See more information in the nRF5 SDK NVM storage modules section in the infocenter.

    Best regards,

    Marjeris

  • Hi Marjeris!

    Thank you for the answer.

    As I mentioned in my first post, the flash manager is not able to store more than 128 bytes records. Moreover it is not able to merge small chunks into larger area. Finally to store 4 byte long data uses extra 4 byte header. This is not what I need.

    I found a working solution while studying the flash manager implementation. Here is the sniplet:


    #include "flash_manager_internal.h"
    
    static void* get_address(uint32_t offset)
    {
        return (void*)(0x4A000 + offset);
    }
    
    ret_code_t fs_write(const uint32_t offset, const uint32_t* data, const uint32_t len)
    {
        uint16_t token = 0;
        flash_operation_t op;
    
        op.type = FLASH_OP_TYPE_WRITE;
        op.params.write.p_start_addr = get_address(offset);
        op.params.write.p_data = data;
        op.params.write.length = len;
        return mesh_flash_op_push(MESH_FLASH_USER_APP, &op, &token);
    }
    
    ret_code_t fs_erase(const uint32_t offset, const uint32_t len)
    {
        uint16_t token = 0;
        flash_operation_t op;
    
        op.type = FLASH_OP_TYPE_ERASE;
        op.params.erase.p_start_addr = get_address(offset);
        op.params.erase.length = len;
        return mesh_flash_op_push(MESH_FLASH_USER_APP, &op, &token);
    }
    

    Seems stable. A completion callback can be set also for user MESH_FLASH_USER_APP.
    The address and length must be 32 bit word aligned in write and flash page aligned in erase.
    Reading is simple using pointers.
    Make sure the pages are not protected by BPROT->CONFIG registers.

    What do you think about this solution? Is it safe? Any disadvantage?

  • Hi Peter,

    I am sorry for the late reply. First I am sorry but my earlier response requires a small update. Using the Flash manager module was an older recommendation. As for Mesh SDK v5.0.0 we now recommend to use "mesh_config" modules (in which in-turn uses Flash manager).

    The solution you outlined may not be safe to work with the rest of the mesh stack. If you want to store longer than 128 byte records you can change the value of FLASH_MANAGER_ENTRY_MAX_SIZE.

    The Flash manager manages the flash and makes the flash operations transparent to the user. Because writing to any word in a flash is possible only "once". If a new value for certain entry is required to be stored it has to be stored in a new word which is not yet written. Eventually flash page fills and it needs to be defragmented. Flash manager handles all of this in the background silently.

    If you have to write large blocks of data to flash, then it's better o use the "mesh_flash.c" module, similar to the way it is used in "nrf_mesh_dfu.c" module.

Reply
  • Hi Peter,

    I am sorry for the late reply. First I am sorry but my earlier response requires a small update. Using the Flash manager module was an older recommendation. As for Mesh SDK v5.0.0 we now recommend to use "mesh_config" modules (in which in-turn uses Flash manager).

    The solution you outlined may not be safe to work with the rest of the mesh stack. If you want to store longer than 128 byte records you can change the value of FLASH_MANAGER_ENTRY_MAX_SIZE.

    The Flash manager manages the flash and makes the flash operations transparent to the user. Because writing to any word in a flash is possible only "once". If a new value for certain entry is required to be stored it has to be stored in a new word which is not yet written. Eventually flash page fills and it needs to be defragmented. Flash manager handles all of this in the background silently.

    If you have to write large blocks of data to flash, then it's better o use the "mesh_flash.c" module, similar to the way it is used in "nrf_mesh_dfu.c" module.

Children
No Data
Related