Commit 1f5cab9e authored by Andrew Leech's avatar Andrew Leech Committed by Damien George

stm32: Add option to put ISR, flash and UART code in RAM.

This allows UART RX to function while flash erase/writes operations are
under way, preventing lost serial data so long as it fits in the UART RX
buffer.

This enables (among other things) mpremote to successfully copy files to
boards that use a UART REPL.

Enable via the following option placed in `mpconfigboard.mk`:

    MICROPY_HW_ENABLE_ISR_UART_FLASH_FUNCS_IN_RAM = 1
Signed-off-by: default avatarAndrew Leech <andrew.leech@planetinnovation.com.au>
parent 35b6a66b
......@@ -143,7 +143,15 @@ CFLAGS += -DMICROPY_FLOAT_IMPL=MICROPY_FLOAT_IMPL_FLOAT
CFLAGS += -fsingle-precision-constant
endif
LDFLAGS += -nostdlib -L $(LD_DIR) $(addprefix -T,$(LD_FILES)) -Wl,-Map=$(@:.elf=.map) -Wl,--cref
# Configure linker include dir for ram/rom isr support
ifeq ($(MICROPY_HW_ENABLE_ISR_UART_FLASH_FUNCS_IN_RAM),1)
CFLAGS += -DMICROPY_HW_ENABLE_ISR_UART_FLASH_FUNCS_IN_RAM=1
LD_ISR_DIR = boards/common_isr_ram
else
LD_ISR_DIR = boards/common_isr_rom
endif
LDFLAGS += -nostdlib -L $(LD_DIR) -L $(LD_ISR_DIR) $(addprefix -T,$(LD_FILES)) -Wl,-Map=$(@:.elf=.map) -Wl,--cref
LDFLAGS += -Wl,--defsym=_estack_reserve=8
LIBS += "$(shell $(CC) $(CFLAGS) -print-libgcc-file-name)"
......@@ -465,7 +473,8 @@ OBJ += $(GEN_PINS_SRC:.c=.o)
# Don't use -O3 with this file because gcc tries to optimise memset in terms of itself.
$(BUILD)/shared/libc/string0.o: COPT += -O2
# We put several files into the first 16K section with the ISRs.
ifneq ($(MICROPY_HW_ENABLE_ISR_UART_FLASH_FUNCS_IN_RAM),1)
# If MBOOT or RAM_IFS is not used we put several files into the first 16K section with the ISRs.
# If we compile these using -O0 then it won't fit. So if you really want these
# to be compiled with -O0, then edit boards/common.ld (in the .isr_vector section)
# and comment out the following lines.
......@@ -474,6 +483,7 @@ $(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os
$(PY_BUILD)/formatfloat.o: COPT += -Os
$(PY_BUILD)/parsenum.o: COPT += -Os
$(PY_BUILD)/mpprint.o: COPT += -Os
endif
all: $(TOP)/lib/stm32lib/README.md all_main $(BUILD)/firmware.hex
......@@ -557,7 +567,7 @@ TEXT0_ADDR ?= 0x08000000
ifeq ($(TEXT1_ADDR),)
# No TEXT1_ADDR given so put all firmware at TEXT0_ADDR location
TEXT0_SECTIONS ?= .isr_vector .text .data .ARM
TEXT0_SECTIONS ?= .isr_vector .isr_extratext .text .data .ARM
deploy-stlink: $(BUILD)/firmware.bin
$(call RUN_STLINK,$^,$(TEXT0_ADDR))
......@@ -574,7 +584,7 @@ $(BUILD)/firmware.dfu: $(BUILD)/firmware.bin
else
# TEXT0_ADDR and TEXT1_ADDR are specified so split firmware between these locations
TEXT0_SECTIONS ?= .isr_vector
TEXT0_SECTIONS ?= .isr_vector .isr_extratext
TEXT1_SECTIONS ?= .text .data .ARM
deploy-stlink: $(BUILD)/firmware0.bin $(BUILD)/firmware1.bin
......
......@@ -19,7 +19,6 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 32K /* sectors 0,1 */
FLASH_APP (rx) : ORIGIN = 0x08008000, LENGTH = 480K /* sectors 2-7 */
FLASH_EXT (rx) : ORIGIN = 0x90000000, LENGTH = 2048K /* external QSPI */
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K /* DTCM+SRAM1+SRAM2 */
......
......@@ -17,7 +17,6 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 32K /* sector 0, 32K */
FLASH_APP (rx) : ORIGIN = 0x08008000, LENGTH = 2016K /* sectors 1-11 3x32K 1*128K 7*256K */
FLASH_EXT (rx) : ORIGIN = 0x90000000, LENGTH = 2048K /* external QSPI */
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 512K /* DTCM=128k, SRAM1=368K, SRAM2=16K */
......
......@@ -40,6 +40,7 @@ _heap_end = _sstack;
ENTRY(Reset_Handler)
REGION_ALIAS("FLASH_ISR", FLASH_APP);
REGION_ALIAS("FLASH_COMMON", FLASH_APP);
SECTIONS
......
......@@ -12,6 +12,7 @@
ENTRY(Reset_Handler)
REGION_ALIAS("FLASH_ISR", FLASH);
REGION_ALIAS("FLASH_COMMON", FLASH);
/* define output sections */
......
......@@ -12,6 +12,7 @@
ENTRY(Reset_Handler)
REGION_ALIAS("FLASH_ISR", FLASH_APP);
REGION_ALIAS("FLASH_COMMON", FLASH_APP);
/* define output sections */
......
......@@ -12,6 +12,7 @@
ENTRY(Reset_Handler)
REGION_ALIAS("FLASH_ISR", FLASH_TEXT);
REGION_ALIAS("FLASH_COMMON", FLASH_TEXT);
/* define output sections */
......
......@@ -13,36 +13,14 @@
ENTRY(Reset_Handler)
REGION_ALIAS("FLASH_ISR", FLASH_START);
REGION_ALIAS("FLASH_COMMON", FLASH_TEXT);
/* define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
/* This first flash block is 16K and the isr vectors only take up
about 400 bytes. So we pull in a couple of object files to pad it
out. */
. = ALIGN(4);
/* NOTE: If you update the list of files contained in .isr_vector,
then be sure to also update smhal/Makefile where it forcibly
builds each of these files with -Os */
*/ff.o(.text*)
*/vfs_fat_*.o(.text*)
*/py/formatfloat.o(.text*)
*/py/parsenum.o(.text*)
*/py/mpprint.o(.text*)
. = ALIGN(4);
} >FLASH_ISR
INCLUDE common_isr.ld
INCLUDE common_isr_extratext.ld
INCLUDE common_text.ld
INCLUDE common_extratext_data_in_flash.ld
INCLUDE common_bss_heap_stack.ld
......
/* This linker script fragment is intended to be included in SECTIONS. */
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
__isr_vector_ram_start = .;
KEEP(*(.isr_vector)) /* Startup code */
/* These functions need to run from ram to enable uart
reception during flash erase/write operations.
Defining them here ensures they're copied from
flash (in main.c) along with the isr_vector above.
*/
. = ALIGN(4);
*(.text.pendsv_kbd_intr)
*(.text.pendsv_schedule_dispatch)
*(.text.storage_systick_callback)
*(.text.SysTick_Handler)
*(.text.uart_irq_handler)
*(.text.UART*_IRQHandler)
*(.text.USART*_IRQHandler)
*(.text.FLASH_PageErase)
*(.text.FLASH_SectorErase)
*(.text.FLASH_WaitForLastOperation)
*(.text.HAL_FLASHEx_Erase)
*(.text.HAL_GetTick)
__isr_vector_ram_end = .;
. = ALIGN(4);
} >RAM AT >FLASH_ISR
/* Used by the start-up code to initialise data */
__isr_vector_flash_addr = LOADADDR(.isr_vector);
......@@ -6,4 +6,4 @@
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH_COMMON
} >FLASH_ISR
/* This linker script fragment is intended to be included in SECTIONS when
common_ifs.ld is used with common_isr.ld
. */
.isr_extratext :
{
. = ALIGN(4);
/* This first flash block is 16K and the isr vectors only take up
about 400 bytes. So we pull in a couple of object files to pad it
out and save flash space in later blocks.
NOTE: If you update the list of files contained here in .isr_extratext
then be sure to also update stm32/Makefile where it builds each of
these files with -Os to keep this section as compact as possible.
*/
*/ff.o(.text*)
*/vfs_fat_*.o(.text*)
*/py/formatfloat.o(.text*)
*/py/parsenum.o(.text*)
*/py/mpprint.o(.text*)
. = ALIGN(4);
} >FLASH_ISR
......@@ -6,7 +6,7 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 384K /* entire flash */
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
FLASH_START (rx): ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 64K /* sectors 1,2,3,4: 16k+16k+16k+16k(of 64k)=64k */
FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 256K /* sectors 5,6 are 128K */
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 80K
......
......@@ -6,7 +6,7 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K /* entire flash */
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
FLASH_START (rx): ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 64K /* sectors 1,2,3,4: 16k+16k+16k+16k(of 64k)=64k */
FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 384K /* sectors 5,6,7 are 128K */
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 80K
......
......@@ -6,7 +6,7 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K /* entire flash */
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
FLASH_START (rx): ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 112K /* sectors 1,2,3,4 are for filesystem */
FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 896K /* sectors 5,6,7,8,9,10,11 */
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
......
......@@ -6,7 +6,7 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K /* entire flash */
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
FLASH_START (rx): ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 64K /* sectors 1,2,3,4: 16k+16k+16k+16k(of 64k)=64k */
FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 384K /* sectors 5,6,7 are 128K */
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 112K
......
......@@ -6,7 +6,7 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K /* entire flash */
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
FLASH_START (rx): ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 64K /* sectors 1,2,3,4: 16k+16k+16k+16k(of 64k)=64k */
FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 896K /* sectors 5,6,7,8,9,10,11 are 128K */
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 240K
......
......@@ -6,7 +6,7 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K /* entire flash */
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
FLASH_START (rx): ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 176K /* sectors 1,2,3 are 16K, 4 is 64K, 5 is 128K (64K used) for filesystem */
FLASH_FS2 (rx) : ORIGIN = 0x08040000, LENGTH = 64K /* sector 6 is 128K (64K used) for filesystem, Total filesystem 240K */
FLASH_TEXT (rx) : ORIGIN = 0x08060000, LENGTH = 640K /* sectors 7,8,9,10,11 are 128K*/
......
......@@ -6,7 +6,7 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1536K /* entire flash */
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
FLASH_START (rx): ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 176K /* sectors 1,2,3 are 16K, 4 is 64K, 5 is 128K (64K used) for filesystem */
FLASH_FS2 (rx) : ORIGIN = 0x08040000, LENGTH = 64K /* sector 6 is 128K (64K used) for filesystem, Total filesystem 240K */
FLASH_TEXT (rx) : ORIGIN = 0x08060000, LENGTH = 1152K /* sectors 7,8,9,10,11,12,13,14,15 are 128K*/
......
......@@ -6,7 +6,7 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K /* entire flash */
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0, 16 KiB */
FLASH_START (rx): ORIGIN = 0x08000000, LENGTH = 16K /* sector 0, 16 KiB */
FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 112K /* sectors 1-4: 3*16K+64K */
FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 896K /* sectors 5-11 are 128K */
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
......
......@@ -6,7 +6,7 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K /* entire flash */
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0, 16 KiB */
FLASH_START (rx): ORIGIN = 0x08000000, LENGTH = 16K /* sector 0, 16 KiB */
FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 112K /* sectors 1-4: 3*16K+64K */
FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 896K /* sectors 5-11 are 128K */
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
......
......@@ -6,7 +6,7 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K /* entire flash */
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
FLASH_START (rx): ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 896K /* sectors 5-11 are 128K */
FLASH_FS (rx) : ORIGIN = 0x08100000, LENGTH = 192K /* sectors 12-15 are 16K, 16 is 64K, 17 is 128K (64K used) */
FLASH_FS2 (rx) : ORIGIN = 0x08140000, LENGTH = 64K /* sector 18 is 128K (64K used) */
......
......@@ -6,7 +6,7 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0, 16K */
FLASH_START (rx): ORIGIN = 0x08000000, LENGTH = 16K /* sector 0, 16K */
FLASH_FS (r) : ORIGIN = 0x08004000, LENGTH = 112K /* sectors 1-4 3*16KiB 1*64KiB*/
FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 384K /* sectors 5-7 3*128KiB = 384K */
DTCM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K /* Used for storage cache */
......
......@@ -6,7 +6,7 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 32K /* sector 0, 32K */
FLASH_START (rx): ORIGIN = 0x08000000, LENGTH = 32K /* sector 0, 32K */
FLASH_FS (r) : ORIGIN = 0x08008000, LENGTH = 96K /* sectors 1, 2, 3 (32K each) */
FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 896K /* sectors 4-7 1*128Kib 3*256KiB = 896K */
DTCM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K /* Used for storage cache */
......
......@@ -6,7 +6,7 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 32K /* sector 0, 32K */
FLASH_START (rx): ORIGIN = 0x08000000, LENGTH = 32K /* sector 0, 32K */
FLASH_APP (rx) : ORIGIN = 0x08008000, LENGTH = 2016K /* sectors 1-11 3x32K 1*128K 7*256K */
FLASH_FS (r) : ORIGIN = 0x08008000, LENGTH = 96K /* sectors 1, 2, 3 (32K each) */
FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 896K /* sectors 4-7 1*128Kib 3*256KiB = 896K */
......
......@@ -6,7 +6,7 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 32K /* sector 0, 32K */
FLASH_START (rx): ORIGIN = 0x08000000, LENGTH = 32K /* sector 0, 32K */
FLASH_FS (r) : ORIGIN = 0x08008000, LENGTH = 96K /* sectors 1, 2, 3 (32K each) */
FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 896K /* sectors 4-7 1*128Kib 3*256KiB = 896K */
DTCM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K /* Used for storage cache */
......
......@@ -6,7 +6,7 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 128K /* sector 0, 128K */
FLASH_START (rx): ORIGIN = 0x08000000, LENGTH = 128K /* sector 0, 128K */
FLASH_FS (r) : ORIGIN = 0x08020000, LENGTH = 128K /* sector 1, 128K */
FLASH_TEXT (rx) : ORIGIN = 0x08040000, LENGTH = 1792K /* sectors 6*128 + 8*128 */
DTCM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K /* Used for storage cache */
......
......@@ -303,10 +303,21 @@ void stm32_main(uint32_t reset_mode) {
// Low-level MCU initialisation.
stm32_system_init();
#if !defined(STM32F0) && defined(MICROPY_HW_VTOR)
#if !defined(STM32F0)
#if MICROPY_HW_ENABLE_ISR_UART_FLASH_FUNCS_IN_RAM
// Copy IRQ vector table to RAM and point VTOR there
extern uint32_t __isr_vector_flash_addr, __isr_vector_ram_start, __isr_vector_ram_end;
size_t __isr_vector_size = (&__isr_vector_ram_end - &__isr_vector_ram_start) * sizeof(uint32_t);
memcpy(&__isr_vector_ram_start, &__isr_vector_flash_addr, __isr_vector_size);
SCB->VTOR = (uint32_t)&__isr_vector_ram_start;
#else
#if defined(MICROPY_HW_VTOR)
// Change IRQ vector table if configured differently
SCB->VTOR = MICROPY_HW_VTOR;
#endif
#endif
#endif
#if __CORTEX_M != 33
// Enable 8-byte stack alignment for IRQ handlers, in accord with EABI
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment