diff --git a/src/Makefile b/src/Makefile index 89e6a06..78c5711 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,4 +1,4 @@ # Main code build rules -src-y += canboot_main.c sched.c command.c flashcmd.c +src-y += sched.c bootentry.c command.c flashcmd.c src-$(CONFIG_ENABLE_LED) += led.c diff --git a/src/canboot_main.c b/src/bootentry.c similarity index 58% rename from src/canboot_main.c rename to src/bootentry.c index 4623605..adb8d1c 100644 --- a/src/canboot_main.c +++ b/src/bootentry.c @@ -1,4 +1,4 @@ -// Canboot main event loop +// Determine if the bootloader or application should start // // Copyright (C) 2021 Eric Callahan // @@ -9,61 +9,11 @@ #include "board/misc.h" // udelay #include "board/flash.h" // flash_read_block #include "board/gpio.h" // gpio_in_setup -#include "canboot_main.h" // canboot_main -#include "command.h" // command_respond_ack +#include "bootentry.h" // bootentry_check #include "ctr.h" // DECL_CTR -#include "byteorder.h" // cpu_to_le32 -#include "sched.h" // sched_run_init #define REQUEST_SIG 0x5984E3FA6CA1589B // Random request sig -static uint8_t complete; -static uint32_t complete_endtime; - -void -command_complete(uint32_t *data) -{ - uint32_t out[3]; - command_respond_ack(CMD_COMPLETE, out, ARRAY_SIZE(out)); - complete = 1; - complete_endtime = timer_read_time() + timer_from_us(100000); -} - -void -complete_task(void) -{ - if (complete && timer_is_before(complete_endtime, timer_read_time())) - jump_to_application(); -} -DECL_TASK(complete_task); - -void -command_connect(uint32_t *data) -{ - uint32_t mcuwords = DIV_ROUND_UP(strlen(CONFIG_MCU), 4); - uint32_t out[6 + mcuwords]; - memset(out, 0, (6 + mcuwords) * 4); - out[2] = cpu_to_le32(PROTO_VERSION); - out[3] = cpu_to_le32(CONFIG_APPLICATION_START); - out[4] = cpu_to_le32(CONFIG_BLOCK_SIZE); - memcpy(&out[5], CONFIG_MCU, strlen(CONFIG_MCU)); - command_respond_ack(CMD_CONNECT, out, ARRAY_SIZE(out)); -} - -static inline uint8_t -check_application_code(void) -{ - // Read the first block of memory, if it - // is all 0xFF then no application has been flashed - uint8_t buf[CONFIG_BLOCK_SIZE]; - flash_read_block(CONFIG_APPLICATION_START, (uint32_t*)buf); - for (uint8_t i = 0; i < CONFIG_BLOCK_SIZE; i++) { - if (buf[i] != 0xFF) - return 1; - } - return 0; -} - // Generated by buildcommands.py DECL_CTR("DECL_BUTTON " __stringify(CONFIG_BUTTON_PIN)); extern int32_t button_gpio, button_high, button_pullup; @@ -93,22 +43,23 @@ check_double_reset(void) // No reset, read the key back out to clear it } - -/**************************************************************** - * Startup - ****************************************************************/ -static void -enter_bootloader(void) +static uint8_t +check_application_code(void) { - sched_run_init(); - - for (;;) - sched_run_tasks(); + // Read the first block of memory, if it + // is all 0xFF then no application has been flashed + uint8_t buf[CONFIG_BLOCK_SIZE]; + flash_read_block(CONFIG_APPLICATION_START, (uint32_t*)buf); + for (uint8_t i = 0; i < CONFIG_BLOCK_SIZE; i++) { + if (buf[i] != 0xFF) + return 1; + } + return 0; } -// Main loop of program -void -canboot_main(void) +// Check if bootloader or application should be started +int +bootentry_check(void) { // Enter the bootloader in the following conditions: // - The request signature is set in memory (request from app) @@ -116,11 +67,12 @@ canboot_main(void) uint64_t bootup_code = get_bootup_code(); if (bootup_code == REQUEST_SIG || !check_application_code() || check_button_pressed()) { + // Start bootloader main loop set_bootup_code(0); - enter_bootloader(); + return 1; } check_double_reset(); // jump to app - jump_to_application(); + return 0; } diff --git a/src/bootentry.h b/src/bootentry.h new file mode 100644 index 0000000..e651e40 --- /dev/null +++ b/src/bootentry.h @@ -0,0 +1,6 @@ +#ifndef __BOOTENTRY_H +#define __BOOTENTRY_H + +int bootentry_check(void); + +#endif // bootentry.h diff --git a/src/canboot_main.h b/src/canboot_main.h deleted file mode 100644 index 50608bc..0000000 --- a/src/canboot_main.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __CANBOOT_MAIN_H -#define __CANBOOT_MAIN_H - -void canboot_main(void); - -#endif // canboot_main.h diff --git a/src/flashcmd.c b/src/flashcmd.c index d58d6a7..43dea75 100644 --- a/src/flashcmd.c +++ b/src/flashcmd.c @@ -7,9 +7,55 @@ #include // memmove #include "autoconf.h" // CONFIG_BLOCK_SIZE #include "board/flash.h" // flash_write_page +#include "board/misc.h" // jump_to_application #include "byteorder.h" // cpu_to_le32 #include "command.h" // command_respond_ack #include "flashcmd.h" // flashcmd_is_in_transfer +#include "sched.h" // DECL_TASK + +// Handler for "connect" commands +void +command_connect(uint32_t *data) +{ + uint32_t mcuwords = DIV_ROUND_UP(strlen(CONFIG_MCU), 4); + uint32_t out[6 + mcuwords]; + memset(out, 0, (6 + mcuwords) * 4); + out[2] = cpu_to_le32(PROTO_VERSION); + out[3] = cpu_to_le32(CONFIG_APPLICATION_START); + out[4] = cpu_to_le32(CONFIG_BLOCK_SIZE); + memcpy(&out[5], CONFIG_MCU, strlen(CONFIG_MCU)); + command_respond_ack(CMD_CONNECT, out, ARRAY_SIZE(out)); +} + + +/**************************************************************** + * Command "complete" handling + ****************************************************************/ + +static uint8_t complete; +static uint32_t complete_endtime; + +void +command_complete(uint32_t *data) +{ + uint32_t out[3]; + command_respond_ack(CMD_COMPLETE, out, ARRAY_SIZE(out)); + complete = 1; + complete_endtime = timer_read_time() + timer_from_us(100000); +} + +void +complete_task(void) +{ + if (complete && timer_is_before(complete_endtime, timer_read_time())) + jump_to_application(); +} +DECL_TASK(complete_task); + + +/**************************************************************** + * Flash commands + ****************************************************************/ static uint8_t page_buffer[CONFIG_MAX_FLASH_PAGE_SIZE]; // Page Tracking diff --git a/src/sched.c b/src/sched.c index f82a97b..7050f21 100644 --- a/src/sched.c +++ b/src/sched.c @@ -5,6 +5,8 @@ // This file may be distributed under the terms of the GNU GPLv3 license. #include "board/io.h" // readb +#include "board/misc.h" // jump_to_application +#include "bootentry.h" // bootentry_check #include "sched.h" // sched_check_periodic // Note that a task is ready to run @@ -24,18 +26,20 @@ sched_check_wake(struct task_wake *w) return 1; } +// Init followed by main task dispatch loop void -sched_run_init(void) +sched_main(void) { + if (!bootentry_check()) + jump_to_application(); + // Run all init functions marked with DECL_INIT() extern void ctr_run_initfuncs(void); ctr_run_initfuncs(); -} -void -sched_run_tasks(void) -{ - // Run all task functions marked with DECL_TASK() - extern void ctr_run_taskfuncs(void); - ctr_run_taskfuncs(); + for (;;) { + // Run all task functions marked with DECL_TASK() + extern void ctr_run_taskfuncs(void); + ctr_run_taskfuncs(); + } } diff --git a/src/sched.h b/src/sched.h index 6baa84b..917a917 100644 --- a/src/sched.h +++ b/src/sched.h @@ -19,8 +19,7 @@ struct task_wake { // sched.c void sched_wake_task(struct task_wake *w); uint8_t sched_check_wake(struct task_wake *w); -void sched_run_init(void); -void sched_run_tasks(void); +void sched_main(void); // Compiler glue for DECL_X macros above. #define _DECL_CALLLIST(NAME, FUNC) \ diff --git a/src/stm32/stm32f0.c b/src/stm32/stm32f0.c index 3a2e438..70159f7 100644 --- a/src/stm32/stm32f0.c +++ b/src/stm32/stm32f0.c @@ -7,9 +7,9 @@ #include "autoconf.h" // CONFIG_CLOCK_REF_FREQ #include "board/armcm_boot.h" // armcm_main #include "board/irq.h" // irq_disable -#include "board/misc.h" // jump_to_application +#include "board/misc.h" // timer_init #include "internal.h" // enable_pclock -#include "canboot_main.h" // sched_main +#include "sched.h" // sched_main #define FREQ_PERIPH 48000000 @@ -113,5 +113,5 @@ armcm_main(void) #endif timer_init(); - canboot_main(); + sched_main(); } diff --git a/src/stm32/stm32f1.c b/src/stm32/stm32f1.c index fd26ca5..870f7de 100644 --- a/src/stm32/stm32f1.c +++ b/src/stm32/stm32f1.c @@ -8,8 +8,7 @@ #include "board/armcm_boot.h" // VectorTable #include "board/irq.h" // irq_disable #include "internal.h" // enable_pclock -#include "board/misc.h" // jump_to_application -#include "canboot_main.h" // canboot_main +#include "sched.h" // sched_main #define FREQ_PERIPH (CONFIG_CLOCK_FREQ / 2) @@ -235,5 +234,5 @@ armcm_main(void) stm32f1_alternative_remap(AFIO_MAPR_SWJ_CFG_Msk, AFIO_MAPR_SWJ_CFG_JTAGDISABLE); - canboot_main(); + sched_main(); }