blob: c9b3fffbbd723d40edf84d587a8be4a3adf4b8ec [file] [log] [blame]
Armando Montanez70095662020-01-09 14:25:04 -08001.. _chapter-pw-boot-armv7m:
2
3.. default-domain:: cpp
4
5.. highlight:: sh
6
7--------------
8pw_boot_armv7m
9--------------
10
11The ARMv7-M boot module provides a linker script and some early initialization
12of static memory regions and C++ constructors. This is enough to get many
13ARMv7-M cores booted and ready to run C++ code.
14
15This module is currently designed to support a very minimal device memory layout
16configuration:
17
18 - One contiguous region for RAM.
19 - One contiguous region for flash.
20 - Static, in-flash vector table at the default location expected by the SoC.
21
22Note that this module is not yet particularly suited for projects that utilize
23a bootloader, as it's relatively opinionated regarding where code is stored.
24
25.. warning::
26 This module is currently NOT stable! Depending on this module may cause
27 breakages as this module is updated.
28
29Setup
30=====
31
32User-Implemented Functions
33--------------------------
34This module expects two extern "C" functions to be defined outside this module.
35
36 - ``int main()``: This is where applications reside.
37 - ``void pw_PreMainInit()``: This function executes just before main, and
38 can be used for any device initialization that isn't application specific.
39 Depending on your platform, this might be turning on a UART, setting up
40 default clocks, etc.
41
42If either of these functions are unimplemented, executables will encounter a
43link error.
44
45Required Configs
46----------------
47This module has a number of required configuration options that mold the linker
48script to fit to a wide variety of ARMv7-M SoCs. The ``pw_boot_armv7m_config``
49GN variable has a ``defines`` member that can be used to modify these linker
50script options. See the documentation section on configuration for information
51regarding which configuration options are required.
52
53Vector Table
54------------
55Targets using pw_boot_armv7m will need to provide an ARMv7-M interrupt vector
56table (ARMv7-M Architecture Reference Manual DDI 0403E.b section B1.5.2 and
57B1.5.3). This is done by storing an array into the ``.vector_table`` section,
58and properly configuring ``PW_BOOT_INTERRUPT_VECTOR_TABLE_*`` preprocessor
59defines to cover the address region your SoC expects the vector table to be
60located at (often the beginning of the flash region). If using a bootloader,
61ensure VTOR (Vector Table Offset Register) is configured to point to the vector
62table. Otherwise, refer to the hardware vendor's documentation to determine
63where the vector table should be located such that it resides where VTOR is
64initialized to by default.
65
66Example vector table:
67
68.. code-block:: cpp
69
70 typedef void (*InterruptHandler)();
71
72 PW_KEEP_IN_SECTION(".vector_table")
73 const InterruptHandler vector_table[] = {
74 // The starting location of the stack pointer.
75 // This address is NOT an interrupt handler/function pointer, it is simply
76 // the address that the main stack pointer should be initialized to. The
77 // value is reinterpret casted because it needs to be in the vector table.
78 [0] = reinterpret_cast<InterruptHandler>(&pw_stack_high_addr),
79
80 // Reset handler, dictates how to handle reset interrupt. This is the
81 // address that the Program Counter (PC) is initialized to at boot.
82 [1] = pw_BootEntry,
83
84 // NMI handler.
85 [2] = DefaultFaultHandler,
86 // HardFault handler.
87 [3] = DefaultFaultHandler,
88 ...
89 };
90
91Usage
92=====
93
94Publicly exported symbols
95-------------------------
96The linker script provided by this module exports a number of symbols that
97may be used to retrieve the locations of specific memory regions at runtime.
98These symbols are declared as ``uint8_t`` variables. The variables themselves
99do not contain the addresses, they only reside at the memory location they
100reference. To retrieve the memory locations, simply take the reference of the
101symbol (e.g. ``&pw_vector_table_addr``).
102
103``pw_heap_[low/high]_addr``: Beginning and end of the memory range of the heap.
104These addresses may be identical, indicating a heap with a size of zero bytes.
105
106``pw_stack_[low/high]_addr``: Beginning and end of the memory range of the main
107stack. This might not be the only stack in the system.
108
109``pw_vector_table_addr``: Beginning of the ARMv7-M interrupt vector table.
110
111Configuration
112=============
113These configuration options can be controlled by appending to
114``pw_boot_armv7m_config.defines`` as part of a Pigweed target config file.
115
116**PW_BOOT_HEAP_SIZE** (required):
117How much memory (in bytes) to reserve for the heap. This can be zero.
118
119**PW_BOOT_MIN_STACK_SIZE** (required):
120The minimum size reserved for the main stack. If statically allocated memory
121begins to cut into the minimum, a link error will be emitted.
122
123**PW_BOOT_FLASH_BEGIN** (required):
124The start address of the MCU's flash region. This region must NOT include the
125vector table. (i.e. if the INTERRUPT_VECTOR_TABLE is in flash, the flash region
126should begin *after* the vtable)
127
128**PW_BOOT_FLASH_SIZE** (required):
129Size of the flash region in bytes.
130
131**PW_BOOT_RAM_BEGIN** (required):
132The start address of the MCU's RAM region.
133
134**PW_BOOT_RAM_SIZE** (required):
135Size of the RAM region in bytes.
136
137**PW_BOOT_INTERRUPT_VECTOR_TABLE_BEGIN** (required):
138Address the target MCU expects the link-time vector table to be located at. This
139is typically the beginning of the flash region. While the vector table may be
140changed later in the boot process, a minimal vector table MUST be present for
141the MCU to operate as expected.
142
143**PW_BOOT_INTERRUPT_VECTOR_TABLE_SIZE** (required):
144Number of bytes to reserve for the ARMv7-M vector table.
145
146Dependencies
147============
148 * pw_preprocessor module