Skip to content

Commit bd05e1b

Browse files
FoniksFoxjorgesg82
andauthored
Refactor/mpu manager (#537)
* Initial structure * no need to have an id for instance * erased no longer needed code * Added DigitalInput and DigitalOutput Services, and added support for Alternate functions * Replaced throw by undefined function * Implemented alternate functions * Added linker script and startup code, and fixed using hal template conf * Added initial GPIO mock * feat(MPU): Initial structure && design of the API * fix(MPU): Bug fixing (MPU subregion calculation, throws and alignment checks) * fix(MPU): Minor bug fixes (missing std::, incorrect subregion mask) * feat(MPU): Initial implementation of MPUManager refactor * feat(MPU)!: Bug fixing and changes on the infrastructure to allow proper MPU configuration * reafactor(MPU): Support legacy MPUManager without conflicts * fix(MPU): Remove MPUManager start call from HALAL init * feat(MPU): Modify linker scripts for MPU configuration * fix(MPU): Remove legacy things * fix(MPU): Fix legacy MPUManager * fix(MPU): Fix no buffer array of size zero issue * fix(MPU): Fix ST-LIB so that it accepts templated objects for MPU buffers * feat(MPU): Add concepts and safer interface * feat(MPU): Make construct method return a reference instead of pointer * fix(MPU): Relax constraints on MPU buffers to allow trivially destructible types * style(MPU): Better wording and documentation * feat(MPU): Make MPU ultra restrictive, should check that there's no region outside defined ones * fixed getting wrong instance * marked indexs as mutable * fix(MPU): Implemente st-lib fix * Fixed instance_of method. Now add interface needs the Device * fix(MPU): Apply the fix of the fix * fix(MPU): Make the MPUManager take it's buffer pointer from a linker symbol, to ensure initialization order doesn't matter * style(MPU): Remove comment * feat(MPU): Some missing things * fix: Delete hal_gpio_interface.h from this branch * refactor(MPU): Refactor the refactor of the MPU, now use linker script as source of truth * feat(MPU): Use more coherent MPU settings for better performance * fix(MPU): Make Stack and Heap use DTCM RAM * fix(MPU): Move ETH buffers to D1_NC ram, also add the buffer definition to the RAM linker script * fix(MPU): Use DTCM for static memory * feat(MPU): Add ram_code section for functions to be executed from ITCM RAM * fix(MPU): Fix comment with invalid syntax * fix(MPU): ADD ram_dx definitions to linker scripts * fix(MPU): Fix linker incompatibility thing * fix(MPU): Differentiate user, legacy, and buffer sections for MPU RAM allocations * fix(MPU): Reorder sections in linker script to ensure buffers are placed at the start * fix(MPU): Apply same change as before to the other linker * fix(MPU): Delete Ethernet::mpu_start functions for safety * feat(MPU): Add helpers * style(MPU): Use log2 and max instead of cascading logic in linker scripts * feat(MPU): Minor improvements * fix(MPU): Use std::ranges::find instead of contains to pass checks * feat(MPU): Change default memory domain to D1 for buffer allocations * feat(MPU): Use absolute values rather than addresses and casts for Linker Symbols, also clean up LD scripts * feat(MPU): Add constructor using entry to allow for named parameters * fix(MPU): Fix the compile error given by compile_error --------- Co-authored-by: Jorge Sáez <jorgeesg82@gmail.com>
1 parent f486b94 commit bd05e1b

11 files changed

Lines changed: 799 additions & 162 deletions

File tree

Inc/HALAL/HALAL.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "HALAL/Services/FMAC/FMAC.hpp"
3838

3939
#include "HALAL/Models/MPUManager/MPUManager.hpp"
40+
#include "HALAL/Models/MPU.hpp"
4041
#include "HALAL/Services/InfoWarning/InfoWarning.hpp"
4142
#include "HALAL/Services/Watchdog/Watchdog.hpp"
4243

Inc/HALAL/Models/MPU.hpp

Lines changed: 449 additions & 0 deletions
Large diffs are not rendered by default.

Inc/HALAL/Models/MPUManager/MPUManager.hpp

Lines changed: 0 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -5,75 +5,8 @@
55

66
#define NO_CACHED_RAM_MAXIMUM_SPACE 2048
77

8-
extern unsigned long _no_cached_ram_start;
9-
10-
118
class MPUManager{
129
public:
13-
static struct config{
14-
bool using_cache = true;
15-
}MPUConfig;/**< MPU configuration defined un Runes.hpp*/
16-
17-
static void start(){
18-
MPU_Region_InitTypeDef MPU_InitStruct = {0};
19-
HAL_MPU_Disable();
20-
21-
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
22-
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
23-
MPU_InitStruct.BaseAddress = 0x0;
24-
MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
25-
MPU_InitStruct.SubRegionDisable = 0x87;
26-
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
27-
MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
28-
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
29-
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
30-
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
31-
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
32-
HAL_MPU_ConfigRegion(&MPU_InitStruct);
33-
/** Initializes and configures the Region and the memory to be protected
34-
*/
35-
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
36-
MPU_InitStruct.BaseAddress = 0x30000000;
37-
MPU_InitStruct.Size = MPU_REGION_SIZE_32KB;
38-
MPU_InitStruct.SubRegionDisable = 0x0;
39-
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
40-
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
41-
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
42-
HAL_MPU_ConfigRegion(&MPU_InitStruct);
43-
/** Initializes and configures the Region and the memory to be protected
44-
*/
45-
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
46-
MPU_InitStruct.Size = MPU_REGION_SIZE_512B;
47-
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
48-
MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
49-
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
50-
HAL_MPU_ConfigRegion(&MPU_InitStruct);
51-
/** Initializes and configures the Region and the memory to be protected
52-
*/
53-
MPU_InitStruct.Number = MPU_REGION_NUMBER3;
54-
MPU_InitStruct.BaseAddress = 0x08000000;
55-
MPU_InitStruct.Size = MPU_REGION_SIZE_1MB;
56-
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
57-
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
58-
HAL_MPU_ConfigRegion(&MPU_InitStruct);
59-
60-
MPU_InitStruct.Number = MPU_REGION_NUMBER4;
61-
MPU_InitStruct.BaseAddress = 0x38000000;
62-
MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;
63-
MPU_InitStruct.SubRegionDisable = 0x0;
64-
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
65-
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
66-
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
67-
HAL_MPU_ConfigRegion(&MPU_InitStruct);
68-
/* Enables the MPU */
69-
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
70-
71-
if(MPUConfig.using_cache){
72-
SCB_EnableICache();
73-
SCB_EnableDCache();
74-
}
75-
}
76-
7710
static void* allocate_non_cached_memory(uint32_t size){
7811
void* buffer = (void*)((uint8_t*)no_cached_ram_start + no_cached_ram_occupied_bytes);
7912
no_cached_ram_occupied_bytes = no_cached_ram_occupied_bytes + size;

Inc/HALAL/Services/Communication/Ethernet/Ethernet.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ class Ethernet{
3838
static void update();
3939

4040
private:
41-
static void mpu_start();
4241
};
4342

4443
#endif

Inc/ST-LIB.hpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ template <typename... Domains> struct BuildCtx {
8383
}
8484
};
8585

86-
using DomainsCtx = BuildCtx<GPIODomain, TimerDomain,
86+
using DomainsCtx = BuildCtx<MPUDomain, GPIODomain, TimerDomain,
8787
DigitalOutputDomain,
8888
DigitalInputDomain /*, ADCDomain, PWMDomain, ...*/>;
8989

@@ -105,13 +105,15 @@ template <auto &...devs> struct Board {
105105
constexpr std::size_t timN = domain_size<TimerDomain>();
106106
constexpr std::size_t doutN = domain_size<DigitalOutputDomain>();
107107
constexpr std::size_t dinN = domain_size<DigitalInputDomain>();
108+
constexpr std::size_t mpuN = domain_size<MPUDomain>();
108109
// ...
109110

110111
struct ConfigBundle {
111112
std::array<GPIODomain::Config, gpioN> gpio_cfgs;
112113
std::array<TimerDomain::Config, timN> tim_cfgs;
113114
std::array<DigitalOutputDomain::Config, doutN> dout_cfgs;
114115
std::array<DigitalInputDomain::Config, dinN> din_cfgs;
116+
std::array<MPUDomain::Config, mpuN> mpu_cfgs;
115117
// ...
116118
};
117119

@@ -124,6 +126,8 @@ template <auto &...devs> struct Board {
124126
ctx.template span<DigitalOutputDomain>()),
125127
.din_cfgs = DigitalInputDomain::template build<dinN>(
126128
ctx.template span<DigitalInputDomain>()),
129+
.mpu_cfgs = MPUDomain::template build<mpuN>(
130+
ctx.template span<MPUDomain>())
127131
// ...
128132
};
129133
}
@@ -135,6 +139,7 @@ template <auto &...devs> struct Board {
135139
constexpr std::size_t timN = domain_size<TimerDomain>();
136140
constexpr std::size_t doutN = domain_size<DigitalOutputDomain>();
137141
constexpr std::size_t dinN = domain_size<DigitalInputDomain>();
142+
constexpr std::size_t mpuN = domain_size<MPUDomain>();
138143
// ...
139144

140145
GPIODomain::Init<gpioN>::init(cfg.gpio_cfgs);
@@ -143,6 +148,7 @@ template <auto &...devs> struct Board {
143148
GPIODomain::Init<gpioN>::instances);
144149
DigitalInputDomain::Init<dinN>::init(cfg.din_cfgs,
145150
GPIODomain::Init<gpioN>::instances);
151+
MPUDomain::Init<mpuN, cfg.mpu_cfgs>::init();
146152
// ...
147153
}
148154

@@ -165,7 +171,12 @@ template <auto &...devs> struct Board {
165171
constexpr std::size_t idx = owner_index_of<Domain, Target>();
166172

167173
constexpr std::size_t N = domain_size<Domain>();
168-
return Domain::template Init<N>::instances[idx];
174+
175+
if constexpr (std::is_same_v<Domain, MPUDomain>) {
176+
return Domain::template Init<N, cfg.mpu_cfgs>::instances[idx];
177+
} else {
178+
return Domain::template Init<N>::instances[idx];
179+
}
169180
}
170181
};
171182

