Using Events and Timers with the Silicon Labs Matter Extension#
Event Handler#
The Matter event handler uses the FreeRTOS queue to transport a message from the producer to the consumer area. Events can be used to create asynchronous message processing or inter-task communication.
For information about customizing app behavior, see Extending Base App Implementation.
Steps to make an event work:
Make sure the queue is initialized
Create an AppEventType for your application
Populate the Type and Handler variables
Post the message to the queue
Event definition enum#
AppEvent contains event types and event structures that are used for specific applications, if needed. Handler is used to store the callback for the event.
struct AppEvent
{
enum AppEventTypes
{
kEventType_Button = 0,
kEventType_Timer,
kEventType_Light,
kEventType_Install,
kEventType_Observer,
};
uint16_t Type;
union
{
struct
{
uint8_t Action;
} ButtonEvent;
struct
{
void * Context;
} TimerEvent;
struct
{
uint8_t Action;
int32_t Actor;
} LightEvent;
};
EventHandler Handler;
};Queue Posting#
When creating an event and pushing it to the event queue at minimum, Handler and Type must be defined in order for the event to work.
Custom event posting and handlers are overridden in the CustomerAppTask file, not in autogen/AppTask.cpp.
void CreateObserverEvent(void)
{
AppEvent active_mode_event = {};
active_mode_event.Type = AppEvent::kEventType_Observer;
active_mode_event.Handler = SilabsSensors::SendSensorsValues;
AppInstance().PostEvent(&active_mode_event);
}Callback#
Observer event callback
void SilabsSensors::SendSensorsValues(AppEvent * aEvent)
{
// Do something
}Dispatcher#
AppTaskMain is dispatching all the events from the event list.
void AppTask::AppTaskMain(void * pvParameter)
{
AppEvent event;
QueueHandle_t sAppEventQueue = *(static_cast<QueueHandle_t *>(pvParameter));
CHIP_ERROR err = AppInstance().Init();
if (err != CHIP_NO_ERROR)
{
SILABS_LOG("AppTask.Init() failed");
appError(err);
}
#if !(defined(CHIP_CONFIG_ENABLE_ICD_SERVER) && CHIP_CONFIG_ENABLE_ICD_SERVER)
AppInstance().StartStatusLEDTimer();
#endif
AppInstance().RegisterObserver();
SILABS_LOG("App Task started");
while (true)
{
BaseType_t eventReceived = xQueueReceive(sAppEventQueue, &event, portMAX_DELAY);
while (eventReceived == pdTRUE)
{
AppInstance().DispatchEvent(&event);
eventReceived = xQueueReceive(sAppEventQueue, &event, 0);
}
}
}Matter Timer#
Start#
Initialize a one-shot timer to expire in 10 seconds and invoke TestCallback upon expiration.
System::Clock::Timeout Timeout = System::Clock::Seconds32(10);
chip::DeviceLayer::PlatformMgr().LockChipStack();
err = DeviceLayer::SystemLayer().StartTimer(Timeout, TestCallback, this);
chip::DeviceLayer::PlatformMgr().UnlockChipStack();Callback#
Timer callback. Implement in src/CustomerAppTask.cpp.
void TestCallback(System::Layer * layer, void * aAppState)
{
// Do something
}If you need a periodic timer, you can recall StartTimer() in the callback.