Edit

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.