Skip to content

MiraMesh System Integration

Review MiraMesh hardware requirements here and here.

Bare metal system

Using MiraMesh in a bare metal environment is straight forward. Call miramesh_init (with the wakeup callbacks doing nothing), configure the memory usage (see mem_usage API), implement miramesh_lock/miramesh_unlock as two empty functions and call your application logic as well as miramesh_run_once in a loop.

For power saving, the loop and wakeup-callbacks have to cooperate so miramesh_run_once is only called when really needed (after the wakeup functions have run) and otherwise call __WFE in the loop. This can be implemented with a simple flag.

There is an example of this in the examples/miramesh folder.

An operating system with preemptive threads

An OS integrating MiraMesh must implement the functions miramesh_lock and miramesh_unlock, they are used to prevent simultanious access to MiraMesh's internal data. The lock need to support recursive calls. For FreeRTOS a RecursiveMutex is a good choice.

As with a bare metal system, miramesh_init needs to be called before any other mira function. The wakeup callbacks are used to wake up the thread/task that should call the miramesh_run_once function. For FreeRTOS a good strategy is to have a task wait with xTaskNotifyWait and the wakeup callbacks call xTaskNotify/xTaskNotifyFromISR to wake it up. When the task wakes up it calls miramesh_run_once before sleeping again.

The priority of the task running miramesh_run_once need to be such that it gets a chance to run once for every packet that the system wants to send or receive. For network rate 0, that means once every 10ms.

There is an example of using MiraMesh with FreeRTOS in the examples/miramesh folder and on GitHub.

An operating system with cooprative threading

When using an OS with cooperative threading a lock is not needed, otherwise it works more or less like an integration on a system with preemtive threads. When miramesh_run_once has run, the thread should yield control to the other threads.


Name Value Description

How many PPIs used by MiraMesh


How many PPI groups used by MiraMesh



Type Name Description
void(*)(void) api_lock The function needs to be reentrant by the same thread and the lock should not be released until miramesh_unlock has been called just as many times.
void(*)(void) api_unlock The function needs to be reentrant by the same thread and the lock should not be released until miramesh_unlock has been called just as many times as miramesh_lock has been called.
void(*)(void) wakeup_from_app_callback This callback is called from app/task context.
void(*)(void) wakeup_from_irq_callback This callback is called from IRQ context.



Type Name Description
uint8_t[MIRAMESH_SYS_NUM_PPIS_USED] ppi_idx The PPIs to use
uint8_t[MIRAMESH_SYS_NUM_PPI_GROUPS_USED] ppi_group_idx The PPI groups to use
uint8_t rtc The RTC to use, 2 for RTC2
uint8_t rtc_irq_prio The prio of the RTC IRQ to use
uint8_t swi The SWI/EGU to use, 0 for SWI0
uint8_t swi_irq_prio The SWI prio. Should be of higher priority than rtc_irq_prio



Type Name Description
const uint8_t * start pointer to the certificate/license pool
const uint8_t * end pointer to the end of the certificate/license pool



Type Name Description
miramesh_callback_cfg_t callback Needed callbacks for OS integration
miramesh_hardware_cfg_t hardware Describes needed hardware resources
miramesh_certificate_cfg_t certificate Describes the certificate location



mira_status_t miramesh_init(
    const miramesh_config_t*           config,
    const mira_net_frontend_config_t*  frontend_cfg);

Init the MiraMesh system.

This function must be called before any other MiraMesh functions are called.


Parameter Description
config The system configuration
frontend_cfg Frontend configuration, NULL means no frontend config




void miramesh_handle_sd_event(
    uint32_t      evt_id);

Routes events from Softdevice to MiraMesh.

This function is used by nRF52 targets with Softdevice to process recieved events.

Normally used like this:

#include "miramesh.h"
#include "miramesh_sys.h"
#include "nrf_sdh_soc.h"

static void sd_evt_observer(uint32_t evt_id, void *ctx) {

NRF_SDH_SOC_OBSERVER(m_sd_evt_miramesh, 0, sd_evt_observer, 0);


void miramesh_rtc_irq_handler(

The IRQ Handler for the RTC events.

This function should be called from the RTCx_IRQHandler


void miramesh_swi_irq_handler(

The IRQ Handler for the SWI events.

This function should be called from the SWIx_EGUx_IRQHandler


void miramesh_run_once(

Run the system once.

This function should be called repeatedly. After running once the thread should sleep until miramesh_wakeup_from_IRQ or miramesh_wakeup_from_API have been called.


while(1) {
    if(xTaskNotifyWait(0, 1, NULL, portMAX_DELAY) == pdPASS) {