4444// Defines for attributes
4545// Note1: Variables declared with these attributes will likely not be initialized by the startup
4646// Note2: These attributes can only be used for static/global variables
47+ #ifdef SIM_ON
48+ #define D1_NC
49+ #define D2_NC
50+ #define D3_NC
51+ #define D1_C
52+ #define D2_C
53+ #define D3_C
54+ #define RAM_CODE
55+ #else
4756#define D1_NC __attribute__ ((section(" .mpu_ram_d1_nc.user" )))
4857#define D2_NC __attribute__ ((section(" .mpu_ram_d2_nc.user" )))
4958#define D3_NC __attribute__ ((section(" .mpu_ram_d3_nc.user" )))
5362
5463// Define for RAM code
5564#define RAM_CODE __attribute__ ((section(" .ram_code" )))
65+ #endif
5666
5767// Memory Bank Symbols from Linker
5868extern " C" const char __itcm_base;
@@ -78,6 +88,17 @@ extern "C" const char __mpu_d2_nc_end;
7888extern " C" const char __mpu_d3_nc_start;
7989extern " C" const char __mpu_d3_nc_end;
8090
91+ inline constexpr std::array<std::size_t , 6 > mpu_supported_alignments = {32 , 16 , 8 , 4 , 2 , 1 };
92+
93+ consteval bool is_supported_mpu_alignment (std::size_t alignment) {
94+ for (std::size_t candidate : mpu_supported_alignments) {
95+ if (candidate == alignment) {
96+ return true ;
97+ }
98+ }
99+ return false ;
100+ }
101+
81102template <typename T>
82103concept mpu_buffer_request = requires (typename T::domain d) {
83104 typename T::buffer_type;
@@ -133,7 +154,7 @@ struct MPUDomain {
133154 " Requested type has alignment greater than cache line size (32 bytes)."
134155 );
135156 static_assert (
136- std::ranges::find (alignments, alignof (T)) != std::ranges::end (alignments ),
157+ is_supported_mpu_alignment ( alignof (T)),
137158 " Requested type has alignment not supported by MPU buffer system."
138159 );
139160 }
@@ -143,14 +164,12 @@ struct MPUDomain {
143164 * @param entry The Entry with all buffer requirements specified.
144165 */
145166 consteval Buffer (Entry entry) : e(entry) {
146- static_assert (
147- entry.alignment <= 32 ,
148- " Requested alignment greater than cache line size (32 bytes)."
149- );
150- static_assert (
151- std::ranges::find (alignments, entry.alignment ) != std::ranges::end (alignments),
152- " Requested alignment not supported by MPU buffer system."
153- );
167+ if (entry.alignment > 32 ) {
168+ compile_error (" Requested alignment greater than cache line size (32 bytes)." );
169+ }
170+ if (!is_supported_mpu_alignment (entry.alignment )) {
171+ compile_error (" Requested alignment not supported by MPU buffer system." );
172+ }
154173 // Verify size matches sizeof(T)
155174 if (entry.size_in_bytes != sizeof (T)) {
156175 compile_error (" Entry size_in_bytes must match sizeof(T)" );
@@ -227,7 +246,7 @@ struct MPUDomain {
227246 uint32_t offsets_c[3 ] = {}; // D1, D2, D3
228247 uint32_t assigned_offsets[N];
229248
230- for (size_t align : alignments ) {
249+ for (size_t align : mpu_supported_alignments ) {
231250 for (size_t i = 0 ; i < N; i++) {
232251 if (entries[i].alignment == align) {
233252 size_t d_idx = static_cast <size_t >(entries[i].memory_domain ) - 1 ;
@@ -260,26 +279,33 @@ struct MPUDomain {
260279 void * ptr;
261280 std::size_t size;
262281
263- template <mpu_buffer_request auto & Target, typename ... Args>
264- auto & construct (Args&&... args) {
265- using T = typename std::remove_cvref_t <decltype (Target)>::buffer_type;
282+ template <auto & Target, typename ... Args> auto & construct (Args&&... args) {
283+ using Request = std::remove_cvref_t <decltype (Target)>;
284+ static_assert (mpu_buffer_request<Request>, " Target must be a valid MPUDomain buffer" );
285+ using T = typename Request::buffer_type;
266286 return *new (ptr) T (std::forward<Args>(args)...);
267287 }
268288
269- template <mpu_buffer_request auto & Target> auto * as () {
270- using T = typename std::remove_cvref_t <decltype (Target)>::buffer_type;
289+ template <auto & Target> auto * as () {
290+ using Request = std::remove_cvref_t <decltype (Target)>;
291+ static_assert (mpu_buffer_request<Request>, " Target must be a valid MPUDomain buffer" );
292+ using T = typename Request::buffer_type;
271293 return static_cast <T*>(ptr);
272294 }
273295 };
274296
275- template <typename Board, mpu_buffer_request auto & Target, typename ... Args>
297+ template <typename Board, auto & Target, typename ... Args>
276298 static auto & construct (Args&&... args) {
299+ using Request = std::remove_cvref_t <decltype (Target)>;
300+ static_assert (mpu_buffer_request<Request>, " Target must be a valid MPUDomain buffer" );
277301 return Board::template instance_of<Target>().template construct <Target>(
278302 std::forward<Args>(args)...
279303 );
280304 }
281305
282- template <typename Board, mpu_buffer_request auto & Target> static auto * as () {
306+ template <typename Board, auto & Target> static auto * as () {
307+ using Request = std::remove_cvref_t <decltype (Target)>;
308+ static_assert (mpu_buffer_request<Request>, " Target must be a valid MPUDomain buffer" );
283309 return Board::template instance_of<Target>().template as <Target>();
284310 }
285311
@@ -289,6 +315,17 @@ struct MPUDomain {
289315 static constexpr auto Sizes = calculate_total_sizes(cfgs);
290316
291317 // Sections defined in Linker Script (aligned to 32 bytes just in case)
318+ #ifdef SIM_ON
319+ alignas (32
320+ ) static inline uint8_t d1_nc_buffer[Sizes.d1_nc_total > 0 ? Sizes.d1_nc_total : 1];
321+ alignas (32 ) static inline uint8_t d1_c_buffer[Sizes.d1_c_total > 0 ? Sizes.d1_c_total : 1];
322+ alignas (32
323+ ) static inline uint8_t d2_nc_buffer[Sizes.d2_nc_total > 0 ? Sizes.d2_nc_total : 1];
324+ alignas (32 ) static inline uint8_t d2_c_buffer[Sizes.d2_c_total > 0 ? Sizes.d2_c_total : 1];
325+ alignas (32
326+ ) static inline uint8_t d3_nc_buffer[Sizes.d3_nc_total > 0 ? Sizes.d3_nc_total : 1];
327+ alignas (32 ) static inline uint8_t d3_c_buffer[Sizes.d3_c_total > 0 ? Sizes.d3_c_total : 1];
328+ #else
292329 __attribute__ ((section(" .mpu_ram_d1_nc.buffer" ))) alignas(32
293330 ) static inline uint8_t d1_nc_buffer[Sizes.d1_nc_total > 0 ? Sizes.d1_nc_total : 1];
294331 __attribute__ ((section(" .ram_d1.buffer" ))) alignas(32
@@ -303,6 +340,7 @@ struct MPUDomain {
303340 ) static inline uint8_t d3_nc_buffer[Sizes.d3_nc_total > 0 ? Sizes.d3_nc_total : 1];
304341 __attribute__ ((section(" .ram_d3.buffer" ))) alignas(32
305342 ) static inline uint8_t d3_c_buffer[Sizes.d3_c_total > 0 ? Sizes.d3_c_total : 1];
343+ #endif
306344
307345 static void init () {
308346 HAL_MPU_Disable ();
@@ -353,8 +391,6 @@ struct MPUDomain {
353391 };
354392
355393private:
356- static constexpr std::size_t alignments[6 ] = {32 , 16 , 8 , 4 , 2 , 1 };
357-
358394 static void configure_dynamic_region (uintptr_t start, uintptr_t end, uint8_t region_num) {
359395 if (end <= start)
360396 return ;
0 commit comments