Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

Storing values to flash using fstorage in the mesh dimming_server example

I am using the nRF5_SDK_17.0.2_d674dde and the nrf5_SDK_for_Mesh_v5.0.0. I am using the nRF52 development kit and I want to know if I can use the flash fstorage on the mesh "dimming_server" example? I noticed that you use a different method for writing the generic level server value to flash instead of using fstorage. Is it possible for me to use fstorage if I want to store a value to flash for recall after a power reset or am I restricted to using the mesh "mc" API?

Thank you, 

Sky

Parents
  • Hi,

    While it is possible to use flash libraries from nRF5 SDK with the nRF5 SDK for Mesh, we highly recommend using the Mesh configuration library if you can. The reason for using a separate flash handling library in the nRF5 SDK for Mesh, is mainly for better coexistence with the operation of the Bluetooth mesh stack.

    If using Flash Storage (fstorage) or Flash Data Storage (FDS), you must also make sure that those modules writes to different flash pages than what the modules from nRF5 SDK for Mesh does. See the nRF5 NVM storage modules section of Integrating Bluetooth mesh into nRF5 SDK examples for details.

    Regards,
    Terje

  • Terje,

    So I have implemented the functions and implementation from here and my code is crashing during runtime when I try to use my set function. Am I writing to an unusable address or am I doing something else wrong?

    //
    // Mesh store values
    //
    // Declare functions
    static void user_get(void);
    static void user_set(void);
    
    // Static Values
    static uint32_t set_value;
    static uint32_t get_value;
    
    #define APP_ENTRY_ID    MESH_CONFIG_ENTRY_ID(0x0010, 0x0001)
    /* Live RAM representation of the value */
    //static uint32_t m_live_value = 5000;
    
    //static uint32_t app_entry_setter(mesh_config_entry_id_t id, const void * p_entry)
    //{
    //    const uint32_t * p_value = (const uint32_t *) p_entry;
    //    if (*p_value >= 10000)
    //    {
    //        /* Rejecting an invalid value. The value will not be stored to persistent storage. */
    //        return NRF_ERROR_INVALID_DATA;
    //    }
    //    m_live_value = *p_value;
    //    return NRF_SUCCESS;
    //}
    //static void app_entry_getter(mesh_config_entry_id_t id, void * p_entry)
    //{
    //    uint32_t * p_value = (uint32_t *) p_entry;
    //    *p_value = m_live_value;
    //}
    
    // SET AND GET FOR FLASH STORE
    static void user_get(void)
    {
        //uint32_t set_value = 19;
        //mesh_config_entry_set(APP_ENTRY_ID, &set_value);
        //uint32_t get_value;
        mesh_config_entry_get(APP_ENTRY_ID, &get_value);
        // get_value == set_value
        //return get_value;
    }
    
    static void user_set(void)
    {
        //uint32_t set_value = 19;
        mesh_config_entry_set(APP_ENTRY_ID, &set_value);
        //uint32_t get_value;
        //mesh_config_entry_get(APP_ENTRY_ID, &get_value);
        // get_value == set_value
    }
    
    MESH_CONFIG_ENTRY(m_app_entry,
                      APP_ENTRY_ID,
                      1, // The entry is singular
                      sizeof(uint32_t),
                      user_set,
                      user_get,
                      NULL, // No need for a delete callback
                      true); // There is a default value
    

    It seems that the get function is working because it is returning a '0' when I run the debugger initially. 

    Thank you

  • Hi,

    Have you registered the config file through use of the MESH_CONFIG_FILE macro, as described under Usage in application?

    Also, please check the return values from the API functions such as mesh_config_entry_set(), mesh_config_entry_get(), etc., as that would reveal information about what has gone wrong.

    Regards,
    Terje

  • Terje, 

    Yes I did register the config file as seen below:

    /******FLASH****/
    
    MESH_CONFIG_FILE(m_app_file, 0x0010, MESH_CONFIG_STRATEGY_CONTINUOUS);

    This is my output during the debug session:

    <t:          0>, main.c,  540, ----- BLE Mesh Dimming Server Demo -----
    <t:          0>, pwm_utils.c,   88, PWM max ticks: 3200
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    2
    1
    2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>, mesh_config.c,  531, 1
    <t:          0>, mesh_config.c,  534, 2
    <t:          0>,

    This is my mesh_config.c 'mesh_config_entry_get' function with logs to see what is going on:

    uint32_t mesh_config_entry_get(mesh_config_entry_id_t id, void * p_entry)
    {
        if (p_entry == NULL)
        {
            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "NRF_ERROR_NULL\n");
            return NRF_ERROR_NULL;
        }
    
        const mesh_config_entry_params_t * p_params = entry_params_find(id);
        if (p_params)
        {
            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "1\n");
            if (p_params->has_default || (*entry_flags_get(p_params, id) & MESH_CONFIG_ENTRY_FLAG_ACTIVE))
            {
                __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "2\n");
                p_params->callbacks.getter(id, p_entry);
            }
            else
            {
                __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "NRF_ERROR_INVALID_STATE\n");
                return NRF_ERROR_INVALID_STATE;
            }
            return NRF_SUCCESS;
        }
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "NRF_ERROR_NOT_FOUND\n");
        return NRF_ERROR_NOT_FOUND;
    }

    There is no error output, the code simply crashes with no error or output available. What do you make of this?

    Thank you, 

    Sky

  • Terje, 

    I have tried to use the set function to write a '5' during the initialization function.

    static void initialize(void)
    {
        __LOG_INIT(LOG_SRC_APP | LOG_SRC_ACCESS | LOG_SRC_BEARER, LOG_LEVEL_INFO, LOG_CALLBACK_DEFAULT);
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- BLE Mesh Dimming Server Demo -----\n");
    
        pwm_utils_enable(&m_pwm0);
        ERROR_CHECK(app_timer_init());
    
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- SET -----\n");
        user_set();
    
        ble_stack_init();
    
    #if MESH_FEATURE_GATT_ENABLED
        gap_params_init();
        conn_params_init();
    #endif
    
        mesh_init();
    }

    This is my user set function:

    static void user_set(void)
    {
        set_value = 5;
        mesh_config_entry_set(APP_ENTRY_ID, &set_value);
    }
    

    When I run the code this is the output that I get:

    <t:          0>, main.c,  530, ----- BLE Mesh Dimming Server Demo -----
    <t:          0>, pwm_utils.c,   88, PWM max ticks: 3200
    <t:          0>, main.c,  537, ----- SET -----
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 6555

    I don't understand why it is looping and outputting the "ID". With no output error I can't figure out what is going on. Is this happening because I am using an invalid ID or is my flash address not usable?

    I've been looking at the enocean example as well as the generic_level_mc.c to see how to store a value to flash and there is much more complicated code at work.

    Is writing to flash on mesh a very in-depth and complicated process or is it more simple? I have followed the "Mesh configuration example" and looked all over the forums to find a solution and I am not finding any guidance to solve this issue. Do you have any suggestions that could help me understand this further?

    Thank you

