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

Beaconing while running the Mesh stack

I successfully tried the "beaconing" example from your Mesh SDK 310.

I noticed that moving

  line 215 "adv_start();" in main.c

right after "ERROR_CHECK(mesh_stack_start());  (line 219 of main.c)

Causes the project not working with an error like:

<t: 0>, main.c, 190, ----- Bluetooth Mesh Beacon Example -----
<t: 9139>, main.c, 196, Initialization complete!
<t: 14006>, mesh_app_utils.c, 65, Device UUID (raw): 930A787CC75A3640B74BD4E3B9525BE7
<t: 14009>, mesh_app_utils.c, 70, Device UUID : 7C780A93-5AC7-4036-B74B-D4E3B9525BE7
<t: 14019>, main.c, 221, Bluetooth Mesh Beacon example started!
<t: 14023>, app_error_weak.c, 108, Mesh assert at 0x0002A64A (:0)

Why??

My guess is that there are context constrains and may be race condition that got violated.

Where can I find some reference document/material to be able to start, stop and modify the beacon behavior without spoiling the Mesh stack?

My need is to be able to start/stop modify the advertiser and modify the beacon payload while the mesh stack is up running!

Maybe the mesh was started hours before, then my application needs to start two different advertisers with different configs and payloads.... can you share the code snippet/template one is supposed to use?

thanks in advance!

 Davide

Parents
  • Very sorry for the delayed response. I have tested this myself & notice a similar assert to you. Could you please use the addr2line function to see where exactly this assert is occurring & then we can take it from there?

  • Thank you for your answer Bjørn:

    this is the reference you asked for.

    $ addr2line -e beaconing_nrf52832_xxAA_s132_6.1.0.elf 0x0002A64A
    C:\Mc\Nordic\nrf5SDKforMeshv310src\mesh\core\src/timer_scheduler.c:225

    I am looking forward to understand how to correctly use the beaconing functionalities.

  • Hi Davide, 

    I'm taking over the case as Bjørn is going on a business trip. 

    I'm not sure I have the same line number in the timer_scheduler.c file as you , but most likely you have the assert at this line: 

     NRF_MESH_ASSERT_DEBUG(bearer_event_in_correct_irq_priority());

    This is due to that the mesh stack in the example by default initialized at Interrupt mode NRF_MESH_IRQ_PRIORITY_LOWEST (see mesh_init() ) 

    And if you have a look here: 

    https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.meshsdk.v3.1.0/md_doc_introduction_mesh_interrupt_priorities.html?cp=5_2_0_4

    You can find this:

    Except for calling initialization related functions before calling mesh_stack_start(), no mesh API functions shall be called from an IRQ priority other than the one specified in the configuration. Breaking this rule may cause unpredicable behavior.

    So if you want to call adv_start() in thread context, you would need to initialize the mesh stack in NRF_MESH_IRQ_PRIORITY_THREAD mode and in your main loop you need to have something like this: 

    bool done = nrf_mesh_process();
    if (done)
    {
        sd_app_evt_wait();
    }

    Otherwise if you want in IRQ mode, you need to call adv_start() in an interrupt at APP LOWEST priority. 

  • Thank you Hung.

    setting NRF_MESH_IRQ_PRIORITY_THREAD solved the problem as you correctly guessed.

    So this ticket can be closed here. Anyway can you kindly point me where to read something regarding the overall picture of the "thread context", "IRQ mode" and whole user application structure? I am still missing the whole picture on how to correctly lay down all the user code we need to complete our products.

  • Hi Davide, 

    The link to the documentation in the infocenter is what we have on this topic. 

    Basically, if you want mesh activity to be performed on interrupt context (NRF_MESH_IRQ_PRIORITY_LOWEST ) so that it can preempt application activity in main context (the main loop) you need to call all Mesh APIs in NRF_MESH_IRQ_PRIORITY_LOWEST context (in an interrupt). Note that you still can have an application interrupt that has more priority than normal mesh activity by setting it's priority lower than NRF_MESH_IRQ_PRIORITY_LOWEST . 

    If you want mesh running in main (Thread) context, so it won't mess up your application running in main, then you need to call nrf_mesh_process() in main loop, and you can call Mesh API in main context. If you call Mesh API in an interrupt, it may results unexpected behavior. 

Reply
  • Hi Davide, 

    The link to the documentation in the infocenter is what we have on this topic. 

    Basically, if you want mesh activity to be performed on interrupt context (NRF_MESH_IRQ_PRIORITY_LOWEST ) so that it can preempt application activity in main context (the main loop) you need to call all Mesh APIs in NRF_MESH_IRQ_PRIORITY_LOWEST context (in an interrupt). Note that you still can have an application interrupt that has more priority than normal mesh activity by setting it's priority lower than NRF_MESH_IRQ_PRIORITY_LOWEST . 

    If you want mesh running in main (Thread) context, so it won't mess up your application running in main, then you need to call nrf_mesh_process() in main loop, and you can call Mesh API in main context. If you call Mesh API in an interrupt, it may results unexpected behavior. 

Children
No Data
Related