blob: 48bd3e49e2523ada11ea0c6f65e5097fc5e83dc0 [file] [log] [blame]
Wyatt Heplerf9fb90f2020-09-30 18:59:33 -07001.. _module-pw_boot_armv7m:
Armando Montanez70095662020-01-09 14:25:04 -08002
3--------------
4pw_boot_armv7m
5--------------
6
7The ARMv7-M boot module provides a linker script and some early initialization
8of static memory regions and C++ constructors. This is enough to get many
9ARMv7-M cores booted and ready to run C++ code.
10
11This module is currently designed to support a very minimal device memory layout
12configuration:
13
14 - One contiguous region for RAM.
15 - One contiguous region for flash.
16 - Static, in-flash vector table at the default location expected by the SoC.
17
18Note that this module is not yet particularly suited for projects that utilize
19a bootloader, as it's relatively opinionated regarding where code is stored.
20
21.. warning::
22 This module is currently NOT stable! Depending on this module may cause
23 breakages as this module is updated.
24
Ewout van Bekkumfff82ec2020-08-21 15:54:28 -070025Sequence
26========
27
28The high level pw_boot_armv7m boot sequence looks like the following psuedo-code
29invocation of the user-implemented functions:
30
31.. code:: cpp
32
33 void pw_boot_Entry() { // Boot entry point.
34 pw_boot_PreStaticMemoryInit(); // User-implemented function.
35 // Static memory initialization.
36 pw_boot_PreStaticConstructorInit(); // User-implemented function.
37 // C++ static constructors are invoked.
38 pw_boot_PreMainInit(); // User-implemented function.
39 main(); // User-implemented function.
Ewout van Bekkum738f42c2020-08-24 12:55:13 -070040 pw_boot_PostMain(); // User-implemented function.
41 PW_UNREACHABLE;
Ewout van Bekkumfff82ec2020-08-21 15:54:28 -070042 }
43
Armando Montanez70095662020-01-09 14:25:04 -080044Setup
45=====
46
47User-Implemented Functions
48--------------------------
Ewout van Bekkum738f42c2020-08-24 12:55:13 -070049This module expects all of these extern "C" functions to be defined outside this
50module:
Armando Montanez70095662020-01-09 14:25:04 -080051
52 - ``int main()``: This is where applications reside.
Ewout van Bekkumfff82ec2020-08-21 15:54:28 -070053 - ``void pw_boot_PreStaticMemoryInit()``: This function executes just before
Shiva Rajagopal9e516562021-05-11 17:04:15 -070054 static memory has been zeroed and static data is intialized. This function
Ewout van Bekkumfff82ec2020-08-21 15:54:28 -070055 should set up any early initialization that should be done before static
56 memory is initialized, such as:
57
58 - Enabling the FPU or other coprocessors.
59 - Opting into extra restrictions such as disabling unaligned access to ensure
60 the restrictions are active during static RAM initialization.
61 - Initial CPU clock, flash, and memory configurations including potentially
62 enabling extra memory regions with .bss and .data sections, such as SDRAM
63 or backup powered SRAM.
64 - Fault handler initialization if required before static memory
65 initialization.
66
67 .. warning::
68 Code running in this hook is violating the C spec as static values are not
69 yet initialized, meaning they have not been loaded (.data) nor
70 zero-initialized (.bss).
71
72 - ``void pw_boot_PreStaticConstructorInit()``: This function executes just
73 before C++ static constructors are called. At this point, other static memory
74 has been zero or data initialized. This function should set up any early
75 initialization that should be done before C++ static constructors are run,
76 such as:
77
78 - Run time dependencies such as Malloc, and ergo sometimes the RTOS.
79 - Persistent memory that survives warm reboots.
80 - Enabling the MPU to catch nullptr dereferences during construction.
81 - Main stack watermarking.
82 - Further fault handling configuration necessary for your platform which
83 were not safe before pw_boot_PreStaticRamInit().
84 - Boot count and/or boot session UUID management.
85
86 - ``void pw_boot_PreMainInit()``: This function executes just before main, and
Armando Montanez70095662020-01-09 14:25:04 -080087 can be used for any device initialization that isn't application specific.
88 Depending on your platform, this might be turning on a UART, setting up
89 default clocks, etc.
90
Ewout van Bekkum738f42c2020-08-24 12:55:13 -070091 - ``PW_NO_RETURN void pw_boot_PostMain()``: This function executes after main
92 has returned. This could be used for device specific teardown such as an
93 infinite loop, soft reset, or QEMU shutdown. In addition, if relevant for
94 your application, this would be the place to invoke the global static
95 destructors. This function must not return!
96
97
Ewout van Bekkumfff82ec2020-08-21 15:54:28 -070098If any of these functions are unimplemented, executables will encounter a link
99error.
Armando Montanez70095662020-01-09 14:25:04 -0800100
101Required Configs
102----------------
103This module has a number of required configuration options that mold the linker
104script to fit to a wide variety of ARMv7-M SoCs. The ``pw_boot_armv7m_config``
105GN variable has a ``defines`` member that can be used to modify these linker
106script options. See the documentation section on configuration for information
107regarding which configuration options are required.
108
109Vector Table
110------------
Armando Montanez0054a9b2020-03-13 13:06:24 -0700111Targets using ``pw_boot_armv7m`` will need to provide an ARMv7-M interrupt
112vector table (ARMv7-M Architecture Reference Manual DDI 0403E.b section B1.5.2
113and B1.5.3). This is done by storing an array into the ``.vector_table``
114section, and properly configuring ``PW_BOOT_VECTOR_TABLE_*`` preprocessor
Armando Montanez70095662020-01-09 14:25:04 -0800115defines to cover the address region your SoC expects the vector table to be
116located at (often the beginning of the flash region). If using a bootloader,
117ensure VTOR (Vector Table Offset Register) is configured to point to the vector
118table. Otherwise, refer to the hardware vendor's documentation to determine
119where the vector table should be located such that it resides where VTOR is
120initialized to by default.
121
122Example vector table:
123
124.. code-block:: cpp
125
126 typedef void (*InterruptHandler)();
127
128 PW_KEEP_IN_SECTION(".vector_table")
129 const InterruptHandler vector_table[] = {
130 // The starting location of the stack pointer.
131 // This address is NOT an interrupt handler/function pointer, it is simply
132 // the address that the main stack pointer should be initialized to. The
133 // value is reinterpret casted because it needs to be in the vector table.
Ewout van Bekkumfff82ec2020-08-21 15:54:28 -0700134 [0] = reinterpret_cast<InterruptHandler>(&pw_boot_stack_high_addr),
Armando Montanez70095662020-01-09 14:25:04 -0800135
136 // Reset handler, dictates how to handle reset interrupt. This is the
137 // address that the Program Counter (PC) is initialized to at boot.
Ewout van Bekkumfff82ec2020-08-21 15:54:28 -0700138 [1] = pw_boot_Entry,
Armando Montanez70095662020-01-09 14:25:04 -0800139
140 // NMI handler.
141 [2] = DefaultFaultHandler,
142 // HardFault handler.
143 [3] = DefaultFaultHandler,
144 ...
145 };
146
147Usage
148=====
149
150Publicly exported symbols
151-------------------------
152The linker script provided by this module exports a number of symbols that
153may be used to retrieve the locations of specific memory regions at runtime.
154These symbols are declared as ``uint8_t`` variables. The variables themselves
155do not contain the addresses, they only reside at the memory location they
156reference. To retrieve the memory locations, simply take the reference of the
Ewout van Bekkumfff82ec2020-08-21 15:54:28 -0700157symbol (e.g. ``&pw_boot_vector_table_addr``).
Armando Montanez70095662020-01-09 14:25:04 -0800158
Ewout van Bekkumfff82ec2020-08-21 15:54:28 -0700159``pw_boot_heap_[low/high]_addr``: Beginning and end of the memory range of the heap.
Armando Montanez70095662020-01-09 14:25:04 -0800160These addresses may be identical, indicating a heap with a size of zero bytes.
161
Ewout van Bekkumfff82ec2020-08-21 15:54:28 -0700162``pw_boot_stack_[low/high]_addr``: Beginning and end of the memory range of the main
Armando Montanez70095662020-01-09 14:25:04 -0800163stack. This might not be the only stack in the system.
164
Ewout van Bekkumfff82ec2020-08-21 15:54:28 -0700165``pw_boot_vector_table_addr``: Beginning of the ARMv7-M interrupt vector table.
Armando Montanez70095662020-01-09 14:25:04 -0800166
167Configuration
168=============
Armando Montaneza761e322020-06-15 16:30:40 -0700169These configuration options can be controlled by appending list items to
170``pw_boot_armv7m_LINK_CONFIG_DEFINES`` as part of a Pigweed target
171configuration.
Armando Montanez70095662020-01-09 14:25:04 -0800172
Armando Montanez0054a9b2020-03-13 13:06:24 -0700173``PW_BOOT_HEAP_SIZE`` (required):
Armando Montanez70095662020-01-09 14:25:04 -0800174How much memory (in bytes) to reserve for the heap. This can be zero.
175
Armando Montanez0054a9b2020-03-13 13:06:24 -0700176``PW_BOOT_MIN_STACK_SIZE`` (required):
Armando Montanez70095662020-01-09 14:25:04 -0800177The minimum size reserved for the main stack. If statically allocated memory
178begins to cut into the minimum, a link error will be emitted.
179
Armando Montanez0054a9b2020-03-13 13:06:24 -0700180``PW_BOOT_FLASH_BEGIN`` (required):
Armando Montanez70095662020-01-09 14:25:04 -0800181The start address of the MCU's flash region. This region must NOT include the
Armando Montanez92212132020-01-16 15:03:20 -0800182vector table. (i.e. if the VECTOR_TABLE is in flash, the flash region
Armando Montanez70095662020-01-09 14:25:04 -0800183should begin *after* the vtable)
184
Armando Montanez0054a9b2020-03-13 13:06:24 -0700185``PW_BOOT_FLASH_SIZE`` (required):
Armando Montanez70095662020-01-09 14:25:04 -0800186Size of the flash region in bytes.
187
Armando Montanez0054a9b2020-03-13 13:06:24 -0700188``PW_BOOT_RAM_BEGIN`` (required):
Armando Montanez70095662020-01-09 14:25:04 -0800189The start address of the MCU's RAM region.
190
Armando Montanez0054a9b2020-03-13 13:06:24 -0700191``PW_BOOT_RAM_SIZE`` (required):
Armando Montanez70095662020-01-09 14:25:04 -0800192Size of the RAM region in bytes.
193
Armando Montanez0054a9b2020-03-13 13:06:24 -0700194``PW_BOOT_VECTOR_TABLE_BEGIN`` (required):
Armando Montanez70095662020-01-09 14:25:04 -0800195Address the target MCU expects the link-time vector table to be located at. This
196is typically the beginning of the flash region. While the vector table may be
197changed later in the boot process, a minimal vector table MUST be present for
198the MCU to operate as expected.
199
Armando Montanez0054a9b2020-03-13 13:06:24 -0700200``PW_BOOT_VECTOR_TABLE_SIZE`` (required):
Armando Montanez70095662020-01-09 14:25:04 -0800201Number of bytes to reserve for the ARMv7-M vector table.
202
203Dependencies
204============
Armando Montanez0054a9b2020-03-13 13:06:24 -0700205 * ``pw_preprocessor`` module