bootentry: Breakup canboot_main.c to flashcmd.c, bootentry.c, and sched.c

Move command handlers from canboot_main.c to flashcmd.c.  Move startup
code to sched.c.  Rename remaining bootloader entry code to new
bootentry.c file.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2022-05-10 15:11:00 -04:00 committed by Eric Callahan
parent 09a500cf90
commit 4a798a2e3b
9 changed files with 90 additions and 90 deletions

View File

@ -1,4 +1,4 @@
# Main code build rules # 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 src-$(CONFIG_ENABLE_LED) += led.c

View File

@ -1,4 +1,4 @@
// Canboot main event loop // Determine if the bootloader or application should start
// //
// Copyright (C) 2021 Eric Callahan <arksine.code@gmail.com> // Copyright (C) 2021 Eric Callahan <arksine.code@gmail.com>
// //
@ -9,61 +9,11 @@
#include "board/misc.h" // udelay #include "board/misc.h" // udelay
#include "board/flash.h" // flash_read_block #include "board/flash.h" // flash_read_block
#include "board/gpio.h" // gpio_in_setup #include "board/gpio.h" // gpio_in_setup
#include "canboot_main.h" // canboot_main #include "bootentry.h" // bootentry_check
#include "command.h" // command_respond_ack
#include "ctr.h" // DECL_CTR #include "ctr.h" // DECL_CTR
#include "byteorder.h" // cpu_to_le32
#include "sched.h" // sched_run_init
#define REQUEST_SIG 0x5984E3FA6CA1589B // Random request sig #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 // Generated by buildcommands.py
DECL_CTR("DECL_BUTTON " __stringify(CONFIG_BUTTON_PIN)); DECL_CTR("DECL_BUTTON " __stringify(CONFIG_BUTTON_PIN));
extern int32_t button_gpio, button_high, button_pullup; 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 // No reset, read the key back out to clear it
} }
static uint8_t
/**************************************************************** check_application_code(void)
* Startup
****************************************************************/
static void
enter_bootloader(void)
{ {
sched_run_init(); // Read the first block of memory, if it
// is all 0xFF then no application has been flashed
for (;;) uint8_t buf[CONFIG_BLOCK_SIZE];
sched_run_tasks(); 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 // Check if bootloader or application should be started
void int
canboot_main(void) bootentry_check(void)
{ {
// Enter the bootloader in the following conditions: // Enter the bootloader in the following conditions:
// - The request signature is set in memory (request from app) // - The request signature is set in memory (request from app)
@ -116,11 +67,12 @@ canboot_main(void)
uint64_t bootup_code = get_bootup_code(); uint64_t bootup_code = get_bootup_code();
if (bootup_code == REQUEST_SIG || !check_application_code() if (bootup_code == REQUEST_SIG || !check_application_code()
|| check_button_pressed()) { || check_button_pressed()) {
// Start bootloader main loop
set_bootup_code(0); set_bootup_code(0);
enter_bootloader(); return 1;
} }
check_double_reset(); check_double_reset();
// jump to app // jump to app
jump_to_application(); return 0;
} }

6
src/bootentry.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef __BOOTENTRY_H
#define __BOOTENTRY_H
int bootentry_check(void);
#endif // bootentry.h

View File

@ -1,6 +0,0 @@
#ifndef __CANBOOT_MAIN_H
#define __CANBOOT_MAIN_H
void canboot_main(void);
#endif // canboot_main.h

View File

@ -7,9 +7,55 @@
#include <string.h> // memmove #include <string.h> // memmove
#include "autoconf.h" // CONFIG_BLOCK_SIZE #include "autoconf.h" // CONFIG_BLOCK_SIZE
#include "board/flash.h" // flash_write_page #include "board/flash.h" // flash_write_page
#include "board/misc.h" // jump_to_application
#include "byteorder.h" // cpu_to_le32 #include "byteorder.h" // cpu_to_le32
#include "command.h" // command_respond_ack #include "command.h" // command_respond_ack
#include "flashcmd.h" // flashcmd_is_in_transfer #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]; static uint8_t page_buffer[CONFIG_MAX_FLASH_PAGE_SIZE];
// Page Tracking // Page Tracking

View File

@ -5,6 +5,8 @@
// This file may be distributed under the terms of the GNU GPLv3 license. // This file may be distributed under the terms of the GNU GPLv3 license.
#include "board/io.h" // readb #include "board/io.h" // readb
#include "board/misc.h" // jump_to_application
#include "bootentry.h" // bootentry_check
#include "sched.h" // sched_check_periodic #include "sched.h" // sched_check_periodic
// Note that a task is ready to run // Note that a task is ready to run
@ -24,18 +26,20 @@ sched_check_wake(struct task_wake *w)
return 1; return 1;
} }
// Init followed by main task dispatch loop
void void
sched_run_init(void) sched_main(void)
{ {
if (!bootentry_check())
jump_to_application();
// Run all init functions marked with DECL_INIT() // Run all init functions marked with DECL_INIT()
extern void ctr_run_initfuncs(void); extern void ctr_run_initfuncs(void);
ctr_run_initfuncs(); ctr_run_initfuncs();
}
void for (;;) {
sched_run_tasks(void) // Run all task functions marked with DECL_TASK()
{ extern void ctr_run_taskfuncs(void);
// Run all task functions marked with DECL_TASK() ctr_run_taskfuncs();
extern void ctr_run_taskfuncs(void); }
ctr_run_taskfuncs();
} }

