Skip to content

Commit 220cb92

Browse files
committed
pbio/sys/light_matrix: Centralize shutdown logic.
Since pbsys has a graceful exit point, start shutdown animations from there instead of relying on changing statuses in special ways that avoid race conditions.
1 parent 32db6b6 commit 220cb92

File tree

4 files changed

+29
-27
lines changed

4 files changed

+29
-27
lines changed

lib/pbio/sys/core.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "core.h"
1414
#include "hmi.h"
1515
#include "light.h"
16+
#include "light_matrix.h"
1617
#include "storage.h"
1718
#include "supervisor.h"
1819
#include "program_stop.h"
@@ -58,6 +59,7 @@ void pbsys_init(void) {
5859
void pbsys_deinit(void) {
5960

6061
pbsys_storage_deinit();
62+
pbsys_hub_light_matrix_deinit();
6163

6264
uint32_t start = pbdrv_clock_get_ms();
6365

lib/pbio/sys/light_matrix.c

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,11 @@ void pbsys_hub_light_matrix_init(void) {
101101
pbsys_hub_light_matrix_start_power_animation();
102102
}
103103

104+
void pbsys_hub_light_matrix_deinit(void) {
105+
// Starting it again continues it in reverse.
106+
pbsys_hub_light_matrix_start_power_animation();
107+
}
108+
104109
/**
105110
* Clears the pixels needed for the run animation
106111
*/
@@ -139,35 +144,23 @@ static uint32_t pbsys_hub_light_matrix_user_program_animation_next(pbio_light_an
139144
}
140145

141146
void pbsys_hub_light_matrix_handle_status_change(pbsys_status_change_t event, pbio_pybricks_status_t data) {
147+
148+
pbio_pybricks_status_t status = (intptr_t)data;
149+
150+
// Only need to handle changing program running state.
151+
if (status != PBIO_PYBRICKS_STATUS_USER_PROGRAM_RUNNING) {
152+
return;
153+
}
154+
142155
if (event == PBSYS_STATUS_CHANGE_SET) {
143-
pbio_pybricks_status_t status = (intptr_t)data;
144-
145-
if (status == PBIO_PYBRICKS_STATUS_USER_PROGRAM_RUNNING) {
146-
// The user animation updates only a subset of pixels to save time,
147-
// so the rest must be cleared before it starts.
148-
pbsys_hub_light_matrix_user_program_animation_clear();
149-
pbio_light_animation_init(&pbsys_hub_light_matrix->animation, pbsys_hub_light_matrix_user_program_animation_next);
150-
pbio_light_animation_start(&pbsys_hub_light_matrix->animation);
151-
} else if (status == PBIO_PYBRICKS_STATUS_SHUTDOWN_REQUEST && !pbsys_status_test(PBIO_PYBRICKS_STATUS_USER_PROGRAM_RUNNING)) {
152-
// If shutdown was requested and no program is running, start power
153-
// down animation. This makes it run while the system processes are
154-
// deinitializing. If it was running, we should wait for it to end
155-
// first, which is handled below to avoid a race condition.
156-
pbsys_hub_light_matrix_start_power_animation();
157-
}
156+
// The user animation updates only a subset of pixels to save time,
157+
// so the rest must be cleared before it starts.
158+
pbsys_hub_light_matrix_user_program_animation_clear();
159+
pbio_light_animation_init(&pbsys_hub_light_matrix->animation, pbsys_hub_light_matrix_user_program_animation_next);
160+
pbio_light_animation_start(&pbsys_hub_light_matrix->animation);
158161
} else if (event == PBSYS_STATUS_CHANGE_CLEARED) {
159-
pbio_pybricks_status_t status = (intptr_t)data;
160-
161-
// The user program has ended.
162-
if (status == PBIO_PYBRICKS_STATUS_USER_PROGRAM_RUNNING) {
163-
if (pbsys_status_test(PBIO_PYBRICKS_STATUS_SHUTDOWN_REQUEST)) {
164-
// If it ended due to forced shutdown, show power-off animation.
165-
pbsys_hub_light_matrix_start_power_animation();
166-
} else {
167-
// If it simply completed, show stop sign and selected slot.
168-
pbsys_hub_light_matrix_show_idle_ui(100);
169-
}
170-
}
162+
// If the user program has ended, show stop sign and selected slot.
163+
pbsys_hub_light_matrix_show_idle_ui(100);
171164
}
172165
}
173166

lib/pbio/sys/light_matrix.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010

1111
#if PBSYS_CONFIG_HUB_LIGHT_MATRIX
1212
void pbsys_hub_light_matrix_init(void);
13+
void pbsys_hub_light_matrix_deinit(void);
1314
void pbsys_hub_light_matrix_handle_status_change(pbsys_status_change_t event, pbio_pybricks_status_t data);
1415
void pbsys_hub_light_matrix_update_program_slot(void);
1516
#else
1617
#define pbsys_hub_light_matrix_init()
18+
#define pbsys_hub_light_matrix_deinit()
1719
#define pbsys_hub_light_matrix_handle_status_change(event, data)
1820
#define pbsys_hub_light_matrix_update_program_slot()
1921
#endif

lib/pbio/sys/main.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ int main(int argc, char **argv) {
120120
pbsys_program_stop_set_buttons(PBIO_BUTTON_CENTER);
121121
pbio_stop_all(true);
122122
program.start_request_type = PBSYS_MAIN_PROGRAM_START_REQUEST_TYPE_NONE;
123+
124+
// Handle pending events triggered by the status change, such as
125+
// stopping status light animation.
126+
while (pbio_os_run_processes_once()) {
127+
}
123128
}
124129

125130
// Power off sensors and motors, including the ones that are always powered.

0 commit comments

Comments
 (0)