STM32H723ZGTX_FLASH.ld

Lines changed: 145 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
ENTRY(Reset_Handler)
3636

3737
/* Highest address of the user mode stack */
38-
_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1); /* end of RAM */
39-
/* Generate a link error if heap and stack don't fit into RAM */
38+
_estack = ORIGIN(DTCMRAM) + LENGTH(DTCMRAM); /* end of RAM */
39+
/* Generate a link error if heap and stack don't fit into RAM/DTCM */
4040
_Min_Heap_Size = 0x200; /* required amount of heap */
4141
_Min_Stack_Size = 0x400; /* required amount of stack */
4242

@@ -54,6 +54,22 @@ MEMORY
5454
/* Define output sections */
5555
SECTIONS
5656
{
57+
/* Export Memory Layout Information for MPU Configuration */
58+
__itcm_base = ABSOLUTE(ORIGIN(ITCMRAM));
59+
__itcm_size = ABSOLUTE(LENGTH(ITCMRAM));
60+
__dtcm_base = ABSOLUTE(ORIGIN(DTCMRAM));
61+
__dtcm_size = ABSOLUTE(LENGTH(DTCMRAM));
62+
__flash_base = ABSOLUTE(ORIGIN(FLASH));
63+
__flash_size = ABSOLUTE(LENGTH(FLASH));
64+
__ram_d1_base = ABSOLUTE(ORIGIN(RAM_D1));
65+
__ram_d1_size = ABSOLUTE(LENGTH(RAM_D1));
66+
__ram_d2_base = ABSOLUTE(ORIGIN(RAM_D2));
67+
__ram_d2_size = ABSOLUTE(LENGTH(RAM_D2));
68+
__ram_d3_base = ABSOLUTE(ORIGIN(RAM_D3));
69+
__ram_d3_size = ABSOLUTE(LENGTH(RAM_D3));
70+
__peripheral_base = 0x40000000;
71+
__peripheral_size = 0x20000000; /* 512MB */
72+
5773
/* The startup code goes first into FLASH */
5874
.isr_vector :
5975
{
@@ -118,6 +134,35 @@ SECTIONS
118134
PROVIDE_HIDDEN (__fini_array_end = .);
119135
} >FLASH
120136

137+
/* MPU D1 Non-Cached Section: Placed at start of RAM_D1 for alignment */
138+
.mpu_ram_d1_nc :
139+
{
140+
. = ALIGN(32);
141+
__mpu_d1_nc_start = ABSOLUTE(.);
142+
143+
/* New MPU system buffers */
144+
*(.mpu_ram_d1_nc.buffer)
145+
146+
/* User manual allocations via D1_NC macro */
147+
*(.mpu_ram_d1_nc.user)
148+
149+
/* Ethernet Rx Pool */
150+
. = ALIGN(32);
151+
*(.Rx_PoolSection)
152+
} >RAM_D1
153+
154+
/* CALCULATE PADDING FOR MPU SUBREGIONS (D1) */
155+
_d1_size = SIZEOF(.mpu_ram_d1_nc);
156+
/* Find next power of 2 (up to 512KB for 320KB RAM) */
157+
_d1_p2 = (1 << LOG2CEIL(MAX(32, _d1_size)));
158+
/* Subregion size is RegionSize / 8 */
159+
_d1_sub = _d1_p2 / 8;
160+
/* Align effective size to the subregion granularity */
161+
_d1_pad = (_d1_size + _d1_sub - 1) / _d1_sub * _d1_sub;
162+
/* Advance current pointer to reserve this space */
163+
. = __mpu_d1_nc_start + _d1_pad;
164+
__mpu_d1_nc_end = ABSOLUTE(.);
165+
121166
/* used by the startup to initialize data */
122167
_sidata = LOADADDR(.data);
123168

@@ -128,12 +173,10 @@ SECTIONS
128173
_sdata = .; /* create a global symbol at data start */
129174
*(.data) /* .data sections */
130175
*(.data*) /* .data* sections */
131-
*(.RamFunc) /* .RamFunc sections */
132-
*(.RamFunc*) /* .RamFunc* sections */
133176

134177
. = ALIGN(4);
135178
_edata = .; /* define a global symbol at data end */
136-
} >RAM_D1 AT> FLASH
179+
} >DTCMRAM AT> FLASH
137180
/*
138181
this needs to be the last thing in FLASH
139182
because the preceeding sections are appended after the one preceeding them
@@ -160,15 +203,10 @@ SECTIONS
160203
*(.bss*)
161204
*(COMMON)
162205

163-
/* ETH_CODE: add placement of RX buffer. STM32H72x/H73x has small D2 RAM, so we need to put it there.
164-
* (NOLOAD) attribute used for .bss section to avoid linker warning (.bss initialized by startup code)
165-
*/
166-
. = ALIGN(32);
167-
*(.Rx_PoolSection)
168206
. = ALIGN(4);
169207
_ebss = .; /* define a global symbol at bss end */
170208
__bss_end__ = _ebss;
171-
} >RAM_D1
209+
} >DTCMRAM
172210

