Skip to content
This repository was archived by the owner on Jul 31, 2024. It is now read-only.

Commit 1660ba7

Browse files
committed
samples: dfu: report FW state and reboot from main thread
So far there were 3 threads involved: * Zephyr main * initialize network * start Golioth system client * Golioth system_client * handle incoming Golioth communication * report FW states * Zephyr sysworkq * trigger reboot This is overly complicated and makes callbacks implementation hard to read due to FW state reporting logic taking most of callback body. Change implementation to utilize only 2 threads instead, with following changes: * Zephyr main * initialize network (as before) * start Golioth system client (as before) * report FW reporting (new) * trigger reboot (new) * Golioth system_client * handle incoming Golioth communication There is little data shared among those threads and most important thing is to notify about state of FW download. For that reason use semaphores, which make main() execution continue step by step, making overall logic easy to follow. This change solves one of the issues with pytest scripts expecting a specific sequence of FW states. So far this sequence was not followed from time to time, due to UDP packets reordering. This issue is now partly solved by reporting FW states from Zephyr main thread and remaining fix will be a conversion from asynchronous to synchronous golioth_fw_report_state() API. Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
1 parent c297f50 commit 1660ba7

File tree

1 file changed

+66
-55
lines changed

1 file changed

+66
-55
lines changed

‎samples/dfu/src/main.c‎

Lines changed: 66 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,11 @@ LOG_MODULE_REGISTER(golioth_dfu, LOG_LEVEL_DBG);
1919

2020
#include "flash.h"
2121

22-
#define REBOOT_DELAY_SEC 1
23-
24-
static void reboot_handler(struct k_work *work)
25-
{
26-
sys_reboot(SYS_REBOOT_COLD);
27-
}
22+
K_SEM_DEFINE(sem_connected, 0, 1);
23+
K_SEM_DEFINE(sem_downloading, 0, 1);
24+
K_SEM_DEFINE(sem_downloaded, 0, 1);
2825

29-
K_WORK_DELAYABLE_DEFINE(reboot_work, reboot_handler);
26+
#define REBOOT_DELAY_SEC 1
3027

3128
static struct golioth_client *client = GOLIOTH_SYSTEM_CLIENT_GET();
3229

@@ -66,38 +63,7 @@ static int data_received(struct golioth_req_rsp *rsp)
6663
}
6764

6865
if (last) {
69-
err = golioth_fw_report_state(client, "main",
70-
current_version_str,
71-
dfu->version,
72-
GOLIOTH_FW_STATE_DOWNLOADED,
73-
GOLIOTH_DFU_RESULT_INITIAL);
74-
if (err) {
75-
LOG_ERR("Failed to update to '%s' state: %d", "downloaded", err);
76-
}
77-
78-
err = golioth_fw_report_state(client, "main",
79-
current_version_str,
80-
dfu->version,
81-
GOLIOTH_FW_STATE_UPDATING,
82-
GOLIOTH_DFU_RESULT_INITIAL);
83-
if (err) {
84-
LOG_ERR("Failed to update to '%s' state: %d", "updating", err);
85-
}
86-
87-
LOG_INF("Requesting upgrade");
88-
89-
err = boot_request_upgrade(BOOT_UPGRADE_TEST);
90-
if (err) {
91-
LOG_ERR("Failed to request upgrade: %d", err);
92-
return err;
93-
}
94-
95-
LOG_INF("Rebooting in %d second(s)", REBOOT_DELAY_SEC);
96-
97-
/* Synchronize logs */
98-
LOG_PANIC();
99-
100-
k_work_schedule(&reboot_work, K_SECONDS(REBOOT_DELAY_SEC));
66+
k_sem_give(&sem_downloaded);
10167
}
10268

10369
if (rsp->get_next) {
@@ -158,14 +124,7 @@ static int golioth_desired_update(struct golioth_req_rsp *rsp)
158124

159125
uri_p = uri_strip_leading_slash(uri, &uri_len);
160126

161-
err = golioth_fw_report_state(client, "main",
162-
current_version_str,
163-
dfu->version,
164-
GOLIOTH_FW_STATE_DOWNLOADING,
165-
GOLIOTH_DFU_RESULT_INITIAL);
166-
if (err) {
167-
LOG_ERR("Failed to update to '%s' state: %d", "downloading", err);
168-
}
127+
k_sem_give(&sem_downloading);
169128

170129
err = golioth_fw_download(client, uri_p, uri_len, data_received, dfu);
171130
if (err) {
@@ -180,14 +139,7 @@ static void golioth_on_connect(struct golioth_client *client)
180139
{
181140
int err;
182141

183-
err = golioth_fw_report_state(client, "main",
184-
current_version_str,
185-
NULL,
186-
GOLIOTH_FW_STATE_IDLE,
187-
dfu_initial_result);
188-
if (err) {
189-
LOG_ERR("Failed to report firmware state: %d", err);
190-
}
142+
k_sem_give(&sem_connected);
191143

192144
err = golioth_fw_observe_desired(client, golioth_desired_update, &update_ctx);
193145
if (err) {
@@ -222,4 +174,63 @@ void main(void)
222174

223175
client->on_connect = golioth_on_connect;
224176
golioth_system_client_start();
177+
178+
k_sem_take(&sem_connected, K_FOREVER);
179+
180+
err = golioth_fw_report_state(client, "main",
181+
current_version_str,
182+
NULL,
183+
GOLIOTH_FW_STATE_IDLE,
184+
dfu_initial_result);
185+
if (err) {
186+
LOG_ERR("Failed to report firmware state: %d", err);
187+
}
188+
189+
k_sem_take(&sem_downloading, K_FOREVER);
190+
191+
err = golioth_fw_report_state(client, "main",
192+
current_version_str,
193+
update_ctx.version,
194+
GOLIOTH_FW_STATE_DOWNLOADING,
195+
GOLIOTH_DFU_RESULT_INITIAL);
196+
if (err) {
197+
LOG_ERR("Failed to update to '%s' state: %d", "downloading", err);
198+
}
199+
200+
k_sem_take(&sem_downloaded, K_FOREVER);
201+
202+
err = golioth_fw_report_state(client, "main",
203+
current_version_str,
204+
update_ctx.version,
205+
GOLIOTH_FW_STATE_DOWNLOADED,
206+
GOLIOTH_DFU_RESULT_INITIAL);
207+
if (err) {
208+
LOG_ERR("Failed to update to '%s' state: %d", "downloaded", err);
209+
}
210+
211+
err = golioth_fw_report_state(client, "main",
212+
current_version_str,
213+
update_ctx.version,
214+
GOLIOTH_FW_STATE_UPDATING,
215+
GOLIOTH_DFU_RESULT_INITIAL);
216+
if (err) {
217+
LOG_ERR("Failed to update to '%s' state: %d", "updating", err);
218+
}
219+
220+
LOG_INF("Requesting upgrade");
221+
222+
err = boot_request_upgrade(BOOT_UPGRADE_TEST);
223+
if (err) {
224+
LOG_ERR("Failed to request upgrade: %d", err);
225+
return;
226+
}
227+
228+
LOG_INF("Rebooting in %d second(s)", REBOOT_DELAY_SEC);
229+
230+
/* Synchronize logs */
231+
LOG_PANIC();
232+
233+
k_sleep(K_SECONDS(REBOOT_DELAY_SEC));
234+
235+
sys_reboot(SYS_REBOOT_COLD);
225236
}

0 commit comments

Comments
 (0)