diff options
author | Eric Callahan <arksine.code@gmail.com> | 2022-04-14 11:07:40 -0400 |
---|---|---|
committer | KevinOConnor <kevin@koconnor.net> | 2022-05-10 11:48:06 -0400 |
commit | 3505f4cae59f4ba17d21fb4d46b3270bfeba9e54 (patch) | |
tree | bb65076ffdf2b88dfbcc951d1d814117c277fd0f /src | |
parent | b44eee609adf8c47d0a0c47ac5a6350078a948fa (diff) | |
download | kutter-3505f4cae59f4ba17d21fb4d46b3270bfeba9e54.tar.gz kutter-3505f4cae59f4ba17d21fb4d46b3270bfeba9e54.tar.xz kutter-3505f4cae59f4ba17d21fb4d46b3270bfeba9e54.zip |
canbus: add bootloader support
This adds a command which allows an external script to broadcast a
bootloader request, using a supplied UUID to match the request.
Included is a method to process requests to enter the canboot
bootloader.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/generic/canbus.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/src/generic/canbus.c b/src/generic/canbus.c index 6c7f2ccc..230f59ff 100644 --- a/src/generic/canbus.c +++ b/src/generic/canbus.c @@ -11,6 +11,7 @@ #include "command.h" // DECL_CONSTANT #include "generic/io.h" // readb #include "generic/irq.h" // irq_disable +#include "board/internal.h" // NVIC_SystemReset #include "sched.h" // sched_wake_task static uint32_t canbus_assigned_id; @@ -90,8 +91,13 @@ console_sendf(const struct command_encoder *ce, va_list args) // Available commands and responses #define CANBUS_CMD_QUERY_UNASSIGNED 0x00 #define CANBUS_CMD_SET_NODEID 0x01 +#define CANBUS_CMD_REQUEST_BOOTLOADER 0x02 #define CANBUS_RESP_NEED_NODEID 0x20 +// CanBoot definitions +#define CANBOOT_SIGNATURE 0x21746f6f426e6143 +#define CANBOOT_REQUEST 0x5984E3FA6CA1589B + // Helper to verify a UUID in a command matches this chip's UUID static int can_check_uuid(uint32_t id, uint32_t len, uint8_t *data) @@ -153,6 +159,24 @@ can_process_set_nodeid(uint32_t id, uint32_t len, uint8_t *data) } } +static void +can_process_request_bootloader(uint32_t id, uint32_t len, uint8_t *data) +{ + if (!can_check_uuid(id, len, data)) + return; + uint32_t *bl_vectors = (uint32_t *)(CONFIG_FLASH_START & 0xFF000000); + uint64_t *boot_sig = (uint64_t *)(bl_vectors[1] - 9); + uint64_t *req_sig = (uint64_t *)bl_vectors[0]; + if (boot_sig == (void *)ALIGN((size_t)boot_sig, 8) && + *boot_sig == CANBOOT_SIGNATURE && + req_sig == (void *)ALIGN((size_t)req_sig, 8)) + { + irq_disable(); + *req_sig = CANBOOT_REQUEST; + NVIC_SystemReset(); + } +} + // Handle an "admin" command static void can_process(uint32_t id, uint32_t len, uint8_t *data) @@ -166,6 +190,9 @@ can_process(uint32_t id, uint32_t len, uint8_t *data) case CANBUS_CMD_SET_NODEID: can_process_set_nodeid(id, len, data); break; + case CANBUS_CMD_REQUEST_BOOTLOADER: + can_process_request_bootloader(id, len, data); + break; } } |