Skip to content

Commit

Permalink
[nrfconnect] Optimized application main loop wake up interval (#10644)
Browse files Browse the repository at this point in the history
Application wakes up MCU every 10 ms to update LEDs state and handle
events even if it's not necessary.

* Moved updating BLE connection and Thread state from main loop
to Matter event handler
* Moved updating LED state from main loop to event handler
* Refactored LEDWidget module to use timer and change LEDs state
on timer expiration.
* By the way spotted and removed unused
lighting-app/nrfconnect/child_image/mcuboot.conf file
  • Loading branch information
kkasperczyk-no authored Oct 20, 2021
1 parent 563e0e3 commit b06b55c
Show file tree
Hide file tree
Showing 15 changed files with 397 additions and 331 deletions.
30 changes: 0 additions & 30 deletions examples/lighting-app/nrfconnect/child_image/mcuboot.conf

This file was deleted.

139 changes: 72 additions & 67 deletions examples/lighting-app/nrfconnect/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,14 @@ int AppTask::Init()
{
// Initialize LEDs
LEDWidget::InitGpio();
LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler);

sStatusLED.Init(SYSTEM_STATE_LED);
sUnusedLED.Init(DK_LED3);
sUnusedLED_1.Init(DK_LED4);

UpdateStatusLED();

// Initialize buttons
int ret = dk_buttons_init(ButtonEventHandler);
if (ret)
Expand Down Expand Up @@ -133,59 +136,8 @@ int AppTask::StartApp()

while (true)
{
ret = k_msgq_get(&sAppEventQueue, &event, K_MSEC(10));

while (!ret)
{
DispatchEvent(&event);
ret = k_msgq_get(&sAppEventQueue, &event, K_NO_WAIT);
}

// Collect connectivity and configuration state from the CHIP stack. Because the
// CHIP event loop is being run in a separate task, the stack must be locked
// while these values are queried. However we use a non-blocking lock request
// (TryLockChipStack()) to avoid blocking other UI activities when the CHIP
// task is busy (e.g. with a long crypto operation).

if (PlatformMgr().TryLockChipStack())
{
sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned();
sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled();
sHaveBLEConnections = (ConnectivityMgr().NumBLEConnections() != 0);
PlatformMgr().UnlockChipStack();
}

// Update the status LED if factory reset has not been initiated.
//
// If system has "full connectivity", keep the LED On constantly.
//
// If thread and service provisioned, but not attached to the thread network yet OR no
// connectivity to the service OR subscriptions are not fully established
// THEN blink the LED Off for a short period of time.
//
// If the system has ble connection(s) uptill the stage above, THEN blink the LEDs at an even
// rate of 100ms.
//
// Otherwise, blink the LED ON for a very short time.
if (sAppTask.mFunction != kFunction_FactoryReset)
{
if (sIsThreadProvisioned && sIsThreadEnabled)
{
sStatusLED.Blink(950, 50);
}
else if (sHaveBLEConnections)
{
sStatusLED.Blink(100, 100);
}
else
{
sStatusLED.Blink(50, 950);
}
}

sStatusLED.Animate();
sUnusedLED.Animate();
sUnusedLED_1.Animate();
k_msgq_get(&sAppEventQueue, &event, K_FOREVER);
DispatchEvent(&event);
}
}

Expand Down Expand Up @@ -334,6 +286,7 @@ void AppTask::FunctionHandler(AppEvent * aEvent)
{
sUnusedLED.Set(false);
sUnusedLED_1.Set(false);
UpdateStatusLED();
sAppTask.CancelTimer();
sAppTask.mFunction = kFunction_NoneSelected;
LOG_INF("Factory Reset has been Canceled");
Expand Down Expand Up @@ -386,29 +339,81 @@ void AppTask::StartBLEAdvertisementHandler(AppEvent * aEvent)
}
}

