aboutsummaryrefslogtreecommitdiffstats
path: root/src/displayapp
diff options
context:
space:
mode:
authormark9064 <30447455+mark9064@users.noreply.github.com>2024-08-22 21:24:04 +0100
committerNeroBurner <pyro4hell@gmail.com>2024-09-21 21:08:07 +0200
commitc3d05901a05a274f30c15b8c0640b6ecdd973ac3 (patch)
treed63aaacce475f495670787f79019df8af6e2af7d /src/displayapp
parentb3756e45fa50ce81255dc3bb21cbce4af3254f2f (diff)
Refactor SystemTask state handling for resilience
State transitions now happen immediately where possible This simplifies state management in general, and prevents bugs such as the chime issue from occurring in the first place
Diffstat (limited to 'src/displayapp')
-rw-r--r--src/displayapp/DisplayApp.cpp23
1 files changed, 20 insertions, 3 deletions
diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp
index 79519621..076b4f8a 100644
--- a/src/displayapp/DisplayApp.cpp
+++ b/src/displayapp/DisplayApp.cpp
@@ -255,9 +255,20 @@ void DisplayApp::Refresh() {
isDimmed = true;
brightnessController.Set(Controllers::BrightnessController::Levels::Low);
}
- if (IsPastSleepTime()) {
- systemTask->PushMessage(System::Messages::GoToSleep);
- state = States::Idle;
+ if (IsPastSleepTime() && uxQueueMessagesWaiting(msgQueue) == 0) {
+ PushMessageToSystemTask(System::Messages::GoToSleep);
+ // Can't set state to Idle here, something may send
+ // DisableSleeping before this GoToSleep arrives
+ // Instead we check we have no messages queued before sending GoToSleep
+ // This works as the SystemTask is higher priority than DisplayApp
+ // As soon as we send GoToSleep, SystemTask pre-empts DisplayApp
+ // Whenever DisplayApp is running again, it is guaranteed that
+ // SystemTask has handled the message
+ // If it responded, we will have a GoToSleep waiting in the queue
+ // By checking that there are no messages in the queue, we avoid
+ // resending GoToSleep when we already have a response
+ // SystemTask is resilient to duplicate messages, this is an
+ // optimisation to reduce pressure on the message queues
}
} else if (isDimmed) {
isDimmed = false;
@@ -273,6 +284,9 @@ void DisplayApp::Refresh() {
if (xQueueReceive(msgQueue, &msg, queueTimeout) == pdTRUE) {
switch (msg) {
case Messages::GoToSleep:
+ if (state != States::Running) {
+ break;
+ }
while (brightnessController.Level() != Controllers::BrightnessController::Levels::Low) {
brightnessController.Lower();
vTaskDelay(100);
@@ -307,6 +321,9 @@ void DisplayApp::Refresh() {
lv_disp_trig_activity(nullptr);
break;
case Messages::GoToRunning:
+ if (state == States::Running) {
+ break;
+ }
if (settingsController.GetAlwaysOnDisplay()) {
lcd.LowPowerOff();
} else {