Skip to content

Commit 45fb650

Browse files
committed
[stm32] Add vector table remap to SRAM for Cortex-M0 STM32 devices
1 parent d46c09d commit 45fb650

File tree

6 files changed

+147
-1
lines changed

6 files changed

+147
-1
lines changed

src/modm/platform/core/cortex/module.lb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@
1212
# -----------------------------------------------------------------------------
1313

1414
def common_vector_table_location(env):
15+
if env.get(":platform:core:vector_table_location", "rom") == "ram":
16+
return "ram"
1517
return env.get(":platform:cortex-m:vector_table_location", "rom")
1618

19+
1720
def common_vector_table(env):
1821
"""
1922
Computes vector table properties:

src/modm/platform/core/stm32/module.lb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,25 @@ def prepare(module, options):
2121
if options[":target"].identifier.platform != "stm32":
2222
return False
2323

24+
if options[":target"].get_driver("core")["type"] == "cortex-m0":
25+
module.add_option(
26+
EnumerationOption(
27+
name="vector_table_location",
28+
description=FileReader("option/vector_table_location.md"),
29+
enumeration=["rom", "ram"],
30+
default="rom")
31+
)
32+
2433
module.depends(":platform:cortex-m")
2534
return True
2635

2736

2837
def build(env):
2938
target = env[":target"].identifier
30-
env.substitutions = {"target": target}
39+
env.substitutions = {
40+
"target": target,
41+
"vector_table_location": env.get(":platform:core:vector_table_location", "rom")
42+
}
3143
env.outbasepath = "modm/src/modm/platform/core"
3244
# startup helper code
3345
env.template("startup_platform.c.in")
@@ -74,6 +86,8 @@ def post_build(env):
7486
env.outbasepath = "modm/link"
7587

7688
linkerscript = "../cortex/ram.ld.in"
89+
if env.get(":platform:core:vector_table_location", "rom") == "ram":
90+
linkerscript = "ram_remap_vector_table.ld.in"
7791
for memory in env.substitutions["memories"]:
7892
if memory["name"] == "ccm":
7993
if "x" in memory["access"]:

src/modm/platform/core/stm32/module.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,3 +440,55 @@ placed into the 128kB DTCM, but cannot overflow into D1_SRAM section.
440440
ITCM │ .vector_ram │
441441
0x0000 0000 └────────────────────────┘◄ __itcm_start
442442
```
443+
444+
## Static RAM (SRAM) with vector table remap on F0 devices
445+
446+
This memory map is identical to the SRAM default one, except that
447+
`.vector_ram` is placed at the beginning of SRAM1. It is used on STM32F0
448+
devices in case the platform-specific vector table relocation option
449+
`modm:platform:core:vector_table_location` is set to `ram`.
450+
451+
```
452+
┌────────────────────────┐◄ __sram1_end
453+
│ +HEAP_SRAM1 │
454+
│ .noinit_sram1 │
455+
│ .noinit │
456+
│ .faststack │
457+
│ .bss_sram1 │
458+
│ .bss │
459+
│ .data_sram1 │
460+
│ .data │
461+
│ .fastdata │
462+
│ .fastcode │
463+
│ +MAIN_STACK_SIZE │◄ __main_stack_top
464+
SRAM1 │ .vector_ram │
465+
0x2000 0000 └────────────────────────┘◄ __sram1_start
466+
467+
┌────────────────────────┐◄ __flash_end
468+
│ (unused) │
469+
├────────────────────────┤◄ __rom_end
470+
│ .table.heap │
471+
│ .table.copy.extern │
472+
tables │ .table.zero.extern │
473+
│ .table.copy.intern │
474+
│ .table.zero.intern │
475+
│ │
476+
copy │ .data_sram1 │
477+
only │ .data │
478+
│ .fastcode │
479+
│ .fastdata │
480+
│ │
481+
│ .note.gnu.build-id │
482+
│ .assertion │
483+
│ .hardware_init │
484+
│ (.eh_frame) │
485+
read │ (.ARM.exidx) │ only with C++ exceptions enabled
486+
only │ (.ARM.extab) │
487+
│ .init_array │
488+
│ .init │
489+
│ .rodata │
490+
│ .text │
491+
FLASH │ .vector_rom │
492+
0x0800 0000 └────────────────────────┘◄ __rom_start, __flash_start
493+
494+
```
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Vector table location in ROM or RAM on F0 devices
2+
3+
STM32 devices with a Cortex-M0 core provide a platform-specific method to place
4+
the interrupt vector table in SRAM although the core does not support vector
5+
table relocation. It is only available on STM32F0 since all other devices
6+
can remap the vector table in the Cortex-M core.
7+
8+
When this method is activated the vector table is copied to the start of SRAM1
9+
by the startup script. The `SYSCFG->CFGR1` register is set to remap the
10+
beginning of SRAM to the vector table location at `0x0000 0000`.
11+
12+
You can modify the RAM vector table using the CMSIS NVIC functions:
13+
14+
- `void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)`
15+
- `uint32_t NVIC_GetVector(IRQn_Type IRQn)`
16+
17+
This remapping method allows to easily boot an application from a custom
18+
bootloader even if the Cortex-M0 core does not support relocation.
19+
20+
For applications that do not modify the vector table at runtime, relocation to
21+
RAM is not necessary and can save a few hundred bytes of static memory.
22+
23+
!!! warning "On Interrupt Latency"
24+
Placing main stack and vector table into the same memory can significantly
25+
slow down interrupt latency, since both I-Code and D-Code memory interface
26+
need to fetch from the same access port.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
%% import "../cortex/linker.macros" as linker with context
2+
{{ linker.copyright() }}
3+
4+
{{ linker.prefix() }}
5+
%% set table_heap = []
6+
%% set table_copy = []
7+
%% set table_zero = []
8+
9+
SECTIONS
10+
{
11+
{{ linker.section_rom_start("FLASH") }}
12+
13+
{{ linker.section_vector_rom("FLASH") }}
14+
15+
{{ linker.section_rom("FLASH") }}
16+
17+
{{ linker.section_vector_ram(cont_ram_regions[0].cont_name|upper, table_copy) }}
18+
19+
{{ linker.section_stack(cont_ram_regions[0].cont_name|upper) }}
20+
21+
{{ linker.section_ram(cont_ram_regions[0].cont_name|upper, "FLASH", table_copy, table_zero,
22+
sections_data=["fastdata", "fastcode", "data_" + cont_ram_regions[0].contains[0].name],
23+
sections_bss=["bss_" + cont_ram_regions[0].contains[0].name],
24+
sections_noinit=["faststack"]) }}
25+
26+
{{ linker.all_heap_sections(table_copy, table_zero, table_heap) }}
27+
28+
%% if with_crashcatcher
29+
%#
30+
/* Bottom of crash stack for `modm:platform:fault` */
31+
g_crashCatcherStack = . - 500;
32+
%#
33+
%% endif
34+
35+
%% if linkerscript_sections
36+
{{ linkerscript_sections | indent(first=True) }}
37+
%#
38+
%% endif
39+
40+
{{ linker.section_tables("FLASH", table_copy, table_zero, table_heap) }}
41+
42+
{{ linker.section_rom_end("FLASH") }}
43+
44+
{{ linker.section_debug() }}
45+
}

src/modm/platform/core/stm32/startup_platform.c.in

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright (c) 2016-2017, Fabian Greif
44
* Copyright (c) 2016-2017, 2019, Niklas Hauser
55
* Copyright (c) 2021, Raphael Lehmann
6+
* Copyright (c) 2021, Christopher Durand
67
*
78
* This file is part of the modm project.
89
*
@@ -71,4 +72,9 @@ __modm_initialize_platform(void)
7172
PWR->CR2 |= PWR_CR2_IOSV;
7273
#endif
7374
%% endif
75+
76+
%% if vector_table_location == "ram"
77+
// Remap SRAM to 0x0 for vector table relocation without VTOR register
78+
SYSCFG->CFGR1 |= SYSCFG_CFGR1_MEM_MODE;
79+
%% endif
7480
}

0 commit comments

Comments
 (0)