mirror of
https://github.com/andreili/katapult.git
synced 2025-08-23 19:34:06 +02:00
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:
parent
ed2bf3e8b0
commit
f4ac6470bf
36
Makefile
36
Makefile
@ -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:
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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
100
src/deployer.c
Normal 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
12
src/deployer.h
Normal 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
119
src/generic/armcm_boot.c
Normal 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;
|
||||
}
|
76
src/generic/armcm_deployer.lds.S
Normal file
76
src/generic/armcm_deployer.lds.S
Normal 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
20
src/generic/armcm_reset.c
Normal 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();
|
||||
}
|
@ -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);
|
||||
|
@ -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
|
||||
######################################################################
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user