173211
/* User_heap_stack section, used to check that there is enough RAM left */
174212
._user_heap_stack :
@@ -179,24 +217,74 @@ SECTIONS
179217
. = . + _Min_Heap_Size;
180218
. = . + _Min_Stack_Size;
181219
. = ALIGN(8);
182-
} >RAM_D1
220+
} >DTCMRAM
183221

184-
/* ETH_CODE: add placement of DMA descriptors, rest is used by RX_POOL */
185-
.lwip_sec (NOLOAD) :
222+
/* MPU D2 Non-Cached Section: Contains Ethernet Descriptors and Generic Buffers */
223+
.mpu_ram_d2_nc :
186224
{
187-
. = ABSOLUTE(0x30000000);
188-
*(.RxDecripSection)
225+
. = ALIGN(32);
226+
__mpu_d2_nc_start = ABSOLUTE(.);
189227

190-
. = ABSOLUTE(0x30000100);
228+
/* ETH Descriptors - Must be aligned */
229+
*(.RxDecripSection)
191230
*(.TxDecripSection)
192231

232+
/* New MPU system buffers */
233+
*(.mpu_ram_d2_nc.buffer)
234+
235+
/* User manual allocations via D2_NC macro */
236+
*(.mpu_ram_d2_nc.user)
237+
193238
} >RAM_D2
194-
.stlib_no_cache_ram_pool :
239+
240+
/* CALCULATE PADDING FOR MPU SUBREGIONS (D2) */
241+
_d2_size = SIZEOF(.mpu_ram_d2_nc);
242+
/* Find next power of 2 (up to 64KB for 32KB RAM to catch overflow logic if needed) */
243+
_d2_p2 = (1 << LOG2CEIL(MAX(32, _d2_size)));
244+
_d2_sub = _d2_p2 / 8;
245+
_d2_pad = (_d2_size + _d2_sub - 1) / _d2_sub * _d2_sub;
246+
. = __mpu_d2_nc_start + _d2_pad;
247+
__mpu_d2_nc_end = ABSOLUTE(.);
248+
249+
/* MPU D3 Non-Cached Section */
250+
.mpu_ram_d3_nc :
195251
{
196-
. = ABSOLUTE(0x38000000);
197-
_no_cached_ram_start = .;
198-
252+
. = ALIGN(32);
253+
__mpu_d3_nc_start = ABSOLUTE(.);
254+
255+
/* New MPU system buffers */
256+
*(.mpu_ram_d3_nc.buffer)
257+
258+
/* Legacy MPUManager allocations */
259+
*(.mpu_ram_d3_nc.legacy)
260+
261+
/* User manual allocations via D3_NC macro */
262+
*(.mpu_ram_d3_nc.user)
263+
264+
199265
} >RAM_D3
266+
267+
/* CALCULATE PADDING FOR MPU SUBREGIONS (D3) */
268+
_d3_size = SIZEOF(.mpu_ram_d3_nc);
269+
/* Find next power of 2 (up to 32KB for 16KB RAM) */
270+
_d3_p2 = (1 << LOG2CEIL(MAX(32, _d3_size)));
271+
_d3_sub = _d3_p2 / 8;
272+
_d3_pad = (_d3_size + _d3_sub - 1) / _d3_sub * _d3_sub;
273+
. = __mpu_d3_nc_start + _d3_pad;
274+
__mpu_d3_nc_end = ABSOLUTE(.);
275+
276+
/* Code running in ITCM RAM (0 Wait States, Instruction Bus) */
277+
.ram_code :
278+
{
279+
. = ALIGN(4);
280+
_sram_code = .;
281+
*(.ram_code)
282+
*(.ram_code*)
283+
. = ALIGN(4);
284+
_eram_code = .;
285+
} >ITCMRAM AT> FLASH
286+
_siram_code = LOADADDR(.ram_code);
287+
200288
/* Remove information from the standard libraries */
201289
/DISCARD/ :
202290
{
@@ -206,4 +294,40 @@ SECTIONS
206294
}
207295

208296
.ARM.attributes 0 : { *(.ARM.attributes) }
297+
298+
/* MPU D1 Cached Section */
299+
.ram_d1 :
300+
{
301+
. = ALIGN(32);
302+
303+
/* User manual allocations via D1_C macro */
304+
*(.ram_d1.user)
305+
306+
/* New MPU system buffers */
307+
*(.ram_d1.buffer)
308+
} >RAM_D1
309+
310+
/* MPU D2 Cached Section */
311+
.ram_d2 :
312+
{
313+
. = ALIGN(32);
314+
315+
/* User manual allocations via D2_C macro */
316+
*(.ram_d2.user)
317+
318+
/* New MPU system buffers */
319+
*(.ram_d2.buffer)
320+
} >RAM_D2
321+
322+
/* MPU D3 Cached Section */
323+
.ram_d3 :
324+
{
325+
. = ALIGN(32);
326+
327+
/* User manual allocations via D3_C macro */
328+
*(.ram_d3.user)
329+
330+
/* New MPU system buffers */
331+
*(.ram_d3.buffer)
332+
} >RAM_D3
209333
}

0 commit comments

Comments
 (0)