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

Loop in flash_manager_wait function() Mesh SDK 2.2.0, Light Switch Proxy Server Example

Hello, i am having problems with a loop in the function "flash_manager_wait()"; in the begining of the code.

main()-> initialize()-> mesh_init()-> mesh_stack_init(&init_params, &m_device_provisioned))-> dsm_flash_config_load()-> (void) dsm_flash_config_load()-> flash_manager_wait();

static inline void flash_manager_wait(void)
{
#if !defined(HOST)
//__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "HOLA 1..1..0..1\n");
while (!flash_manager_is_stable())
{
/* Temporary hack to make sure that bearer events are handled while waiting for
* the flash manager to finish.
* TODO: Find a solution for this that does not include busy-waiting. */
if (bearer_event_handler())
{
__WFE();
}
}
#endif
}

this happen after many reboots thath i do each 1 minute, and the only form to recover it, is erase all the flash, and re flashing soft-device and program.

i do the reboot whit the timer1 and the " function mesh_stack_device_reset()"

 void TIMER1_IRQHandler(void)
    {
        if (NRF_TIMER1->EVENTS_COMPARE[0] == 1 )
            {  
              __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- Count1 -----\n");
              NRF_TIMER1->EVENTS_COMPARE[0] =  0;
              if ( TIMER_REINICIO1 == 1)
              {
                 
                 nrf_delay_ms(100);
                  mesh_stack_device_reset();
                 
              }
            }
            
        if (NRF_TIMER1->EVENTS_COMPARE[1] == 1)
            {  
               __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- Count2 -----\n");
               NRF_TIMER1->EVENTS_COMPARE[1] = 0;
               
               if ( TIMER_REINICIO2 == 1)
              {
                
                 nrf_delay_ms(100);
                   mesh_stack_device_reset();
                 
              }
               
            }
    }

help please.

Parents
  • Hello,

    Is there a particular reason you have the nrf_delay_ms(100) in your timeout handler? It probably isn't that scary to use in mesh, but it may caused some unexpected behavior when you also use the "normal" BLE stack (proxy-example). At least if the softdevice is still running.

    I suspect that what might have happened is that the device is reset due to a softdevice assert, and not due to mesh_stack_device_reset(); at one point in time, and it was reset with an unstable flash, since the chip is halted for 100ms, which may crash with some softdevice event. When it returns, and is about to continue with the mesh_stack_device_reset, it may have been interrupted by a softdevice assert before having the time to do this.

    Can you try to remove the nrf_delay_ms() (also if you use them any other places).

    If that doesn't help, can you check which of the checks inside flash_manager_is_stable() that returns false?

    return (!packet_buffer_can_pop(&m_action_queue) && !flash_manager_defrag_is_running());

    Either packet_buffer_can_pop(&m_action_queue) returns true, or flash_manager_defrag_is_running() returns true.

    If you are still stuck after this, is it possible to send a project and some instructions on how I can replicate this?

    Best regards,

    Edvin

Reply
  • Hello,

    Is there a particular reason you have the nrf_delay_ms(100) in your timeout handler? It probably isn't that scary to use in mesh, but it may caused some unexpected behavior when you also use the "normal" BLE stack (proxy-example). At least if the softdevice is still running.

    I suspect that what might have happened is that the device is reset due to a softdevice assert, and not due to mesh_stack_device_reset(); at one point in time, and it was reset with an unstable flash, since the chip is halted for 100ms, which may crash with some softdevice event. When it returns, and is about to continue with the mesh_stack_device_reset, it may have been interrupted by a softdevice assert before having the time to do this.

    Can you try to remove the nrf_delay_ms() (also if you use them any other places).

    If that doesn't help, can you check which of the checks inside flash_manager_is_stable() that returns false?

    return (!packet_buffer_can_pop(&m_action_queue) && !flash_manager_defrag_is_running());

    Either packet_buffer_can_pop(&m_action_queue) returns true, or flash_manager_defrag_is_running() returns true.

    If you are still stuck after this, is it possible to send a project and some instructions on how I can replicate this?

    Best regards,

    Edvin

