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

  • It might be a bug that leads to this error. Another customer reported a similar issue as you have seen. It might be that the stack is trying to send a segmented message , which is why m_packet.bearer_bitmap is non-zero. It could be that the node gets interrupted by a mesh packet & tries to relay this packet. During the relaying, the node will check whether m_packet.bearer_bitmap is zero, which then leads to the assert. Have you tried with mesh sdk v1.0.1 to see if you get the same assert?

  • I haven't yet tried v1.0.1. As soon as i have time to do this, i will try it. What would be the problem if you are trying to segment a message?

  • Do messages still get segmented if this is set: "reliable.message.force_segmented = false;". Would it be worthwhile to see if reducing the packet size from 20 bytes to something like 15 bytes help? I read somewhere on the forum that the maximum size before segmentation happens is 15 bytes, is that correct?

  • I believe the mesh specification says 11bytes payload (including opcode). i would think that force_segmented is to literally force segmentation to be on (it would be weird that you can turn this off). and if you try to transmit a frame which is to large, wouldn't it generate an error (if you could disable segmentation)? Or it should go wrong immediately, because you are (partially) missing data....

    I can be wrong of course.

  • I changed my packet size to 11 bytes, so each node (out of 6 total) is pushing data around the mesh every 3 secs. The problem still persists.

Reply Children
  • 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();
        }
    }

  • Hi Bjorn,

    Thanks for the reply. Do I do this for the provisioner, client and server? or just the server?

  • I tried to reproduce this error by adding a call to:

    simple_on_off_client_set(&m_clients[0],!hal_led_pin_get(BSP_LED_0));

    in the main loop of the light switch client in mesh sdk v2.0.1, but was not able to reproduce the assert error.

    I double checked with another engineer & you need to only change the priority for the devices that are running a mesh api function call in the main loop.

    I also sent you a PM.

  • Hi Bjorn, this fix ended up working for me. It turns out that I only needed it on the server node(s). What was interfering was the application timers (since my server nodes are the only ones that use the app scheduler). Thanks for the help, every thing works as expected now Slight smile

Related