#ifdef CONFIG_CHIP_NFC_COMMISSIONING
void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */)
void AppTask::UpdateLedStateEventHandler(AppEvent * aEvent)
{
if (event->Type != DeviceEventType::kCHIPoBLEAdvertisingChange)
return;
if (aEvent->Type == AppEvent::kEventType_UpdateLedState)
{
aEvent->UpdateLedStateEvent.LedWidget->UpdateState();
}
}

void AppTask::LEDStateUpdateHandler(LEDWidget & ledWidget)
{
AppEvent event;
event.Type = AppEvent::kEventType_UpdateLedState;
event.Handler = UpdateLedStateEventHandler;
event.UpdateLedStateEvent.LedWidget = &ledWidget;
sAppTask.PostEvent(&event);
}

void AppTask::UpdateStatusLED()
{
/* Update the status LED.
*
* If thread and service provisioned, keep the LED On constantly.
*
* If the system has ble connection(s) uptill the stage above, THEN blink the LED at an even
* rate of 100ms.
*
* Otherwise, blink the LED On for a very short time. */
if (sIsThreadProvisioned && sIsThreadEnabled)
{
sStatusLED.Set(true);
}
else if (sHaveBLEConnections)
{
sStatusLED.Blink(100, 100);
}
else
{
sStatusLED.Blink(50, 950);
}
}

if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Started)
void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */)
{
switch (event->Type)
{
if (NFCMgr().IsTagEmulationStarted())
case DeviceEventType::kCHIPoBLEAdvertisingChange:
#ifdef CONFIG_CHIP_NFC_COMMISSIONING
if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Started)
{
LOG_INF("NFC Tag emulation is already started");
if (NFCMgr().IsTagEmulationStarted())
{
LOG_INF("NFC Tag emulation is already started");
}
else
{
ShareQRCodeOverNFC(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE));
}
}
else
else if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Stopped)
{
ShareQRCodeOverNFC(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE));
NFCMgr().StopTagEmulation();
}
}
else if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Stopped)
{
NFCMgr().StopTagEmulation();
#endif
sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0;
UpdateStatusLED();
break;
case DeviceEventType::kThreadStateChange:
sIsThreadProvisioned = ConnectivityMgr().IsThreadProvisioned();
sIsThreadEnabled = ConnectivityMgr().IsThreadEnabled();
UpdateStatusLED();
break;
default:
break;
}
}
#endif

void AppTask::CancelTimer()
{
Expand Down
7 changes: 7 additions & 0 deletions examples/lighting-app/nrfconnect/main/include/AppEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

#include <cstdint>

#include "LEDWidget.h"

struct AppEvent;
typedef void (*EventHandler)(AppEvent *);

Expand All @@ -31,6 +33,7 @@ struct AppEvent
kEventType_Timer,
kEventType_Lighting,
kEventType_Install,
kEventType_UpdateLedState,
#ifdef CONFIG_MCUMGR_SMP_BT
kEventType_StartSMPAdvertising,
#endif
Expand All @@ -54,6 +57,10 @@ struct AppEvent
uint8_t Action;
int32_t Actor;
} LightingEvent;
struct
{
LEDWidget * LedWidget;
} UpdateLedStateEvent;
};

EventHandler Handler;
Expand Down
4 changes: 4 additions & 0 deletions examples/lighting-app/nrfconnect/main/include/AppTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#pragma once

#include "AppEvent.h"
#include "LEDWidget.h"
#include "LightingManager.h"
#include "Rpc.h"

Expand Down Expand Up @@ -54,6 +55,9 @@ class AppTask

void DispatchEvent(AppEvent * event);

static void UpdateStatusLED();
static void LEDStateUpdateHandler(LEDWidget & ledWidget);
static void UpdateLedStateEventHandler(AppEvent * aEvent);
static void FunctionTimerEventHandler(AppEvent * aEvent);
static void FunctionHandler(AppEvent * aEvent);
static void StartThreadHandler(AppEvent * aEvent);
Expand Down
Loading

0 comments on commit b06b55c

Please sign in to comment.