From 74665c05692bcc87600dc6f116c2a6f3a8e03489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Wed, 5 Jun 2019 10:17:05 +0200 Subject: [PATCH] [ion] Fix reset jump address accross platforms --- ion/src/device/n0100/flash.ld | 2 +- ion/src/device/{shared => n0100}/ram.ld | 2 +- ion/src/device/n0100/usb/dfu.ld | 2 +- ion/src/device/n0200/flash.ld | 2 +- ion/src/device/n0200/internal_flash.ld | 2 +- ion/src/device/n0200/ram.ld | 81 +++++++++++++++++++++++++ ion/src/device/n0200/usb/dfu.ld | 2 +- ion/src/device/shared/drivers/reset.cpp | 4 +- ion/test/external_flash_tests.ld | 2 +- scripts/targets.device.mak | 4 +- 10 files changed, 92 insertions(+), 11 deletions(-) rename ion/src/device/{shared => n0100}/ram.ld (98%) create mode 100644 ion/src/device/n0200/ram.ld diff --git a/ion/src/device/n0100/flash.ld b/ion/src/device/n0100/flash.ld index 80f02b63d..048883902 100644 --- a/ion/src/device/n0100/flash.ld +++ b/ion/src/device/n0100/flash.ld @@ -30,7 +30,7 @@ SECTIONS { * We're generating the ISR vector table in code because it's very * convenient: using function pointers, we can easily point to the service * routine for each interrupt. */ - _isr_start = .; + _jump_reset_address = .; KEEP(*(.isr_vector_table)) } >FLASH diff --git a/ion/src/device/shared/ram.ld b/ion/src/device/n0100/ram.ld similarity index 98% rename from ion/src/device/shared/ram.ld rename to ion/src/device/n0100/ram.ld index 5dd3efb6a..c30ad73a1 100644 --- a/ion/src/device/shared/ram.ld +++ b/ion/src/device/n0100/ram.ld @@ -20,10 +20,10 @@ MEMORY { * overwritten (for instance, vtables that live in the .rodata section). */ STACK_SIZE = 32K; +_jump_reset_address = 0x08000000; SECTIONS { .isr_vector_table ORIGIN(RAM_BUFFER) : { - _isr_start = .; KEEP(*(.isr_vector_table)) } >RAM_BUFFER diff --git a/ion/src/device/n0100/usb/dfu.ld b/ion/src/device/n0100/usb/dfu.ld index 739bc3b61..f3a2e67e5 100644 --- a/ion/src/device/n0100/usb/dfu.ld +++ b/ion/src/device/n0100/usb/dfu.ld @@ -27,7 +27,7 @@ MEMORY { /* The DFU needs to know to which address it should jump to after a leave * command. This address is used in Ion::Device::Reset::jump(). */ -_isr_start = 0x08000000; +_jump_reset_address = 0x08000000; SECTIONS { .text : { diff --git a/ion/src/device/n0200/flash.ld b/ion/src/device/n0200/flash.ld index eebbc0946..95a982755 100644 --- a/ion/src/device/n0200/flash.ld +++ b/ion/src/device/n0200/flash.ld @@ -38,7 +38,7 @@ SECTIONS { * We're generating the ISR vector table in code because it's very * convenient: using function pointers, we can easily point to the service * routine for each interrupt. */ - _isr_start = .; + _jump_reset_address = .; KEEP(*(.isr_vector_table)) } >INTERNAL_FLASH diff --git a/ion/src/device/n0200/internal_flash.ld b/ion/src/device/n0200/internal_flash.ld index b205549af..110b4b599 100644 --- a/ion/src/device/n0200/internal_flash.ld +++ b/ion/src/device/n0200/internal_flash.ld @@ -22,7 +22,7 @@ SECTIONS { * We're generating the ISR vector table in code because it's very * convenient: using function pointers, we can easily point to the service * routine for each interrupt. */ - _isr_start = .; + _jump_reset_address = .; KEEP(*(.isr_vector_table)) } >INTERNAL_FLASH diff --git a/ion/src/device/n0200/ram.ld b/ion/src/device/n0200/ram.ld new file mode 100644 index 000000000..8ec6b0a24 --- /dev/null +++ b/ion/src/device/n0200/ram.ld @@ -0,0 +1,81 @@ +/* Create a firmware that runs from RAM. + * Caution: ST's bootloader uses some RAM, so we want to stay off of that memory + * region. Per AN2606, sections 31.1 and 36.1, it's using 16Kbytes form address + * 0x20000000. We'll try to play safe and avoid the first 32KB of RAM. + * + * This is used to: + * - Flash faster. Flashing using ST's ROMed DFU bootloader is reliable but + * very slow. To make flashing faster, we can leverage ST's bootloader to copy + * a small "flasher" in RAM, and run it from there. + * - Run the bench software from the RAM. */ + +MEMORY { + RAM_BUFFER (rw) : ORIGIN = 0x20000000 + 32K, LENGTH = 256K - 32K +} + +/* The stack is quite large: we put it equal to Epsilon's. + * Indeed, when building the flasher, we're making the USB::Calculator object + * live on the stack, and it's quite large (about 4K just for this single + * object). Using a stack too small would result in some memory being + * overwritten (for instance, vtables that live in the .rodata section). */ + +STACK_SIZE = 32K; +_jump_reset_address = 0x00200000; + +SECTIONS { + .isr_vector_table ORIGIN(RAM_BUFFER) : { + KEEP(*(.isr_vector_table)) + } >RAM_BUFFER + + .text : { + . = ALIGN(4); + *(.text) + *(.text.*) + } >RAM_BUFFER + + .init_array : { + . = ALIGN(4); + _init_array_start = .; + KEEP (*(.init_array*)) + _init_array_end = .; + } >RAM_BUFFER + + .rodata : { + . = ALIGN(4); + *(.rodata) + *(.rodata.*) + } >RAM_BUFFER + + .data : { + . = ALIGN(4); + *(.data) + *(.data.*) + } >RAM_BUFFER + + .bss : { + . = ALIGN(4); + _bss_section_start_ram = .; + *(.bss) + *(.bss.*) + *(COMMON) + _bss_section_end_ram = .; + } >RAM_BUFFER + + .stack : { + . = ALIGN(8); + _stack_end = .; + . += (STACK_SIZE - 8); + . = ALIGN(8); + _stack_start = .; + } >RAM_BUFFER + + .phony : { + /* We won't do dynamic memory allocation */ + _heap_start = .; + _heap_end = .; + /* Effectively bypass copying .data to RAM */ + _data_section_start_flash = .; + _data_section_start_ram = .; + _data_section_end_ram = .; + } >RAM_BUFFER +} diff --git a/ion/src/device/n0200/usb/dfu.ld b/ion/src/device/n0200/usb/dfu.ld index be93ac8e0..ba7d420c2 100644 --- a/ion/src/device/n0200/usb/dfu.ld +++ b/ion/src/device/n0200/usb/dfu.ld @@ -27,7 +27,7 @@ MEMORY { /* The DFU needs to know to which address it should jump to after a leave * command. This address is used in Ion::Device::Reset::jump(). */ -_isr_start = 0x00200000; +_jump_reset_address = 0x00200000; SECTIONS { .text : { diff --git a/ion/src/device/shared/drivers/reset.cpp b/ion/src/device/shared/drivers/reset.cpp index 9c65073b1..48e4ff399 100644 --- a/ion/src/device/shared/drivers/reset.cpp +++ b/ion/src/device/shared/drivers/reset.cpp @@ -4,7 +4,7 @@ #include #include -extern void * _isr_start; +extern void * _jump_reset_address; namespace Ion { namespace Device { @@ -30,7 +30,7 @@ void jump() { * real reset would. These operations should be made at once, otherwise the C * compiler might emit some instructions that modify the stack inbetween. */ - uint32_t * stackPointerAddress = reinterpret_cast(&_isr_start); + uint32_t * stackPointerAddress = reinterpret_cast(&_jump_reset_address); uint32_t * resetHandlerAddress = stackPointerAddress + 1; asm volatile ( diff --git a/ion/test/external_flash_tests.ld b/ion/test/external_flash_tests.ld index 603ab6f15..34003f5e3 100644 --- a/ion/test/external_flash_tests.ld +++ b/ion/test/external_flash_tests.ld @@ -31,7 +31,7 @@ SECTIONS { * We're generating the ISR vector table in code because it's very * convenient: using function pointers, we can easily point to the service * routine for each interrupt. */ - _isr_start = .; + _jump_reset_address = .; KEEP(*(.isr_vector_table)) } >INTERNAL_FLASH diff --git a/scripts/targets.device.mak b/scripts/targets.device.mak index f13b9fb49..a8c607312 100644 --- a/scripts/targets.device.mak +++ b/scripts/targets.device.mak @@ -54,7 +54,7 @@ openocd: # fully filled ifeq ($(EPSILON_USB_DFU_XIP)$(EPSILON_DEVICE_BENCH),10) $(BUILD_DIR)/ion/src/$(PLATFORM)/shared/usb/flasher.o: SFLAGS += $(ION_DEVICE_SFLAGS) -$(BUILD_DIR)/flasher.$(EXE): LDSCRIPT = ion/src/$(PLATFORM)/shared/ram.ld +$(BUILD_DIR)/flasher.$(EXE): LDSCRIPT = ion/src/$(PLATFORM)/$(MODEL)/ram.ld $(BUILD_DIR)/flasher.$(EXE): $(objs) $(BUILD_DIR)/ion/src/$(PLATFORM)/shared/usb/flasher.o else $(BUILD_DIR)/flasher.$(EXE): @@ -63,7 +63,7 @@ endif #TODO Do not build all apps... Put elsewhere? ifeq ($(EPSILON_USB_DFU_XIP)$(EPSILON_DEVICE_BENCH),11) -$(BUILD_DIR)/benchRAM.$(EXE): LDSCRIPT = ion/src/$(PLATFORM)/shared/ram.ld +$(BUILD_DIR)/benchRAM.$(EXE): LDSCRIPT = ion/src/$(PLATFORM)/$(MODEL)/ram.ld $(BUILD_DIR)/benchRAM.$(EXE): $(objs) $(call object_for,$(bench_src)) else $(BUILD_DIR)/benchRAM.$(EXE):