View File

@ -19,8 +19,7 @@ struct task_wake {
// sched.c // sched.c
void sched_wake_task(struct task_wake *w); void sched_wake_task(struct task_wake *w);
uint8_t sched_check_wake(struct task_wake *w); uint8_t sched_check_wake(struct task_wake *w);
void sched_run_init(void); void sched_main(void);
void sched_run_tasks(void);
// Compiler glue for DECL_X macros above. // Compiler glue for DECL_X macros above.
#define _DECL_CALLLIST(NAME, FUNC) \ #define _DECL_CALLLIST(NAME, FUNC) \

View File

@ -7,9 +7,9 @@
#include "autoconf.h" // CONFIG_CLOCK_REF_FREQ #include "autoconf.h" // CONFIG_CLOCK_REF_FREQ
#include "board/armcm_boot.h" // armcm_main #include "board/armcm_boot.h" // armcm_main
#include "board/irq.h" // irq_disable #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 "internal.h" // enable_pclock
#include "canboot_main.h" // sched_main #include "sched.h" // sched_main
#define FREQ_PERIPH 48000000 #define FREQ_PERIPH 48000000
@ -113,5 +113,5 @@ armcm_main(void)
#endif #endif
timer_init(); timer_init();
canboot_main(); sched_main();
} }

View File

@ -8,8 +8,7 @@
#include "board/armcm_boot.h" // VectorTable #include "board/armcm_boot.h" // VectorTable
#include "board/irq.h" // irq_disable #include "board/irq.h" // irq_disable
#include "internal.h" // enable_pclock #include "internal.h" // enable_pclock
#include "board/misc.h" // jump_to_application #include "sched.h" // sched_main
#include "canboot_main.h" // canboot_main
#define FREQ_PERIPH (CONFIG_CLOCK_FREQ / 2) #define FREQ_PERIPH (CONFIG_CLOCK_FREQ / 2)
@ -235,5 +234,5 @@ armcm_main(void)
stm32f1_alternative_remap(AFIO_MAPR_SWJ_CFG_Msk, stm32f1_alternative_remap(AFIO_MAPR_SWJ_CFG_Msk,
AFIO_MAPR_SWJ_CFG_JTAGDISABLE); AFIO_MAPR_SWJ_CFG_JTAGDISABLE);
canboot_main(); sched_main();
} }