Events#
The Zigbee Application Framework and its associated cluster code use the Zigbee Stack event mechanism to schedule events on both the SoC and the host. Use of the Zigbee event mechanism saves code and RAM and works better with sleepy devices.
At a high level, the event mechanism provides a central location where all periodic actions taken by the device can be activated and deactivated based on either some user input, an OTA command, or device initialization. The event mechanism is superior to the constant tick mechanism it replaces because it allows the Zigbee Application Framework to know precisely when the next action is going to occur on the device. This is extremely important for sleepy devices that need to know exactly when they must wake up to take some action or more importantly that they cannot go to sleep because some event is in progress. The application can create and use its own events.
Creating Application Events#
The Zigbee Application Framework uses the Zigbee standard event mechanism to control and run application events within the Zigbee Application Framework. The stack’s event mechanism is documented in the zigbee_app_framework_event.h header file located at app/framework/common.
An application can create a new event by simply declaring a new variable of sl_zigbee_event_t type. Such variable should be initialized before being used by invoking the sl_zigbee_event_init()
API. Once the event is initialized, the following APIs can be invoked:
void sl_zigbee_af_event_set_active(sl_zigbee_af_event_t *event)
void sl_zigbee_af_event_set_inactive(sl_zigbee_af_event_t *event)
bool sl_zigbee_af_event_is_scheduled(sl_zigbee_af_event_t *event)
uint32_t sl_zigbee_af_event_get_remaining_ms(sl_zigbee_af_event_t *event)
void sl_zigbee_af_event_set_delay_ms(sl_zigbee_af_event_t *event, uint32_t delay)
void sl_zigbee_af_event_set_delay_qs(sl_zigbee_af_event_t *event, uint32_t delay)
void sl_zigbee_af_event_set_delay_minutes(sl_zigbee_af_event_t *event, uint32_t delay)
One Caveat is if you have an event scheduled in an ISR a different set of APIs are required:
void sl_zigbee_af_isr_event_init(sl_zigbee_af_event_t *event, void (*handler)(sl_zigbee_af_event_t *));
Event Struct and Event Handler#
An application event consists of two parts:
The event handler, called when the event fires.
The sl_zigbee_af_event_t struct which is used to schedule the event. Scheduled events end up in the Zigbee Application Framework event queue which the Zigbee Application Framework uses to keep track of when the next event will occur for the purposes of sleeping.
Application Event Example#
The Z3Light sample application uses a custom event to manage its state. The event consists of two parts:
The sl_zigbee_af_event_t struct called commissioning_led_event.
The event handler which is called each time the event fires. The event handler is called the commissioning_led_event_handler. The event handler and event struct are included in the app.c file shipped with the sample application.
How Cluster Events Are Created#
Every cluster includes a server and a client “tick” callback. The Zigbee Cluster Configurator generates a declaration of a sl_zigbee_af_event_t struct for each cluster server or client on each endpoint. The actual declarations are generated in the zap_event.h header which is included and used in the Zigbee Application Framework’s event code in app/framework/util/af-event.c.
Initialization of endpoint-specific events must be accomplished using the dedicated API sl_zigbee_af_endpoint_event_init()
.
How Cluster Events Are Scheduled#
The component or application code can manage cluster-related events in the event table by using the Zigbee Application Framework’s event management API. This API consists of two functions: sl_zigbee_zcl_schedule_cluster_tick
and sl_zigbee_zcl_deactivate_cluster_tick
.
A tick is the basic unit of time used in the event system. The duration of a tick depends on the platform that is being used. Using the current Zigbee platform, one tick is approximately equal to:
where MILLISECOND_TICKS_PER_SECOND is the number of clock ticks per second. Therefore, when sl_zigbee_zcl_schedule_cluster_tick
is called with a value of t for the delayMs
argument, the event will be run in no less than
Of course, the empirical error in this value depends on the reliability of the clock source.
sl_zigbee_zcl_schedule_cluster_tick#
sl_zigbee_zcl_schedule_cluster_tick
uses the endpoint, cluster id, and client/server identity to find the associated event in the sl_zigbee_af_event_context_t event context table. This table is generated by the Zigbee Cluster Configurator into zap-event.h. If it cannot find the event table entry, sl_zigbee_zcl_schedule_cluster_tick
returns the EmberStatus SL_ZIGBEE_BAD_ARGUMENT to the caller. If it finds the event table entry, then it schedules the event to take place in the number of milliseconds requested by the caller and it returns SL_ZIGBEE_SUCCESS.
EmberStatus sl_zigbee_zcl_schedule_cluster_tick (int8u endpoint,
sl_zigbee_af_cluster_id_t clusterId,
boolean isClient,
uint32_t delayMs,
sl_zigbee_af_event_sleep_control_t sleepControl);
The sl_zigbee_af_event_sleep_control_t
argument allows the caller to indicate what the device may do while the event is active in the event table. This value is only relevant for sleepy devices; it has no effect for devices that do not go to sleep. The possible values for sl_zigbee_af_event_sleep_control_t
are enumerated in app/framework/include/af-types.h, as follows:
SL_ZIGBEE_AF_OK_TO_HIBERNATE
means that the application may go into prolonged deep sleep until the event needs to be called. Use this sleep control value if the scheduling code does not care what the device does up to the point when the event is called.SL_ZIGBEE_AF_OK_TO_NAP
means that the device should sleep for the nap period and should wake up to poll between naps until the event is called. Use this sleep control value if the scheduling code wants the device to poll periodically until the event is called. This is particularly useful if the scheduled event is a timeout waiting for some reply from another device on the network. If the event is a timeout, you do not want the device to go into hibernation until the timeout is called because it will never hear the message it is waiting for, thereby guaranteeing that the timeout will be called.SL_ZIGBEE_AF_STAY_AWAK
E means that the device should not sleep at all but should stay awake until the event is called. Use this event if you are scheduling a very frequent event and do not want the device to nap for a very short period of time because the device will poll each time it wakes up. If the device is held out of sleep entirely, it will poll once per second.
sl_zigbee_zcl_deactivate_cluster_tick#
The deactivation function is used to turn off an event. This function should be called when the scheduled event is called to ensure that the event code does not continue to call the event. It may also be called before the event is called if the event is no longer necessary.
Note: In the Zigbee Application Framework
sl_zigbee_zcl_deactivate_cluster_tick
is automatically called before the event fires to ensure that the event will not continue to be called on every tick.
deactivate_cluster_tick
is like schedule_cluster_tick
in that it takes most of the same arguments, but it also has to locate the correct event in the event context table before shutting it off.
EmberStatus sl_zigbee_zcl_deactivate_cluster_tick (int8u endpoint,
sl_zigbee_af_cluster_id_t clusterId,
boolean isClient);