stm32f1: Add support for building with bootloader support

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2018-10-04 10:14:16 -04:00
parent 215b4c5a1e
commit 75fa74313c
5 changed files with 167 additions and 9 deletions

View File

@ -209,11 +209,11 @@ avrdude -c stk500v2 -p atmega2560 -P /dev/ttyACM0 -u -Uflash:w:out/klipper.elf.h
STM32F103 micro-controllers (Blue Pill devices)
===============================================
The STM32F103 devices have a ROM that can flash a bootloader via 3.3V
serial. To access this ROM, one should connect the "boot 0" pin to
high and "boot 1" pin to low, and then reset the device. The
"stm32flash" package can then be used to flash the device using
something like:
The STM32F103 devices have a ROM that can flash a bootloader or
application via 3.3V serial. To access this ROM, one should connect
the "boot 0" pin to high and "boot 1" pin to low, and then reset the
device. The "stm32flash" package can then be used to flash the device
using something like:
```
stm32flash -w out/klipper.bin -v -g 0 /dev/ttyAMA0
```
@ -224,8 +224,32 @@ stm32flash protocol uses a serial parity mode which the Raspberry Pi's
https://www.raspberrypi.org/documentation/configuration/uart.md for
details on enabling the full uart on the Raspberry Pi GPIO pins.
This document does not describe the method to flash an application via
an STM32F103 bootloader.
After flashing, set both "boot 0" and "boot 1" back to low so that
future resets boot from flash.
## STM32F103 with stm32duino bootloader ##
The "stm32duino" project has a USB capable bootloader - see:
https://github.com/rogerclarkmelbourne/STM32duino-bootloader
This bootloader can be flashed via 3.3V serial with something like:
```
wget 'https://github.com/rogerclarkmelbourne/STM32duino-bootloader/raw/master/binaries/generic_boot20_pc13.bin'
stm32flash -w generic_boot20_pc13.bin -v -g 0 /dev/ttyAMA0
```
This bootloader uses 8KiB of flash space (the application must be
compiled with a start address of 8KiB). Flash an application with
something like:
```
dfu-util -d 1eaf:0003 -a 2 -R -D out/klipper.bin
```
The bootloader typically runs for only a short period after boot. It
may be necessary to time the above command so that it runs while the
bootloader is still active (the bootloader will flash a board led
while it is running). Alternatively, set the "boot 0" pin to low and
"boot 1" pin to high to stay in the bootloader after a reset.
LPC176x micro-controllers (Smoothieboards)
==========================================

View File

@ -18,6 +18,19 @@ config CLOCK_FREQ
int
default 8000000 # 72000000 / 9
choice
prompt "Bootloader offset"
config STM_FLASH_START_0000
bool "No bootloader"
config STM_FLASH_START_2000
bool "8KiB bootloader (stm32duino)"
endchoice
config FLASH_START
hex
default 0x2000 if STM_FLASH_START_2000
default 0x0000
config USBSERIAL
bool "Use USB for communication (instead of serial)"
default y

View File

@ -13,8 +13,7 @@ CFLAGS += -Ilib/hal-stm32f1/include
CFLAGS += -DSTM32F103xB
CFLAGS += -O3
CFLAGS_klipper.elf += -Llib/cmsis-stm32f1/source/
CFLAGS_klipper.elf += -Tlib/cmsis-stm32f1/source/stm32f1.ld
CFLAGS_klipper.elf += -T $(OUT)stm32f1.ld
CFLAGS_klipper.elf += --specs=nano.specs --specs=nosys.specs
# Add source files
@ -33,6 +32,13 @@ $(OUT)%.o: %.s $(OUT)autoconf.h $(OUT)board-link
$(OUT)klipper.elf: $(patsubst %.s, $(OUT)src/%.o,$(asmsrc-y))
# Build the linker script
target-y := $(OUT)stm32f1.ld $(target-y)
$(OUT)stm32f1.ld: src/stm32f1/stm32f1.ld $(OUT)board-link
@echo " Preprocessing $@"
$(Q)$(CPP) -P -MD -MT $@ -DFLASH_START=$(CONFIG_FLASH_START) $< -o $@
# Binary output file rules
target-y += $(OUT)klipper.bin

View File

@ -135,6 +135,8 @@ int
main(void)
{
SystemInit();
SCB->VTOR += CONFIG_FLASH_START;
LL_Init1msTick(SystemCoreClock);
clock_config();
adc_config();

113
src/stm32f1/stm32f1.ld Normal file
View File

@ -0,0 +1,113 @@
/* Cortex-M linker script
This file is taken from lib/cmsis-stm32f1/source/stm32f1.ld . It
has been modified to support a bootloader offset.
*/
ENTRY(Reset_Handler)
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000 + FLASH_START, LENGTH = 64K - FLASH_START
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
}
/* highest address of the user mode stack */
_estack = 0x20005000;
SECTIONS
{
/* Interrupt vector table */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
} >FLASH
/* Program code and constant data */
.text :
{
. = ALIGN(4);
*(.text)
*(.text*)
*(.rodata)
*(.rodata*)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .;
} >FLASH
/* Exception handling */
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
.ARM : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
/* Static constructor initialization (C++) */
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH
/* Initialized data, needs to be handled by startup code */
_sidata = .;
.data : AT (_sidata)
{
. = ALIGN(4);
_sdata = . ;
_data = . ;
*(.data)
*(.data*)
*(.RAMtext)
. = ALIGN(4);
_edata = . ;
} >RAM
/* Uninitialized data */
.bss (NOLOAD) :
{
. = ALIGN(4);
_sbss = .;
__bss_start__ = .;
_bss = .;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
__bss_end__ = _ebss;
} >RAM
/* Pointers to end of data for dynamic memory management */
PROVIDE (end = _ebss);
PROVIDE (_end = _ebss);
/* Remove debugging from standard libraries */
/DISCARD/ :
{
libc.a (*)
libm.a (*)
libgcc.a (*)
}
}