Skip to content

Commit d0fac79

Browse files
committed
wip
1 parent c63dfe5 commit d0fac79

File tree

21 files changed

+299
-71
lines changed

21 files changed

+299
-71
lines changed

bootloader/Makefile

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,19 @@ uavcan_nodestatus_publisher \
2424
uavcan_allocatee \
2525
spi_device \
2626
driver_profiLED \
27-
uavcan_timesync
27+
uavcan_timesync \
28+
uavcan_debug
2829

2930
MESSAGES_ENABLED = \
3031
uavcan.protocol.GetNodeInfo \
3132
uavcan.protocol.file.BeginFirmwareUpdate \
3233
uavcan.protocol.file.Read \
3334
uavcan.protocol.RestartNode \
34-
uavcan.equipment.indication.LightsCommand
35+
uavcan.equipment.indication.LightsCommand \
36+
com.hex.file.FileStreamStart \
37+
com.hex.file.FileStreamChunk
38+
39+
DSDL_NAMESPACE_DIRS += dsdl/com
3540

3641
LOAD_REGION = bl
3742

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
int18[3] body_pos_mm
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
uavcan.Timestamp timestamp
2+
uint8[16] base_in_use_hwid
3+
void6
4+
uint2 CARRIER_SOLUTION_TYPE_NONE = 0
5+
uint2 CARRIER_SOLUTION_TYPE_FLOAT = 1
6+
uint2 CARRIER_SOLUTION_TYPE_FIXED = 2
7+
uint2 carrier_solution_type
8+
float32[<=3] pos_rel_body
9+
float32[3] pos_rel_ecef
10+
float16[<=6] pos_rel_ecef_covariance
474 Bytes
Binary file not shown.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
bool preserve_source
2+
bool overwrite_destination
3+
void6
4+
5+
uavcan.protocol.file.Path source
6+
uavcan.protocol.file.Path destination
7+
8+
---
9+
10+
uavcan.protocol.file.Error error
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
uavcan.protocol.file.Path path
2+
uint40 offset
3+
---
4+
uavcan.protocol.file.Error error
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
uint8 source_node_id
2+
uavcan.protocol.file.Path source_path
3+
uavcan.protocol.file.Path dest_path
4+
---
5+
void7
6+
bool ack
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
uavcan.protocol.file.Path path
2+
uint40 offset
3+
uint8[<=256] data

bootloader/openocd.cfg

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
11
source [find interface/stlink.cfg]
22
source [find target/stm32h7x.cfg]
3-
reset_config srst_only separate connect_assert_srst
4-
$_TARGETNAME configure -rtos ChibiOS
5-
$_TARGETNAME configure -event gdb-attach {
6-
halt
7-
}
8-
$_TARGETNAME configure -event gdb-attach {
9-
reset init
10-
}
3+
$_CHIPNAME.cpu0 configure -rtos ChibiOS
114
init
12-
reset halt

bootloader/out.bin

42.3 KB
Binary file not shown.

bootloader/src/bootloader.c

Lines changed: 138 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,18 @@
1515
#include <uavcan.protocol.RestartNode.h>
1616
#include <uavcan.protocol.GetNodeInfo.h>
1717

18+
#ifdef MODULE_UAVCAN_DEBUG_ENABLED
19+
#include <modules/uavcan_debug/uavcan_debug.h>
20+
#define BL_DEBUG(...) uavcan_send_debug_msg(UAVCAN_PROTOCOL_DEBUG_LOGLEVEL_DEBUG, "BL", __VA_ARGS__)
21+
#else
22+
#define BL_DEBUG(...) {}
23+
#endif
24+
25+
#ifdef BOOTLOADER_SUPPORT_BROADCAST_UPDATE
26+
#include <com.hex.file.FileStreamStart.h>
27+
#include <com.hex.file.FileStreamChunk.h>
28+
#endif // BOOTLOADER_SUPPORT_BROADCAST_UPDATE
29+
1830
#if __GNUC__ != 6 || __GNUC_MINOR__ != 3 || __GNUC_PATCHLEVEL__ != 1
1931
#error Please use arm-none-eabi-gcc 6.3.1.
2032
#endif
@@ -40,13 +52,17 @@ static const struct shared_hw_info_s _hw_info = BOARD_CONFIG_HW_INFO_STRUCTURE;
4052
static struct {
4153
bool in_progress;
4254
uint32_t ofs;
55+
uint32_t read_req_ofs;
4356
uint32_t app_start_ofs;
4457
uint8_t uavcan_idx;
4558
uint8_t read_transfer_id;
4659
uint8_t retries;
4760
uint8_t source_node_id;
4861
int32_t last_erased_page;
4962
char path[201];
63+
#ifdef BOOTLOADER_SUPPORT_BROADCAST_UPDATE
64+
bool using_stream_mode;
65+
#endif // BOOTLOADER_SUPPORT_BROADCAST_UPDATE
5066
} flash_state;
5167