Children
  • Can you try to remove the nrf_delay_ms() (also if you use them any other places).

    i tried this, but happen the same.

    If that doesn't help, can you check which of the checks inside flash_manager_is_stable() that returns false?

    (!packet_buffer_can_pop(&m_action_queue) && !flash_manager_defrag_is_running()); = 0

    is it possible to send a project and some instructions on how I can replicate this?

    i am using nrf52 DK, and Mesh Sdk 2.2.0 whit softdevice 6.0.0, the light_switch_proxy_server_nrf52832_xxAA_s132_6_0_0

    just changue the main file, program the board, init Jlink rtt viewer and wait. until the board stop.

    /* Copyright (c) 2010 - 2018, Nordic Semiconductor ASA Original
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     * list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
    *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    #include <stdint.h>
    #include <string.h>
    
    /* HAL */
    #include "boards.h"
    #include "simple_hal.h"
    #include "app_timer.h"
    
    /* Core */
    #include "sdk_config.h"
    #include "nrf_mesh_configure.h"
    #include "nrf_mesh.h"
    #include "mesh_stack.h"
    #include "device_state_manager.h"
    #include "access_config.h"
    #include "net_state.h"
    #include "mesh_adv.h"
    #include "nrf_sdh.h"
    #include "nrf_sdh_ble.h"
    #include "nrf_sdh_soc.h"
    #include "ble_conn_params.h"
    #include "ble_hci.h"
    #include "proxy.h"
    #include "mesh_opt_gatt.h"
    #include "mesh_config.h"
    
    /* Provisioning and configuration */
    #include "mesh_provisionee.h"
    #include "mesh_app_utils.h"
    #include "mesh_softdevice_init.h"
    
    /* Models */
    #include "generic_onoff_server.h"
    
    /* Logging and RTT */
    #include "log.h"
    #include "rtt_input.h"
    
    /* Example specific includes */
    #include "app_config.h"
    #include "example_common.h"
    #include "nrf_mesh_config_examples.h"
    #include "light_switch_example_common.h"
    #include "app_onoff.h"
    
    #include "nrf_delay.h"
    
    #define ONOFF_SERVER_0_LED          (BSP_LED_0)
    
    #define DEVICE_NAME                     "nRF5x Mesh Light"
    #define MIN_CONN_INTERVAL               MSEC_TO_UNITS(150,  UNIT_1_25_MS)           /**< Minimum acceptable connection interval. */
    #define MAX_CONN_INTERVAL               MSEC_TO_UNITS(250,  UNIT_1_25_MS)           /**< Maximum acceptable connection interval. */
    #define SLAVE_LATENCY                   0                                           /**< Slave latency. */
    #define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)             /**< Connection supervisory timeout (4 seconds). */
    #define FIRST_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(100)                        /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called. */
    #define NEXT_CONN_PARAMS_UPDATE_DELAY   APP_TIMER_TICKS(2000)                       /**< Time between each call to sd_ble_gap_conn_param_update after the first call. */
    #define MAX_CONN_PARAMS_UPDATE_COUNT    3                                           /**< Number of attempts before giving up the connection parameter negotiation. */
    
    static bool m_device_provisioned;
    
    static void gap_params_init(void);
    static void conn_params_init(void);
    
    /*************************************************************************************************/
    static void app_onoff_server_set_cb(const app_onoff_server_t * p_server, bool onoff);
    static void app_onoff_server_get_cb(const app_onoff_server_t * p_server, bool * p_present_onoff);
    bool TIMER_REINICIO1 = 0, TIMER_REINICIO2 = 0;
    
    /* Generic OnOff server structure definition and initialization */
    APP_ONOFF_SERVER_DEF(m_onoff_server_0,
                         APP_CONFIG_FORCE_SEGMENTATION,
                         APP_CONFIG_MIC_SIZE,
                         app_onoff_server_set_cb,
                         app_onoff_server_get_cb)
    
    /* Callback for updating the hardware state */
    static void app_onoff_server_set_cb(const app_onoff_server_t * p_server, bool onoff)
    {
        /* Resolve the server instance here if required, this example uses only 1 instance. */
    
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Setting GPIO value: %d\n", onoff)
    
        hal_led_pin_set(ONOFF_SERVER_0_LED, onoff);
    }
    
    /* Callback for reading the hardware state */
    static void app_onoff_server_get_cb(const app_onoff_server_t * p_server, bool * p_present_onoff)
    {
        /* Resolve the server instance here if required, this example uses only 1 instance. */
    
        *p_present_onoff = hal_led_pin_get(ONOFF_SERVER_0_LED);
    }
    
    static void app_model_init(void)
    {
        /* Instantiate onoff server on element index 0 */
        ERROR_CHECK(app_onoff_init(&m_onoff_server_0, 0));
    }
    
    /*************************************************************************************************/
     void config_TIMER ()
    {
     NRF_TIMER1->TASKS_STOP = 1;
     NRF_TIMER1->MODE=0;//TIMER MODE
     NRF_TIMER1->BITMODE= 3;//32 bit
     NRF_TIMER1->PRESCALER=9;
     NRF_TIMER1->CC[0] = 0X3D09*3;//0X3D09 for 500mS
     NRF_TIMER1->CC[1] = 0X15752A0/960;//0X15752A0 for 12 Minutes
     NRF_TIMER1->TASKS_CLEAR = 1; /* Clear timer */
     NRF_TIMER1->INTENSET=0X030000;//ENABLE COMPARE0 Y COMPARE1
     #define TIMER1_IRQ_LEVEL (15)///7
     NVIC_SetPriority(TIMER1_IRQn, TIMER1_IRQ_LEVEL); 
     NVIC_EnableIRQ(TIMER1_IRQn);
     NRF_TIMER1->EVENTS_COMPARE[0] =0;
     NRF_TIMER1->EVENTS_COMPARE[1] =0;
     //NRF_TIMER1->TASKS_START = 0;
    }
    
     void TIMER1_IRQHandler(void)
        {
            if (NRF_TIMER1->EVENTS_COMPARE[0] == 1 )
                {  
                  __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- TIMER1 -----\n");
                  NRF_TIMER1->EVENTS_COMPARE[0] =  0;
                  if ( TIMER_REINICIO1 == 1)
                  {
                     __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- TIMER1: \n");
                    // nrf_delay_ms(100);
                      mesh_stack_device_reset();
                     //NVIC_SystemReset();
                  }
                }
                
            if (NRF_TIMER1->EVENTS_COMPARE[1] == 1)
                {  
                   __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- TIMER2 -----\n");
                   NRF_TIMER1->EVENTS_COMPARE[1] = 0;
                   
                   if ( TIMER_REINICIO2 == 1)
                  {
                     __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- TIMER2: \n");
                     //nrf_delay_ms(100);
                       mesh_stack_device_reset();
                     //NVIC_SystemReset();
                  }
                   
                }
        }
    
    /////////////////////////////////////////////////////////////////////////////////////////////
    
    static void on_sd_evt(uint32_t sd_evt, void * p_context)
    {
        (void) nrf_mesh_on_sd_evt(sd_evt);
    }
    
    NRF_SDH_SOC_OBSERVER(mesh_observer, NRF_SDH_BLE_STACK_OBSERVER_PRIO, on_sd_evt, NULL);
    
    static void node_reset(void)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- Node reset  -----\n");
        hal_led_blink_ms(LEDS_MASK, LED_BLINK_INTERVAL_MS, LED_BLINK_CNT_RESET);
        /* This function may return if there are ongoing flash operations. */
        mesh_stack_device_reset();
    }
    
    static void config_server_evt_cb(const config_server_evt_t * p_evt)
    {
        if (p_evt->type == CONFIG_SERVER_EVT_NODE_RESET)
        {
            node_reset();
        }
    }
    
    static void button_event_handler(uint32_t button_number)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Button %u pressed\n", button_number);
        switch (button_number)
        {
            /* Pressing SW1 on the Development Kit will result in LED state to toggle and trigger
            the STATUS message to inform client about the state change. This is a demonstration of
            state change publication due to local event. */
            case 0:
            {
                __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "User action \n");
                hal_led_pin_set(ONOFF_SERVER_0_LED, !hal_led_pin_get(ONOFF_SERVER_0_LED));
                app_onoff_status_publish(&m_onoff_server_0);
                break;
            }
    
            /* Initiate node reset */
            case 3:
            {
                /* Clear all the states to reset the node. */
                if (mesh_stack_is_device_provisioned())
                {
                    (void) proxy_stop();
                    mesh_stack_config_clear();
                    node_reset();
                }
                else
                {
                    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "The device is unprovisioned. Resetting has no effect.\n");
                }
                break;
            }
    
            default:
                break;
        }
    }
    
    static void app_rtt_input_handler(int key)
    {
        if (key >= '0' && key <= '4')
        {
            uint32_t button_number = key - '0';
            button_event_handler(button_number);
        }
    }
    
    static void on_conn_params_evt(ble_conn_params_evt_t * p_evt)
    {
        uint32_t err_code;
    
        if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED)
        {
            err_code = sd_ble_gap_disconnect(p_evt->conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
            APP_ERROR_CHECK(err_code);
        }
        else if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_SUCCEEDED)
        {
            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Successfully updated connection parameters\n");
        }
    }
    
    static void conn_params_error_handler(uint32_t nrf_error)
    {
        APP_ERROR_HANDLER(nrf_error);
    }
    
    static void provisioning_complete_cb(void)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Successfully provisioned\n");
    
        /* Restores the application parameters after switching from the Provisioning service to the Proxy  */
        gap_params_init();
        conn_params_init();
    
        dsm_local_unicast_address_t node_address;
        dsm_local_unicast_addresses_get(&node_address);
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Node Address: 0x%04x \n", node_address.address_start);
    
        hal_led_mask_set(LEDS_MASK, false);
        hal_led_blink_ms(LEDS_MASK, LED_BLINK_INTERVAL_MS, LED_BLINK_CNT_PROV);
    }
    
    static void models_init_cb(void)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Initializing and adding models\n");
        app_model_init();
    }
    
    static void mesh_init(void)
    {
        uint8_t dev_uuid[NRF_MESH_UUID_SIZE];
        uint8_t node_uuid_prefix[NODE_UUID_PREFIX_LEN] = SERVER_NODE_UUID_PREFIX;
    
        ERROR_CHECK(mesh_app_uuid_gen(dev_uuid, node_uuid_prefix, NODE_UUID_PREFIX_LEN));
        mesh_stack_init_params_t init_params =
        {
            .core.irq_priority       = NRF_MESH_IRQ_PRIORITY_LOWEST,
            .core.lfclksrc           = DEV_BOARD_LF_CLK_CFG,
            .core.p_uuid             = dev_uuid,
            .models.models_init_cb   = models_init_cb,
            .models.config_server_cb = config_server_evt_cb
        };
        ERROR_CHECK(mesh_stack_init(&init_params, &m_device_provisioned));
    }
    
    static void gap_params_init(void)
    {
        uint32_t                err_code;
        ble_gap_conn_sec_mode_t sec_mode;
    
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
    
        err_code = sd_ble_gap_device_name_set(&sec_mode,
                                              (const uint8_t *) DEVICE_NAME,
                                              strlen(DEVICE_NAME));
        APP_ERROR_CHECK(err_code);
    }
    
    static void conn_params_init(void)
    {
        uint32_t               err_code;
        ble_conn_params_init_t cp_init;
        ble_gap_conn_params_t  gap_conn_params;
    
        memset(&gap_conn_params, 0, sizeof(gap_conn_params));
        gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
        gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
        gap_conn_params.slave_latency     = SLAVE_LATENCY;
        gap_conn_params.conn_sup_timeout  = CONN_SUP_TIMEOUT;
    
        err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
        APP_ERROR_CHECK(err_code);
    
        memset(&cp_init, 0, sizeof(cp_init));
        cp_init.p_conn_params                  = &gap_conn_params;
        cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
        cp_init.next_conn_params_update_delay  = NEXT_CONN_PARAMS_UPDATE_DELAY;
        cp_init.max_conn_params_update_count   = MAX_CONN_PARAMS_UPDATE_COUNT;
        cp_init.start_on_notify_cccd_handle    = BLE_GATT_HANDLE_INVALID;
        cp_init.disconnect_on_fail             = false;
        cp_init.evt_handler                    = on_conn_params_evt;
        cp_init.error_handler                  = conn_params_error_handler;
    
        err_code = ble_conn_params_init(&cp_init);
        APP_ERROR_CHECK(err_code);
    }
    
    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 Light Switch Proxy Server Demo -----\n");
    
        ERROR_CHECK(app_timer_init());
        hal_leds_init();
    
    #if BUTTON_BOARD
        ERROR_CHECK(hal_buttons_init(button_event_handler));
    #endif
        uint32_t err_code = nrf_sdh_enable_request();
        APP_ERROR_CHECK(err_code);
    #if defined S140 // todo remove that after S140 priority fixing
        softdevice_irq_priority_checker();
    #endif
    
        uint32_t ram_start = 0;
        /* Set the default configuration (as defined through sdk_config.h). */
        err_code = nrf_sdh_ble_default_cfg_set(MESH_SOFTDEVICE_CONN_CFG_TAG, &ram_start);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_sdh_ble_enable(&ram_start);
        APP_ERROR_CHECK(err_code);
    
        gap_params_init();
        conn_params_init();
    
        mesh_init();
    }
    
    static void start(void)
    {
        rtt_input_enable(app_rtt_input_handler, RTT_INPUT_POLL_PERIOD_MS);
        ERROR_CHECK(mesh_stack_start());
    
        if (!m_device_provisioned)
        {
            static const uint8_t static_auth_data[NRF_MESH_KEY_SIZE] = STATIC_AUTH_DATA;
            mesh_provisionee_start_params_t prov_start_params =
            {
                .p_static_data    = static_auth_data,
                .prov_complete_cb = provisioning_complete_cb,
                .p_device_uri = NULL
            };
            ERROR_CHECK(mesh_provisionee_prov_start(&prov_start_params));
        }
    
        const uint8_t *p_uuid = nrf_mesh_configure_device_uuid_get();
        __LOG_XB(LOG_SRC_APP, LOG_LEVEL_INFO, "Device UUID ", p_uuid, NRF_MESH_UUID_SIZE);
    }
    
    int main(void)
    {
        initialize();
        execution_start(start);
         config_TIMER ();
         TIMER_REINICIO2 = 1;
         NRF_TIMER1->TASKS_START = 1;
        for (;;)
        {
            (void)sd_app_evt_wait();
        }
    }
    

    i hope you can help me.

    thanks

  • i set the Timer to 3 seconds for speed up the process.

  • Hello, i want to know if you are working on this, or do you have some actualization ?

    Thanks.

  • Hello, Yes. I am looking into this. I still haven't found the reason for why it is stuck in the while loop. I will let you know as soon as I know.

    BR,

    Edvin

  • Hello,

    I have been talking to our Mesh Group, and this was an issue that they were aware of, and that they have actually fixed. Unfortunately, it is not a simple one liner, and the fix is spread out on several files. 

    I have tested the current dev branch of the Mesh SDK, and your application (main.c file) works as intended in that version. Unfortunately, I can't distribute this version now, but it will be included in the next release. 

    The issue is related to that the flash manager is waiting for a flash operation to be preformed, before the module that is going to perform this operation is initialized. 

    The issue should occur after about 500 resets with the currently available SDK for Mesh (2.2.0). Is this something you can work with until the official release is available? I can't give any guarantees for when that will happen, but it shouldn't be too long. Is this bug making it impossible for you to continue the development?

    Best regards,

    Edvin

Related