Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Bluetooth 5 BLE mesh: assert 0x0002DC36

Hi all,s

I have a couple of nrf52840 boards and i was testing the ble mesh light application. The application works fine, but i changed it so it will periodically set the LED on the server side. After a few transmissions (usually around 100 or 200 packets). Then i get the following assert in the light client application: (app_error_weak.c, 95, mesh assert at 0x0002DC36). I did a stack trace wich showed me that it is going wrong in the core_tx.c in line 105: 

NRF_MESH_ASSERT(m_packet.bearer_bitmap == 0)

it should be zero but it is obviously not. zero.., i have no clue why it is happening. It happens when i use a reliable transfer and an unreliable transfer.

Has anybody an idea about what is going wrong?

Thanks fot the help!

Parents
  • hello,

    Can I suggest that you provide the code snippet that you changed (or upload the server main.c file) and/or the logs, then we may be able to help you diagnose a bit further.

    Regards,

  • Hi, 

    Here is a code snippet from the client software that i have added.

    typedef struct test_settings //test parameters
    {
        int i;
        long n_time;            //transmissionperiod (example 500ms)
        int n_messages;         //total number of transmissions to be done
        //more parameters will be added later
    } test_settings;
    
    test_settings test_setup;
    
    typedef struct test_results //test results
    {
        int i_n_transmitted;    //counter (transmissions)
        //more parameters will be added later
    } test_results;
    
    test_results test_result;
    
    static uint8_t test_start_process = false; //toggle by a button press (button 1)
    
    
    /*
     * this function is repeatedly called by the main process (while())
     * everytime it checks wheter or not the wright amount of time (parameter eg 500ms) has passed 
     * if enough time passed => it will try to send simple_on_off_client_set => if succesfull, then the counter will be increased
     */
    
    int test_process()
    {
        test_parameter_setup();
    
         if(test_start_process == true) // global variable to start or stop a test (can also be stopped by an extern source)
         {
             if(current_time + test_setup.n_time <= timer_now())       //check if enough time has passed (example 500ms)
             {
                if(MAX_TRANSMISSIONS <  test_setup.n_messages)
                {
                    test_setup.n_messages = MAX_TRANSMISSIONS;
                }
    
    
                //__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "timer %d\n", timer_now());            
       
                if(simple_on_off_client_set(m_clients, !hal_led_pin_get(13 + 1)) == NRF_SUCCESS)
                {
                    latencyTable[test_result.i_n_transmitted] = timer_now();
                   // SEGGER_RTT_printf(0, "transmitted = %d\n", test_result.i_n_transmitted);
                    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "transmitted = %d\n", test_result.i_n_transmitted);
                    test_result.i_n_transmitted++;
                }
                else
                {
                    for(int j = 0; j < 500000; j++);
                }
                if(test_result.i_n_transmitted >= test_setup.n_messages)
                {
                    for(int j = 0; j < 200000; j++); // add some delay
    
                    test_start_process = false;      //after reaching the predetermined number of transmissions => stop the test
                    SEGGER_RTT_printf(0, "transmitted = %d\n", test_result.i_n_transmitted);
    
                    test_result.i_n_transmitted = 0; //reset transmission counter
                }
                current_time = timer_now();          //start timing
              }
              else
              {
                //do nothing
              }
         }
         else
         {
            //do nothing
         }
        return test_start_process;
    }

    Without the simple_on_off_client_set() function it is working, if i setup a time like for example 500ms it will approximately print every 1s that the timer has been increased. When i execute this code with the simple_on_off_client_set() function it will work for i couple of times, but when i give as parameter 500 messages it will hang somewhere. with the error code which i already mentioned before.

    The server part just contains a counter, everytime it receives a message it increments the counter. When i press a button there it prints the number.

    Regards

  • Also, Bjorn,

    Is there a possible work around for this issue in the meantime?

  • I do not believe there is a fix for this issue at the moment. I believe this issue is not present in the mesh sdk v1.0.1, so you could revert back to this sdk if you want. I will update this thread with the patch when it is found.

  • I won't be able to revert to this sdk as I need the mesh network to be bluetooth mesh compliant. How do you know this issue isn't present in the mesh sdk v1.0.1? I am trying to tug at every thread in order to find a fix or workaround for it as it has become a huge problem with one of our products.

  • Sorry for the delayed response. This is most likely an IRQ priority settings issue which can be read about more here.

    When you run mesh_init() in mesh sdk v2.01, the IRQ priority is set to NRF_MESH_IRQ_PRIORITY_LOWEST, which is defined at level 7. However, when a Mesh API function is called in the main loop, the IRQ priority is set to NRF_MESH_IRQ_PRIORITY_THREAD, which is defined at level 15. Level 15 is a less critical interrupt priority level than level 7. This can lead to some mesh events interrupting other mesh events. Since we want the mesh stack to run at the same priority, we need to make sure that IRQ priority is decreased from level 7 to level 15 when running the mesh API in the main loop. This can be done by changing this line in the mesh_init function from:

    .core.irq_priority = NRF_MESH_IRQ_PRIORITY_LOWEST,

    to:

     

    .core.irq_priority = NRF_MESH_IRQ_PRIORITY_THREAD 

    & updating the main loop to include: 

    while (true)
    {
        app_sched_execute();
        bool done = nrf_mesh_process();
        if (done)
        {
            sd_app_evt_wait();
        }
    }

Reply
  • Sorry for the delayed response. This is most likely an IRQ priority settings issue which can be read about more here.

    When you run mesh_init() in mesh sdk v2.01, the IRQ priority is set to NRF_MESH_IRQ_PRIORITY_LOWEST, which is defined at level 7. However, when a Mesh API function is called in the main loop, the IRQ priority is set to NRF_MESH_IRQ_PRIORITY_THREAD, which is defined at level 15. Level 15 is a less critical interrupt priority level than level 7. This can lead to some mesh events interrupting other mesh events. Since we want the mesh stack to run at the same priority, we need to make sure that IRQ priority is decreased from level 7 to level 15 when running the mesh API in the main loop. This can be done by changing this line in the mesh_init function from:

    .core.irq_priority = NRF_MESH_IRQ_PRIORITY_LOWEST,

    to:

     

    .core.irq_priority = NRF_MESH_IRQ_PRIORITY_THREAD 

    & updating the main loop to include: 

    while (true)
    {
        app_sched_execute();
        bool done = nrf_mesh_process();
        if (done)
        {
            sd_app_evt_wait();
        }
    }

Children
Related