The mesh stack has different interrupt priority levels defined by its architecture. It includes various interrupt priority level restrictions that are imposed on the application when using the stack to avoid race condition scenarios and ensure that all operations execute in non-overlapping manner.
Table of contents
The mesh stack runs in the following interrupt priorities:
The mesh network must know in which IRQ priority the user application is running. To know this, nrf_mesh_init_params_t (used by nrf_mesh_init) now has an irq_priority
field. Normally, it must be set to NRF_MESH_IRQ_PRIORITY_LOWEST, or NRF_MESH_IRQ_PRIORITY_THREAD if running in the main loop. You can also use the APP_IRQ_PRIORITY_* defines in the nRF5 SDK.
You must ensure that no mesh API functions are called from an IRQ priority other than the one specified in the configuration. The only exception is calling the initialization-related functions before calling mesh_stack_start(). Breaking this rule can cause unpredictable behavior.
The mesh stack uses the SoftDevice NVIC APIs for accessing NVIC. In particular, the functions sd_nvic_critical_region_enter() and sd_nvic_critical_region_exit() are used to prevent the mesh event handler from being started in some cases. The application must not use these functions in any callback functions provided by the application to the mesh stack.
Starting with the nRF5 SDK for Mesh v1.0.0, all event processing must run in the same IRQ priority.
Depending on your application, you can choose to:
Before the release of the nRF5 SDK for Mesh v1.0.0, applications made using nRF5 SDK for Mesh v0.10.0-Alpha or an older version of the Mesh SDK would normally run low priority event handling in several IRQ priorities:
When running in a low priority interrupt, the application can no longer call nrf_mesh_process(). You must change the main loop. For example:
You can use the application scheduler from the nRF5 SDK to run the application and the mesh event handling.
To add app_scheduler to the application and initialize it:
CMakeList.txt
.include
directory, add the following defines in app_config.h
: main()
, initialize app_scheduler: APP_SCHED_EVENT_SIZE
must be greater than or equal to APP_TIMER_SCHED_EVENT_DATA_SIZE
, because the app timer also needs to use the scheduler.APP_SCHED_QUEUE_SIZE
must be sufficiently large. This is required to be able to hold many events (user events, SoftDevice events, multiple events from various user or stack timers, or both) that could be generated between two successive calls to the app_sched_execute()
from the main loop. The value of 32
could be reasonable for typical use cases, when there is a minimal or no additional user code within the main loop.When running from the main loop, nrf_mesh_process() still needs to be called, but as soon as there are no more events to be processed, the CPU can be put to sleep:
If you need to use simple_hal.c
module to handle button press actions, use the scheduler to execute the button_event_handler()
function from the thread priority. To do this, use an intermediate function as a button event handler, and post the event to the secondary function using the scheduler. For example: