deployer: Add support for a CanBoot "deployer"

Support building a "flashing application" that one may run from an
existing bootloader.  This flashing application will then flash the
main CanBoot binary to the start of flash.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2022-07-27 21:54:47 -04:00 committed by Eric Callahan
parent ed2bf3e8b0
commit f4ac6470bf
16 changed files with 505 additions and 41 deletions

View File

@ -23,6 +23,7 @@ PYTHON=python3
# Source files
src-y =
deployer-y =
dirs-y = src
# Default compiler flags
@ -38,10 +39,16 @@ OBJS_canboot.elf = $(patsubst %.c, $(OUT)src/%.o,$(src-y))
OBJS_canboot.elf += $(OUT)compile_time_request.o
CFLAGS_canboot.elf = $(CFLAGS) -Wl,--gc-sections
OBJS_deployer.elf = $(patsubst %.c, $(OUT)src/%.o,$(deployer-y))
OBJS_deployer.elf += $(OUT)deployer_ctr.o $(OUT)canboot_payload.o
CFLAGS_deployer.elf = $(CFLAGS) -Wl,--gc-sections
BUILDBINARY_FLAGS =
CPPFLAGS = -I$(OUT) -P -MD -MT $@
# Default targets
target-y := $(OUT)canboot.elf
target-y := $(OUT)canboot.elf $(OUT)canboot.bin
all:
@ -72,6 +79,27 @@ $(OUT)canboot.elf: $(OBJS_canboot.elf)
$(Q)$(CC) $(OBJS_canboot.elf) $(CFLAGS_canboot.elf) -o $@
$(Q)scripts/check-gcc.sh $@ $(OUT)compile_time_request.o
$(OUT)canboot.bin: $(OUT)canboot.elf ./scripts/buildbinary.py
@echo " Creating hex file $@"
$(Q)$(OBJCOPY) -O binary $< $(OUT)canboot.work
$(Q)$(PYTHON) ./scripts/buildbinary.py -b $(CONFIG_FLASH_START) -s $(CONFIG_APPLICATION_START) $(BUILDBINARY_FLAGS) $(OUT)canboot.work -c $(OUT)canboot_payload.c $@
$(OUT)canboot_payload.o: $(OUT)canboot.bin
@echo " Compiling $@"
$(Q)$(CC) $(CFLAGS) -c $(OUT)canboot_payload.c -o $@
################ CanBoot "deployer" build rules
target-$(CONFIG_BUILD_DEPLOYER) += $(OUT)deployer.elf $(OUT)deployer.bin
$(OUT)deployer.elf: $(OBJS_deployer.elf) $(OUT)canboot.bin
@echo " Linking $@"
$(Q)$(CC) $(OBJS_deployer.elf) $(CFLAGS_deployer.elf) -o $@
$(OUT)deployer.bin: $(OUT)deployer.elf
@echo " Creating hex file $@"
$(Q)$(OBJCOPY) -O binary $< $@
################ Compile time requests
$(OUT)%.o.ctr: $(OUT)%.o
@ -83,6 +111,12 @@ $(OUT)compile_time_request.o: $(patsubst %.c, $(OUT)src/%.o.ctr,$(src-y)) ./scri
$(Q)$(PYTHON) ./scripts/buildcommands.py $(OUT)compile_time_request.txt $(OUT)compile_time_request.c
$(Q)$(CC) $(CFLAGS) -c $(OUT)compile_time_request.c -o $@
$(OUT)deployer_ctr.o: $(patsubst %.c, $(OUT)src/%.o.ctr,$(deployer-y)) ./scripts/buildcommands.py
@echo " Building $@"
$(Q)cat $(patsubst %.c, $(OUT)src/%.o.ctr,$(deployer-y)) | tr -s '\0' '\n' > $(OUT)deployer_ctr.txt
$(Q)$(PYTHON) ./scripts/buildcommands.py $(OUT)deployer_ctr.txt $(OUT)deployer_ctr.c
$(Q)$(CC) $(CFLAGS) -c $(OUT)deployer_ctr.c -o $@
################ Auto generation of "board/" include file link
create-board-link:

View File

@ -13,6 +13,29 @@ Rerun "make menuconfig" and either increase the APPLICATION_START or
disable features to reduce the final binary size.
"""
C_TEMPLATE = """
/* DO NOT EDIT! This is an autogenerated file. See scripts/buildbinary.py. */
#include <stdint.h>
#include "deployer.h"
const uint8_t deployer_canboot_binary[] = {
%s
};
const uint32_t deployer_canboot_binary_size = %d;
"""
def format_c_code(data):
ldata = len(data)
data = data + (b"\xff" * (8 - (ldata % 8)))
vals = [" "]
for i, d in enumerate(data):
vals.append("0x%02x," % (d,))
if i % 14 == 13:
vals.append("\n ")
return C_TEMPLATE % ("".join(vals), ldata)
def update_lpc176x_checksum(data):
data28 = data[:28]
words = struct.unpack('<IIIIIII', data28)
@ -25,6 +48,7 @@ def main():
parser.add_argument("-s", "--start", help="Address of application start")
parser.add_argument("-l", "--lpc176x", action='store_true',
help="Perform lpc176x checksum")
parser.add_argument("-c", "--code", help="C code file containing binary")
parser.add_argument("input_file", help="Raw binary filename")
parser.add_argument("output_file", help="Final binary filename")
args = parser.parse_args()
@ -45,6 +69,11 @@ def main():
if args.lpc176x:
data = update_lpc176x_checksum(data)
if args.code:
f = open(args.code, 'w')
f.write(format_c_code(data))
f.close()
f = open(args.output_file, 'wb')
f.write(data)
f.close()

View File

@ -99,6 +99,11 @@ config STATUS_LED_PIN
string "Status LED GPIO Pin"
depends on ENABLE_LED
config BUILD_DEPLOYER
bool
default y if DEPLOYER_START != 0
default n
# The HAVE_x options allow boards to disable support for some commands
# if the hardware does not support the feature.
config HAVE_CHIPID

View File

@ -2,3 +2,5 @@
src-y += sched.c bootentry.c command.c flashcmd.c initial_pins.c
src-$(CONFIG_ENABLE_LED) += led.c
deployer-y += deployer.c

100
src/deployer.c Normal file
View File

@ -0,0 +1,100 @@
// Main code for canboot deployer application
//
// Copyright (C) 2016-2022 Kevin O'Connor <kevin@koconnor.net>
//
// This file may be distributed under the terms of the GNU GPLv3 license.
#include <string.h> // memcmp
#include "autoconf.h" // CONFIG_BLOCK_SIZE
#include "board/flash.h" // flash_write_block
#include "board/io.h" // readb
#include "board/misc.h" // try_request_canboot
#include "deployer.h" // deployer_is_active
#include "sched.h" // sched_check_periodic
// The CanBoot "deployer application" is running
int
deployer_is_active(void)
{
return 1;
}
// Implement simple delay mechanism
void
udelay(uint32_t usecs)
{
uint32_t end = timer_read_time() + timer_from_us(usecs);
while (timer_is_before(timer_read_time(), end))
;
}
// Wrapper for Klipper compatibility
void
sched_wake_tasks(void)
{
}
// Note that a task is ready to run
void
sched_wake_task(struct task_wake *w)
{
writeb(&w->wake, 1);
}
// Check if a task is ready to run (as indicated by sched_wake_task)
uint8_t
sched_check_wake(struct task_wake *w)
{
if (!readb(&w->wake))
return 0;
writeb(&w->wake, 0);
return 1;
}
// Halt the processor
static void
halt(void)
{
for (;;)
;
}
// Init followed by CanBoot flashing
void
sched_main(void)
{
timer_setup();
// Run all init functions marked with DECL_INIT()
extern void ctr_run_initfuncs(void);
ctr_run_initfuncs();
// Check if flash has already been written
void *fstart = (void*)CONFIG_FLASH_START;
uint32_t cbsize = deployer_canboot_binary_size;
if (memcmp(fstart, deployer_canboot_binary, cbsize) == 0) {
try_request_canboot();
halt();
}
// Write CanBoot to flash
const uint8_t *p = deployer_canboot_binary, *end = &p[cbsize];
while (p < end) {
uint32_t data[CONFIG_BLOCK_SIZE / 4];
memset(data, 0xff, sizeof(data));
uint32_t c = CONFIG_BLOCK_SIZE;
if (p + c > end)
c = end - p;
memcpy(data, p, c);
int ret = flash_write_block((uint32_t)fstart, data);
if (ret < 0)
// An error occurred - halt to try avoiding endless boot loops
halt();
p += c;
fstart += c;
}
flash_complete();
// Flash completed - reboot into canboot
try_request_canboot();
}

12
src/deployer.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef __DEPLOYER_H
#define __DEPLOYER_H
#include <stdint.h> // uint8_t
int deployer_is_active(void);
// Code in out/canboot_payload.c generated by scripts/buildbinary.py
extern const uint8_t deployer_canboot_binary[];
extern const uint32_t deployer_canboot_binary_size;
#endif // deployer.h

119
src/generic/armcm_boot.c Normal file
View File

@ -0,0 +1,119 @@
// ARM Cortex-M vector table and initial bootup handling
//
// Copyright (C) 2019 Kevin O'Connor <kevin@koconnor.net>
//
// This file may be distributed under the terms of the GNU GPLv3 license.
#include "armcm_boot.h" // DECL_ARMCM_IRQ
#include "autoconf.h" // CONFIG_MCU
#include "board/internal.h" // SysTick
#include "command.h" // DECL_CONSTANT_STR
#include "misc.h" // dynmem_start
// Export MCU type
DECL_CONSTANT_STR("MCU", CONFIG_MCU);
// Symbols created by armcm_link.lds.S linker script
extern uint32_t _data_start, _data_end, _data_flash;
extern uint32_t _bss_start, _bss_end, _stack_start;
extern uint32_t _stack_end;
/****************************************************************
* Basic interrupt handlers
****************************************************************/
static void __noreturn
reset_handler_stage_two(void)
{
int i;
// Clear all enabled user interrupts and user pending interrupts
for (i = 0; i < ARRAY_SIZE(NVIC->ICER); i++) {
NVIC->ICER[i] = 0xFFFFFFFF;
__DSB();
NVIC->ICPR[i] = 0xFFFFFFFF;
}
// Reset all user interrupt priorities
for (i = 0; i < ARRAY_SIZE(NVIC->IP); i++)
NVIC->IP[i] = 0;
// Disable SysTick interrupt
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk;
__DSB();
// Clear pending pendsv and systick interrupts
SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk | SCB_ICSR_PENDSTCLR_Msk;
// Reset all system interrupt priorities
#if __CORTEX_M >= 7
for (i = 0; i < ARRAY_SIZE(SCB->SHPR); i++)
SCB->SHPR[i] = 0;
#else
for (i = 0; i < ARRAY_SIZE(SCB->SHP); i++)
SCB->SHP[i] = 0;
#endif
__DSB();
__ISB();
__enable_irq();
// Copy global variables from flash to ram
uint32_t count = (&_data_end - &_data_start) * 4;
__builtin_memcpy(&_data_start, &_data_flash, count);
// Clear the bss segment
__builtin_memset(&_bss_start, 0, (&_bss_end - &_bss_start) * 4);
barrier();
// Initializing the C library isn't needed...
//__libc_init_array();
// Run the main board specific code
armcm_main();
// The armcm_main() call should not return
for (;;)
;
}
// Initial code entry point - invoked by the processor after a reset
// Reset interrupts and stack to take control from bootloaders
void
ResetHandler(void)
{
__disable_irq();
// Explicitly load the stack pointer, jump to stage two
asm volatile("mov sp, %0\n bx %1"
: : "r"(&_stack_end), "r"(reset_handler_stage_two));
}
DECL_ARMCM_IRQ(ResetHandler, -15);
// Code called for any undefined interrupts
void
DefaultHandler(void)
{
for (;;)
;
}
/****************************************************************
* Dynamic memory range
****************************************************************/
// Return the start of memory available for dynamic allocations
void *
dynmem_start(void)
{
return &_bss_end;
}
// Return the end of memory available for dynamic allocations
void *
dynmem_end(void)
{
return &_stack_start;
}

View File

@ -0,0 +1,76 @@
// CanBoot "deployer" ARM Cortex-M linker script
//
// Copyright (C) 2019-2022 Kevin O'Connor <kevin@koconnor.net>
//
// This file may be distributed under the terms of the GNU GPLv3 license.
#include "autoconf.h" // CONFIG_FLASH_START
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
MEMORY
{
rom (rx) : ORIGIN = CONFIG_DEPLOYER_START , LENGTH = CONFIG_FLASH_SIZE
ram (rwx) : ORIGIN = CONFIG_RAM_START , LENGTH = CONFIG_RAM_SIZE
}
SECTIONS
{
.text : {
. = ALIGN(4);
_text_vectortable_start = .;
KEEP(*(.vector_table))
_text_vectortable_end = .;
#if CONFIG_APPLICATION_START > CONFIG_DEPLOYER_START
. = CONFIG_APPLICATION_START - CONFIG_DEPLOYER_START ;
#endif
*(.text .text.*)
*(.rodata .rodata*)
} > rom
. = ALIGN(4);
_data_flash = .;
#if CONFIG_ARMCM_RAM_VECTORTABLE
.ram_vectortable (NOLOAD) : {
_ram_vectortable_start = .;
. = . + ( _text_vectortable_end - _text_vectortable_start ) ;
_ram_vectortable_end = .;
} > ram
#endif
.data : AT (_data_flash)
{
. = ALIGN(4);
_data_start = .;
*(.ramfunc .ramfunc.*);
*(.data .data.*);
. = ALIGN(4);
_data_end = .;
} > ram
.bss (NOLOAD) :
{
. = ALIGN(4);
_bss_start = .;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
_bss_end = .;
} > ram
_stack_start = CONFIG_RAM_START + CONFIG_RAM_SIZE - CONFIG_STACK_SIZE ;
.stack _stack_start (NOLOAD) :
{
. = . + CONFIG_STACK_SIZE;
_stack_end = .;
} > ram
/DISCARD/ : {
// The .init/.fini sections are used by __libc_init_array(), but
// that isn't needed so no need to include them in the binary.
*(.init)
*(.fini)
}
}

20
src/generic/armcm_reset.c Normal file
View File

@ -0,0 +1,20 @@
// Generic reset command handler for ARM Cortex-M boards
//
// Copyright (C) 2019 Kevin O'Connor <kevin@koconnor.net>
//
// This file may be distributed under the terms of the GNU GPLv3 license.
#include "autoconf.h" // CONFIG_FLASH_START
#include "board/internal.h" // NVIC_SystemReset
#include "board/irq.h" // irq_disable
#include "board/misc.h" // try_request_canboot
void
try_request_canboot(void)
{
uint32_t *bl_vectors = (uint32_t *)(CONFIG_FLASH_START & 0xFF000000);
uint64_t *req_sig = (uint64_t *)bl_vectors[0];
irq_disable();
*req_sig = REQUEST_CANBOOT;
NVIC_SystemReset();
}

View File

@ -18,6 +18,8 @@ void application_read_flash(uint32_t address, uint32_t *dest);
int application_check_valid(void);
void application_jump(void);
void try_request_canboot(void);
void timer_setup(void);
uint32_t timer_from_us(uint32_t us);

View File

@ -57,6 +57,28 @@ config FLASH_START
hex
default 0x0000
######################################################################
# Bootloader
######################################################################
choice
prompt "Build CanBoot deployment application"
config LPC176X_FLASH_START_0000
bool "Do not build"
config LPC176X_FLASH_START_4000
bool "16KiB bootloader"
endchoice
config DEPLOYER_START
hex
default 0x4000 if LPC176X_FLASH_START_4000
default 0
######################################################################
# Communication inteface
######################################################################
choice
prompt "Communication interface"
config LPC_USB
@ -70,6 +92,7 @@ choice
select SERIAL
endchoice
######################################################################
# Flash settings
######################################################################

View File

@ -6,26 +6,26 @@ CROSS_PREFIX=arm-none-eabi-
dirs-y += src/lpc176x src/generic lib/lpc176x/device
CFLAGS += -mthumb -mcpu=cortex-m3 -Ilib/lpc176x/device -Ilib/cmsis-core
CFLAGS += -Wno-nonnull
CFLAGS_canboot.elf += --specs=nano.specs --specs=nosys.specs
CFLAGS_canboot.elf += -T $(OUT)src/generic/armcm_link.ld
$(OUT)canboot.elf: $(OUT)src/generic/armcm_link.ld
# Add source files
src-y += lpc176x/main.c lpc176x/gpio.c lpc176x/flash.c
src-y += generic/armcm_canboot.c generic/armcm_irq.c
src-y += generic/armcm_timer.c generic/crc16_ccitt.c
src-y += ../lib/lpc176x/device/system_LPC17xx.c
mcu-y = lpc176x/main.c lpc176x/gpio.c lpc176x/flash.c
mcu-y += generic/armcm_irq.c generic/armcm_timer.c generic/crc16_ccitt.c
mcu-y += ../lib/lpc176x/device/system_LPC17xx.c
src-y += generic/armcm_canboot.c $(mcu-y)
src-$(CONFIG_USBSERIAL) += lpc176x/usbserial.c lpc176x/chipid.c
src-$(CONFIG_USBSERIAL) += generic/usb_cdc.c
src-$(CONFIG_SERIAL) += lpc176x/serial.c generic/serial_irq.c
BUILDBINARY_FLAGS = -l
# Build the additional bin output file
target-y += $(OUT)canboot.bin
$(OUT)canboot.bin: $(OUT)canboot.elf ./scripts/buildbinary.py
@echo " Creating hex file $@"
$(Q)$(OBJCOPY) -O binary $< $(OUT)canboot.work
$(Q)$(PYTHON) ./scripts/buildbinary.py -b $(CONFIG_FLASH_START) -s $(CONFIG_APPLICATION_START) -l $(OUT)canboot.work $@
# Deployer build
deployer-y += generic/armcm_boot.c generic/armcm_reset.c $(mcu-y)
CFLAGS_deployer.elf += --specs=nano.specs --specs=nosys.specs
CFLAGS_deployer.elf += -T $(OUT)src/generic/armcm_deployer.ld
$(OUT)deployer.elf: $(OUT)src/generic/armcm_deployer.ld

View File

@ -7,8 +7,16 @@
#include "board/io.h" // readb
#include "board/misc.h" // jump_to_application
#include "bootentry.h" // bootentry_check
#include "deployer.h" // deployer_is_active
#include "sched.h" // sched_check_periodic
// The main CanBoot code is running (not the deployer application)
int
deployer_is_active(void)
{
return 0;
}
// Implement simple delay mechanism
void
udelay(uint32_t usecs)

View File

@ -138,6 +138,10 @@ config CLOCK_FREQ
default 64000000 if MACH_STM32G0
default 400000000 if MACH_STM32H7 # 400Mhz is max Klipper currently supports
config FLASH_START
hex
default 0x8000000
config FLASH_SIZE
hex
default 0x4000 if MACH_STM32F031
@ -189,7 +193,9 @@ config STM32F103GD_DISABLE_SWD
######################################################################
choice
prompt "Bootloader offset" if 0
prompt "Build CanBoot deployment application"
config STM32_FLASH_START_0000
bool "Do not build"
config STM32_FLASH_START_2000
bool "8KiB bootloader" if MACH_STM32F103 || MACH_STM32F070 || MACH_STM32G0 || MACH_STM32F0x2
config STM32_FLASH_START_5000
@ -209,21 +215,32 @@ choice
config STM32_FLASH_START_800
bool "2KiB bootloader (HID Bootloader)" if MACH_STM32F103
config STM32_FLASH_START_1000
bool "4KiB bootloader" if MACH_STM32F1 || MACH_STM32F0
config STM32_FLASH_START_4000
bool "16KiB bootloader (HID Bootloader)" if MACH_STM32F207 || MACH_STM32F401 || MACH_STM32F4x5 || MACH_STM32F103 || MACH_STM32F072
config STM32_FLASH_START_20000
bool "128KiB bootloader (SKR SE BX v2.0)" if MACH_STM32H743
config STM32_FLASH_START_0000
bool "No bootloader"
endchoice
config FLASH_START
config DEPLOYER_START
hex
default 0x8000000
default 0x8000800 if STM32_FLASH_START_800
default 0x8001000 if STM32_FLASH_START_1000
default 0x8002000 if STM32_FLASH_START_2000
default 0x8004000 if STM32_FLASH_START_4000
default 0x8005000 if STM32_FLASH_START_5000
default 0x8007000 if STM32_FLASH_START_7000
default 0x8008000 if STM32_FLASH_START_8000
default 0x8008800 if STM32_FLASH_START_8800
default 0x800C000 if STM32_FLASH_START_C000
default 0x8010000 if STM32_FLASH_START_10000
default 0x8020000 if STM32_FLASH_START_20000
default 0x8020200 if STM32_FLASH_START_20200
default 0
config ARMCM_RAM_VECTORTABLE
bool
default y if MACH_STM32F0 && FLASH_START != 0x8000000
default y if MACH_STM32F0 && DEPLOYER_START != 0
default n

View File

@ -25,26 +25,27 @@ CFLAGS_canboot.elf += -T $(OUT)src/generic/armcm_link.ld
$(OUT)canboot.elf: $(OUT)src/generic/armcm_link.ld
# Add source files
src-y += stm32/gpio.c stm32/flash.c stm32/clockline.c
src-y += generic/armcm_canboot.c generic/armcm_irq.c generic/crc16_ccitt.c
src-$(CONFIG_MACH_STM32F0) += ../lib/stm32f0/system_stm32f0xx.c
src-$(CONFIG_MACH_STM32F0) += stm32/stm32f0.c stm32/stm32f0_timer.c
src-$(CONFIG_MACH_STM32F0) += stm32/gpioperiph.c
mcu-y = stm32/gpio.c stm32/flash.c stm32/clockline.c
mcu-y += generic/armcm_irq.c generic/crc16_ccitt.c
mcu-$(CONFIG_MACH_STM32F0) += ../lib/stm32f0/system_stm32f0xx.c
mcu-$(CONFIG_MACH_STM32F0) += stm32/stm32f0.c stm32/stm32f0_timer.c
mcu-$(CONFIG_MACH_STM32F0) += stm32/gpioperiph.c
src-$(CONFIG_MACH_STM32F1) += ../lib/stm32f1/system_stm32f1xx.c
src-$(CONFIG_MACH_STM32F1) += stm32/stm32f1.c generic/armcm_timer.c
mcu-$(CONFIG_MACH_STM32F1) += ../lib/stm32f1/system_stm32f1xx.c
mcu-$(CONFIG_MACH_STM32F1) += stm32/stm32f1.c generic/armcm_timer.c
src-$(CONFIG_MACH_STM32F2) += ../lib/stm32f2/system_stm32f2xx.c
src-$(CONFIG_MACH_STM32F2) += stm32/stm32f4.c generic/armcm_timer.c
src-$(CONFIG_MACH_STM32F2) += stm32/gpioperiph.c
mcu-$(CONFIG_MACH_STM32F2) += ../lib/stm32f2/system_stm32f2xx.c
mcu-$(CONFIG_MACH_STM32F2) += stm32/stm32f4.c generic/armcm_timer.c
mcu-$(CONFIG_MACH_STM32F2) += stm32/gpioperiph.c
src-$(CONFIG_MACH_STM32F4) += ../lib/stm32f4/system_stm32f4xx.c
src-$(CONFIG_MACH_STM32F4) += stm32/stm32f4.c generic/armcm_timer.c
src-$(CONFIG_MACH_STM32F4) += stm32/gpioperiph.c
mcu-$(CONFIG_MACH_STM32F4) += ../lib/stm32f4/system_stm32f4xx.c
mcu-$(CONFIG_MACH_STM32F4) += stm32/stm32f4.c generic/armcm_timer.c
mcu-$(CONFIG_MACH_STM32F4) += stm32/gpioperiph.c
src-$(CONFIG_MACH_STM32G0) += stm32/stm32f0_timer.c
src-$(CONFIG_MACH_STM32G0) += stm32/stm32g0.c stm32/gpioperiph.c
mcu-$(CONFIG_MACH_STM32G0) += stm32/stm32f0_timer.c
mcu-$(CONFIG_MACH_STM32G0) += stm32/stm32g0.c stm32/gpioperiph.c
src-y += generic/armcm_canboot.c $(mcu-y)
usb-src-$(CONFIG_HAVE_STM32_USBFS) := stm32/usbfs.c
usb-src-$(CONFIG_HAVE_STM32_USBOTG) := stm32/usbotg.c
src-$(CONFIG_USBSERIAL) += $(usb-src-y) stm32/chipid.c generic/usb_cdc.c
@ -58,10 +59,8 @@ canbus-src-$(CONFIG_HAVE_STM32_CANBUS) += stm32/can.c
canbus-src-$(CONFIG_HAVE_STM32_FDCANBUS) += stm32/fdcan.c
src-$(CONFIG_CANSERIAL) += $(canbus-src-y) generic/canbus.c stm32/chipid.c
# Binary output file rules
target-y += $(OUT)canboot.bin
$(OUT)canboot.bin: $(OUT)canboot.elf ./scripts/buildbinary.py
@echo " Creating hex file $@"
$(Q)$(OBJCOPY) -O binary $< $(OUT)canboot.work
$(Q)$(PYTHON) ./scripts/buildbinary.py -b $(CONFIG_FLASH_START) -s $(CONFIG_APPLICATION_START) $(OUT)canboot.work $@
# Deployer build
deployer-y += generic/armcm_boot.c generic/armcm_reset.c $(mcu-y)
CFLAGS_deployer.elf += --specs=nano.specs --specs=nosys.specs
CFLAGS_deployer.elf += -T $(OUT)src/generic/armcm_deployer.ld
$(OUT)deployer.elf: $(OUT)src/generic/armcm_deployer.ld

View File

@ -8,6 +8,7 @@
#include "board/armcm_boot.h" // armcm_main
#include "board/irq.h" // irq_disable
#include "command.h" // DECL_CONSTANT_STR
#include "deployer.h" // deployer_is_active
#include "internal.h" // enable_pclock
#include "sched.h" // sched_main
@ -131,6 +132,21 @@ hsi14_setup(void)
* Startup
****************************************************************/
// Copy vector table and remap ram so new vector table is used
static void
enable_ram_vectortable(void)
{
// Symbols created by armcm_link.lds.S linker script
extern uint32_t _ram_vectortable_start, _ram_vectortable_end;
extern uint32_t _text_vectortable_start;
uint32_t count = (&_ram_vectortable_end - &_ram_vectortable_start) * 4;
__builtin_memcpy(&_ram_vectortable_start, &_text_vectortable_start, count);
barrier();
SYSCFG->CFGR1 |= 3 << SYSCFG_CFGR1_MEM_MODE_Pos;
}
// Main entry point - called from armcm_boot.c:ResetHandler()
void
armcm_main(void)
@ -138,6 +154,8 @@ armcm_main(void)
SystemInit();
enable_pclock(SYSCFG_BASE);
if (CONFIG_ARMCM_RAM_VECTORTABLE && deployer_is_active())
enable_ram_vectortable();
// Set flash latency
FLASH->ACR = (1 << FLASH_ACR_LATENCY_Pos) | FLASH_ACR_PRFTBE;