Table of Contents
The Zigbee Multi Sensor with FreeRTOS example demonstrates how to use Zigbee stack with FreeRTOS and create a multi-threaded application. It is based on single-threaded Zigbee Multi Sensor Example that incorporates the ZCL Temperature Measurement Cluster and ZCL Pressure Measurement Cluster, among others.
The application includes several FreeRTOS-specific tasks.
Setup
You can find the source code in the following folder: <InstallFolder>\examples\zigbee\experimental\multi_sensor_freertos
LED assignments
The example uses LED assignments as described in Thread BSP LED and button reference for the following LEDs:
- LED3 – Used to indicate the Zigbee network connection state.
The following LEDs reserved for user application purposes are assigned in this example:
- LED1 (as an exception from the default LED1 assignment):
- Blinking (no difference in pattern):
- FreeRTOS scheduler is running.
- FreeRTOS scheduler is switching tasks.
- Blinking (no difference in pattern):
Testing
To test the FreeRTOS example, complete the steps described in the Testing section in Zigbee Multi Sensor Example.
The only difference is the LED1 blinking when the FreeRTOS scheduler is running, and when the scheduler is switching tasks. There is no difference in blinking pattern between these two cases.
FreeRTOS-specific tasks
The following tasks are running within the target application and are specific to the Zigbee Multi Sensor with FreeRTOS example. They are started automatically with the application.
- zigbee_main_task
- Responsible for processing the stack events. The task calls zboss_main_loop_iteration in its main loop. Within its context, zboss_signal_handler gets called, from which you can make a thread-safe call to the stack API. Calling the stack API from outside the handler is not thread-safe and requires a mutex guard.
- Note
- In the nRF5 SDK for Thread and Zigbee v4.2.0, there is no way to perform deep sleep in a safe way (ZB_COMMON_SIGNAL_CAN_SLEEP signal handler has an empty implementation, unlike in Zigbee Multi Sensor Example).
- led_toggle_task
- Responsible for the blinking LED1. Although this task could be handled by the built-in timer task, having a LED toggle task is meant to show that some non-Zigbee related tasks can be executed in parallel to Zigbee functionality.
- logger_task
- Responsible for deferred log processing. This task is used when NRF_LOG_ENABLED and NRF_LOG_DEFERRED are both set to
1insdk_config.h. In this case, the logs generated by NRF_LOG_INFO, NRF_LOG_ERROR, and other events are processed by this task and written to the log backend (UART in the default configuration).
- Note
- In the nRF5 SDK for Thread and Zigbee v4.2.0, the deferred log processing with FreeRTOS must be executed within a task of lower priority than any task that produces logs (calling NRF_LOG_INFO or other events).
- FreeRTOS built-in timer task
- When using FreeRTOS, the app_timer module from the nRF5 SDK wraps the FreeRTOS software timers. As a consequence, the callback
temperature_measurement_timer_handlergets called from this task. As the API is not thread-safe, the update of the ZCL Temperature Measurement Cluster attribute (zb_zcl_set_attr_val) must happen either guarded by mutex or fromzigbee_main_task. Because using blocking functions from the FreeRTOS API in the FreeRTOS timer handler is not allowed, a scheduling callback tozigbee_main_task(using ZB_SCHEDULE_APP_CALLBACK) is used instead. The callback updates the cluster attribute from thezigbee_main_taskcontext, so no locking is required.
- pressure_measurement_task
- Responsible for updating the ZCL Pressure Measurement Cluster attribute. The update of cluster attribute (call to zb_zcl_set_attr_val) is guarded by mutex.
- FreeRTOS built-in idle task
vApplicationIdleHookresponsible for lowering the power usage is called from this task. It has the lowest priority.
- Note
- In the nRF5 SDK for Thread and Zigbee v4.2.0, it is not safe to call zb_sleep_now from
vApplicationIdleHook.