Reply
  • Terje, 

    I have tried to use the set function to write a '5' during the initialization function.

    static void initialize(void)
    {
        __LOG_INIT(LOG_SRC_APP | LOG_SRC_ACCESS | LOG_SRC_BEARER, LOG_LEVEL_INFO, LOG_CALLBACK_DEFAULT);
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- BLE Mesh Dimming Server Demo -----\n");
    
        pwm_utils_enable(&m_pwm0);
        ERROR_CHECK(app_timer_init());
    
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- SET -----\n");
        user_set();
    
        ble_stack_init();
    
    #if MESH_FEATURE_GATT_ENABLED
        gap_params_init();
        conn_params_init();
    #endif
    
        mesh_init();
    }

    This is my user set function:

    static void user_set(void)
    {
        set_value = 5;
        mesh_config_entry_set(APP_ENTRY_ID, &set_value);
    }
    

    When I run the code this is the output that I get:

    <t:          0>, main.c,  530, ----- BLE Mesh Dimming Server Demo -----
    <t:          0>, pwm_utils.c,   88, PWM max ticks: 3200
    <t:          0>, main.c,  537, ----- SET -----
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 65552
    <t:          0>, mesh_config.c,  507, ID 6555

    I don't understand why it is looping and outputting the "ID". With no output error I can't figure out what is going on. Is this happening because I am using an invalid ID or is my flash address not usable?

    I've been looking at the enocean example as well as the generic_level_mc.c to see how to store a value to flash and there is much more complicated code at work.

    Is writing to flash on mesh a very in-depth and complicated process or is it more simple? I have followed the "Mesh configuration example" and looked all over the forums to find a solution and I am not finding any guidance to solve this issue. Do you have any suggestions that could help me understand this further?

    Thank you

Children
No Data
Related