5268
static struct {
@@ -64,11 +80,18 @@ static struct worker_thread_listener_task_s restart_req_listener_task;
6480
static struct worker_thread_timer_task_s delayed_restart_task;
6581
static struct worker_thread_listener_task_s getnodeinfo_req_listener_task;
6682

83+
#ifdef BOOTLOADER_SUPPORT_BROADCAST_UPDATE
84+
static struct worker_thread_listener_task_s filestreamchunk_listener_task;
85+
static void filestreamchunk_handler(size_t msg_size, const void* buf, void* ctx);
86+
87+
// static struct worker_thread_listener_task_s filestreamstart_res_listener_task;
88+
// static void filestreamstart_res_handler(size_t msg_size, const void* buf, void* ctx);
89+
#endif // BOOTLOADER_SUPPORT_BROADCAST_UPDATE
90+
6791
static void file_beginfirmwareupdate_request_handler(size_t msg_size, const void* buf, void* ctx);
6892
static void begin_flash_from_path(uint8_t uavcan_idx, uint8_t source_node_id, const char* path);
6993
static void file_read_response_handler(size_t msg_size, const void* buf, void* ctx);
70-
static void do_resend_read_request(void);
71-
static void do_send_read_request(void);
94+
static void do_send_read_request(bool retry);
7295
static uint32_t get_app_sec_size(void);
7396
static void start_boot(struct worker_thread_timer_task_s* task);
7497
static void update_app_info(void);
@@ -110,6 +133,14 @@ RUN_AFTER(UAVCAN_INIT) {
110133

111134
struct pubsub_topic_s* getnodeinfo_req_topic = uavcan_get_message_topic(0, &uavcan_protocol_GetNodeInfo_req_descriptor);
112135
worker_thread_add_listener_task(&WT, &getnodeinfo_req_listener_task, getnodeinfo_req_topic, getnodeinfo_req_handler, NULL);
136+
137+
#ifdef BOOTLOADER_SUPPORT_BROADCAST_UPDATE
138+
struct pubsub_topic_s* filestreamchunk_topic = uavcan_get_message_topic(0, &com_hex_file_FileStreamChunk_descriptor);
139+
worker_thread_add_listener_task(&WT, &filestreamchunk_listener_task, filestreamchunk_topic, filestreamchunk_handler, NULL);
140+
141+
// struct pubsub_topic_s* filestreamstart_res_topic = uavcan_get_message_topic(0, &com_hex_file_FileStreamStart_res_descriptor);
142+
// worker_thread_add_listener_task(&WT, &filestreamstart_res_listener_task, filestreamstart_res_topic, filestreamstart_res_handler, NULL);
143+
#endif // BOOTLOADER_SUPPORT_BROADCAST_UPDATE
113144
}
114145

115146
static void getnodeinfo_req_handler(size_t msg_size, const void* buf, void* ctx) {
@@ -168,71 +199,141 @@ static void begin_flash_from_path(uint8_t uavcan_idx, uint8_t source_node_id, co
168199
cancel_boot_timer();
169200
memset(&flash_state, 0, sizeof(flash_state));
170201
flash_state.in_progress = true;
171-
flash_state.ofs = 0;
202+
flash_state.ofs = 0;
203+
flash_state.read_transfer_id = 255;
172204
flash_state.source_node_id = source_node_id;
173205
flash_state.uavcan_idx = uavcan_idx;
174206
strncpy(flash_state.path, path, 200);
175-
worker_thread_add_timer_task(&WT, &read_timeout_task, read_request_response_timeout, NULL, chTimeMS2I(500), false);
176-
do_send_read_request();
207+
worker_thread_add_timer_task(&WT, &read_timeout_task, read_request_response_timeout, NULL, chTimeMS2I(2000), false);
208+
do_send_read_request(false);
177209

178210
corrupt_app();
179211
flash_state.last_erased_page = -1;
180212
}
181213

182-
static void file_read_response_handler(size_t msg_size, const void* buf, void* ctx) {
214+
static void process_chunk(size_t chunk_size, const void* chunk) {
215+
if (flash_state.ofs + chunk_size > get_app_sec_size()) {
216+
do_fail_update();
217+
BL_DEBUG("fail: file too large");
218+
return;
219+
}
220+
221+
if (chunk_size == 0) {
222+
on_update_complete();
223+
return;
224+
}
225+
226+
int32_t curr_page = get_app_page_from_ofs(flash_state.ofs + chunk_size);
227+
if (curr_page > flash_state.last_erased_page) {
228+
for (int32_t i=flash_state.last_erased_page+1; i<=curr_page; i++) {
229+
erase_app_page(i);
230+
}
231+
}
232+
233+
if (chunk_size < 256) {
234+
struct flash_write_buf_s buf = {((chunk_size/FLASH_WORD_SIZE) + 1) * FLASH_WORD_SIZE, chunk};
235+
flash_write((void*)get_app_address_from_ofs(flash_state.ofs), 1, &buf);
236+
on_update_complete();
237+
} else {
238+
struct flash_write_buf_s buf = {chunk_size, chunk};
239+
flash_write((void*)get_app_address_from_ofs(flash_state.ofs), 1, &buf);
240+
flash_state.ofs += chunk_size;
241+
do_send_read_request(false);
242+
}
243+
}
244+
245+
// TODO factor common code out of read_response_handler and filestreamchunk_handler
246+
#ifdef BOOTLOADER_SUPPORT_BROADCAST_UPDATE
247+
static void filestreamchunk_handler(size_t msg_size, const void* buf, void* ctx) {
183248
(void)msg_size;
184249
(void)ctx;
250+
185251
if (flash_state.in_progress) {
186252
const struct uavcan_deserialized_message_s* msg_wrapper = buf;
187-
const struct uavcan_protocol_file_Read_res_s *res = (const struct uavcan_protocol_file_Read_res_s*)msg_wrapper->msg;
253+
const struct com_hex_file_FileStreamChunk_s *msg = (const struct com_hex_file_FileStreamChunk_s*)msg_wrapper->msg;
188254

189-
if (msg_wrapper->transfer_id != flash_state.read_transfer_id) {
255+
if (msg->path.path_len != strnlen(flash_state.path, 200) || memcmp(flash_state.path, msg->path.path, msg->path.path_len) != 0) {
256+
// Not our stream
190257
return;
191258
}
192259

193-
if (res->error.value != 0 || flash_state.ofs + res->data_len > get_app_sec_size()) {
194-
do_fail_update();
260+
flash_state.using_stream_mode = true;
261+
worker_thread_timer_task_reschedule(&WT, &read_timeout_task, chTimeMS2I(2000));
262+
263+
if (msg->offset > flash_state.ofs) {
264+
// We need to ask for the stream to go back to our offset
265+
struct com_hex_file_FileStreamStart_req_s req;
266+
req.path.path_len = strnlen(flash_state.path, 200);
267+
req.offset = flash_state.ofs;
268+
memcpy(req.path.path, flash_state.path, req.path.path_len);
269+
uavcan_request(flash_state.uavcan_idx, &com_hex_file_FileStreamStart_req_descriptor, CANARD_TRANSFER_PRIORITY_MEDIUM+1, flash_state.source_node_id, &req);
195270
return;
196271
}
197272

198-
if (res->data_len == 0) {
199-
on_update_complete();
273+
if (msg->offset != flash_state.ofs) {
200274
return;
201275
}
202276

203-
int32_t curr_page = get_app_page_from_ofs(flash_state.ofs + res->data_len);
204-
if (curr_page > flash_state.last_erased_page) {
205-
for (int32_t i=flash_state.last_erased_page+1; i<=curr_page; i++) {
206-
erase_app_page(i);
207-
}
277+
process_chunk(msg->data_len, msg->data);
278+
}
279+
}
280+
#endif // BOOTLOADER_SUPPORT_BROADCAST_UPDATE
281+
282+
static void file_read_response_handler(size_t msg_size, const void* buf, void* ctx) {
283+
(void)msg_size;
284+
(void)ctx;
285+
if (flash_state.in_progress) {
286+
const struct uavcan_deserialized_message_s* msg_wrapper = buf;
287+
const struct uavcan_protocol_file_Read_res_s *res = (const struct uavcan_protocol_file_Read_res_s*)msg_wrapper->msg;
288+
289+
if (msg_wrapper->transfer_id != flash_state.read_transfer_id || flash_state.ofs != flash_state.read_req_ofs) {
290+
return;
208291
}
209292

210-
if (res->data_len < 256) {
211-
struct flash_write_buf_s buf = {((res->data_len/FLASH_WORD_SIZE) + 1) * FLASH_WORD_SIZE, (void*)res->data};
212-
flash_write((void*)get_app_address_from_ofs(flash_state.ofs), 1, &buf);
213-
on_update_complete();
214-
} else {
215-
struct flash_write_buf_s buf = {res->data_len, (void*)res->data};
216-
flash_write((void*)get_app_address_from_ofs(flash_state.ofs), 1, &buf);
217-
flash_state.ofs += res->data_len;
218-
do_send_read_request();
293+
if (res->error.value != 0) {
294+
do_fail_update();
295+
BL_DEBUG("fail: file read error");
296+
return;
219297
}
298+
299+
process_chunk(res->data_len, res->data);
220300
}
221301
}
222302

223-
static void do_resend_read_request(void) {
303+
static void do_send_read_request(bool retry) {
304+
305+
#ifdef BOOTLOADER_SUPPORT_BROADCAST_UPDATE
306+
if (!flash_state.using_stream_mode) {
307+
struct uavcan_protocol_file_Read_req_s read_req;
308+
flash_state.read_req_ofs = read_req.offset = flash_state.ofs;
309+
strncpy((char*)read_req.path.path,flash_state.path,sizeof(read_req.path));
310+
read_req.path.path_len = strnlen(flash_state.path,sizeof(read_req.path));
311+
flash_state.read_transfer_id = uavcan_request(flash_state.uavcan_idx, &uavcan_protocol_file_Read_req_descriptor, CANARD_TRANSFER_PRIORITY_MEDIUM+1, flash_state.source_node_id, &read_req);
312+
}
313+
314+
if ((retry && flash_state.using_stream_mode) || (flash_state.ofs < 2048 && !flash_state.using_stream_mode)) {
315+
// attempt to start stream mode with the first few requests
316+
struct com_hex_file_FileStreamStart_req_s req;
317+
req.offset = flash_state.ofs;
318+
req.path.path_len = strnlen(flash_state.path, 200);
319+
memcpy(req.path.path, flash_state.path, req.path.path_len);
320+
uavcan_request(flash_state.uavcan_idx, &com_hex_file_FileStreamStart_req_descriptor, CANARD_TRANSFER_PRIORITY_MEDIUM+1, flash_state.source_node_id, &req);
321+
}
322+
#else
224323
struct uavcan_protocol_file_Read_req_s read_req;
225324
read_req.offset = flash_state.ofs;
226325
strncpy((char*)read_req.path.path,flash_state.path,sizeof(read_req.path));
227326
read_req.path.path_len = strnlen(flash_state.path,sizeof(read_req.path));
228-
flash_state.read_transfer_id = uavcan_request(flash_state.uavcan_idx, &uavcan_protocol_file_Read_req_descriptor, CANARD_TRANSFER_PRIORITY_HIGH, flash_state.source_node_id, &read_req);
229-
worker_thread_timer_task_reschedule(&WT, &read_timeout_task, chTimeMS2I(500));
230-
flash_state.retries++;
231-
}
327+
flash_state.read_transfer_id = uavcan_request(flash_state.uavcan_idx, &uavcan_protocol_file_Read_req_descriptor, CANARD_TRANSFER_PRIORITY_MEDIUM+1, flash_state.source_node_id, &read_req);
328+
#endif
232329

233-
static void do_send_read_request(void) {
234-
do_resend_read_request();
235-
flash_state.retries = 0;
330+
worker_thread_timer_task_reschedule(&WT, &read_timeout_task, chTimeMS2I(1000));
331+
332+
if (retry) {
333+
flash_state.retries++;
334+
} else {
335+
flash_state.retries = 0;
336+
}
236337
}
237338

238339
static uint32_t get_app_sec_size(void) {
@@ -414,9 +515,10 @@ static void delayed_restart_func(struct worker_thread_timer_task_s* task) {
414515
static void read_request_response_timeout(struct worker_thread_timer_task_s* task) {
415516
(void)task;
416517
if (flash_state.in_progress) {
417-
do_resend_read_request();
418-
if (flash_state.retries > 10) { // retry for 5 seconds
518+
do_send_read_request(true);
519+
if (flash_state.retries > 100) { // retry for 5 seconds
419520
do_fail_update();
521+
BL_DEBUG("fail: out of retries");
420522
}
421523
}
422524
}

include/chconf.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,16 +672,20 @@
672672
/**
673673
* @brief ISR enter hook.
674674
*/
675+
#ifndef CH_CFG_IRQ_PROLOGUE_HOOK
675676
#define CH_CFG_IRQ_PROLOGUE_HOOK() { \
676677
/* IRQ prologue code here.*/ \
677678
}
679+
#endif
678680

679681
/**
680682
* @brief ISR exit hook.
681683
*/
684+
#ifndef CH_CFG_IRQ_EPILOGUE_HOOK
682685
#define CH_CFG_IRQ_EPILOGUE_HOOK() { \
683686
/* IRQ epilogue code here.*/ \
684687
}
688+
#endif
685689

686690
/**
687691
* @brief Idle thread enter hook.

mk/build.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes
209209
CPPWARN = -Wall -Wextra -Wundef
210210

211211
# List all user C define here, like -D_DEBUG=1
212-
UDEFS += -DGIT_HASH=0x$(shell git rev-parse --short=8 HEAD) $(MODULES_ENABLED_DEFS) -DCORTEX_ENABLE_WFI_IDLE=TRUE
212+
UDEFS += -DGIT_HASH=0x$(shell git rev-parse --short=8 HEAD) $(MODULES_ENABLED_DEFS) -DCORTEX_ENABLE_WFI_IDLE=FALSE
213213

214214
# Define ASM defines here
215215
UADEFS =

modules/can/can.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -567,9 +567,9 @@ static void can_expire_handler(struct worker_thread_timer_task_s* task) {
567567
for (uint8_t i=0; i < instance->num_tx_mailboxes; i++) {
568568
chSysLock();
569569
if (instance->tx_mailbox[i].state == CAN_TX_MAILBOX_PENDING && can_tx_frame_expired_X(instance->tx_mailbox[i].frame)) {
570-
if (instance->driver_iface->abort_tx_mailbox_I(instance->driver_ctx, i)) {
571-
instance->tx_mailbox[i].state = CAN_TX_MAILBOX_ABORTING;
572-
}
570+
// NOTE: order matters below - abort_tx_mailbox_I may call functions that read the mailbox state
571+
instance->tx_mailbox[i].state = CAN_TX_MAILBOX_ABORTING;
572+
instance->driver_iface->abort_tx_mailbox_I(instance->driver_ctx, i);
573573
}
574574
chSysUnlock();
575575
}

modules/can/can_driver.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
typedef void (*driver_start_t)(void* ctx, bool silent, bool auto_retransmit, uint32_t baudrate);
55
typedef void (*driver_stop_t)(void* ctx);
66

7-
typedef bool (*driver_mailbox_abort_t)(void* ctx, uint8_t mb_idx);
7+
typedef void (*driver_mailbox_abort_t)(void* ctx, uint8_t mb_idx);
88
typedef bool (*driver_load_tx_mailbox_t)(void* ctx, uint8_t mb_idx, struct can_frame_s* frame);
99
typedef bool (*driver_pop_rx_frame_t)(void* ctx, uint8_t mb_idx, struct can_frame_s* frame);
1010
typedef bool (*driver_rx_frame_available_t)(void* ctx, uint8_t mb_idx);

0 commit comments

Comments
 (0)