diff --git a/src/modm/platform/core/cortex/module.lb b/src/modm/platform/core/cortex/module.lb index c9e446e88a..577c2fe045 100644 --- a/src/modm/platform/core/cortex/module.lb +++ b/src/modm/platform/core/cortex/module.lb @@ -330,6 +330,9 @@ def validate(env): def build(env): env.substitutions = env.query("vector_table") + core = env.substitutions["core"] + with_icache = "m7" in core + with_dcache = with_icache and not (env.has_module(":platform:dma") or env.has_module(":platform:bdma")) env.substitutions.update({ "target": env[":target"].identifier, "with_fault_storage": env.has_module(":platform:fault"), @@ -337,10 +340,15 @@ def build(env): "with_assert": env.has_module(":architecture:assert"), "with_fpu": env.get("float-abi", "soft") != "soft", "with_multicore": env.has_module(":platform:multicore"), - "with_msplim": sum(c.isnumeric() for c in env.substitutions["core"]) == 2, + "with_msplim": sum(c.isnumeric() for c in core) == 2, + "with_icache": with_icache, + "with_dcache": with_dcache, }) env.outbasepath = "modm/src/modm/platform/core" + if env.substitutions["with_icache"] and not env.substitutions["with_dcache"]: + env.log.warning("Cortex-M7 D-Cache is disabled due to using DMA!") + # startup script env.template("reset_handler.sx.in") env.template("startup.c.in") diff --git a/src/modm/platform/core/cortex/module.md b/src/modm/platform/core/cortex/module.md index 557726863c..eeb86f04bc 100644 --- a/src/modm/platform/core/cortex/module.md +++ b/src/modm/platform/core/cortex/module.md @@ -19,7 +19,7 @@ implemented as follows: 3. Call `modm_initialize_platform()` to initialize the custom device hardware. 4. Copy data to internal RAM. 5. Zero sections in internal RAM. -6. Initialize ARM Cortex-M core: enable FPU and relocate vector table. +6. Initialize ARM Cortex-M core: enable FPU, caches and relocate vector table. 7. Execute shared hardware initialization functions. 8. Copy data to *external* RAM. 9. Zero sections in *external* RAM. @@ -62,11 +62,11 @@ perhaps even write this function in Assembly if deemed necessary. ### Cache Initialization -For Cortex-M7 devices, both the I-Cache and D-Cache are enabled by default with -a write-through policy to significantly improve performance. However, it is -important to note that manual invalidation of the caches is required on certain -operations, such as when writing to Flash (I-Cache) or when using DMA -(D-Cache). See the [CMSIS-Core documentation][cache_api] for more info. +For Cortex-M7 devices, the I-Cache is enabled by default. The D-Cache with a +write-back write-allocate policy is only enabled if the `modm:platform:dma` +module is NOT selected. modm currently does not support allocating DMA buffers +in non-cachable regions or granular cache invalidation. See the +[CMSIS-Core Cache API][cache_api] for more information on cache management. ### Additional Initialization diff --git a/src/modm/platform/core/cortex/startup.c.in b/src/modm/platform/core/cortex/startup.c.in index 453d9f3b32..8a48fd4ca9 100644 --- a/src/modm/platform/core/cortex/startup.c.in +++ b/src/modm/platform/core/cortex/startup.c.in @@ -24,6 +24,8 @@ // ---------------------------------------------------------------------------- // Default implementation of platform initialization modm_weak void modm_initialize_platform(void) {} +extern void __modm_initialize_memory(void); +extern int main(void); // ---------------------------------------------------------------------------- // Linker section start and end pointers @@ -96,26 +98,28 @@ void __modm_startup(void) // Copy and zero all internal memory table_copy(__table_copy_intern_start, __table_copy_intern_end); table_zero(__table_zero_intern_start, __table_zero_intern_end); - -%% if "m7" in core +%# +%% if with_icache // Enable instruction cache SCB_InvalidateICache(); SCB_EnableICache(); - // Enable data cache with write-through policy +%% endif +%% if with_dcache + // Enable data cache with default WBWA policy SCB_InvalidateDCache(); SCB_EnableDCache(); %% endif - +%# %% if core != "cortex-m0" // Set the vector table location SCB->VTOR = (uint32_t)__vector_table_{{ vector_table_location }}_start; %% endif - +%# %% if "m0" not in core // Enable trapping of divide by zero for UDIV/SDIV instructions. SCB->CCR |= SCB_CCR_DIV_0_TRP_Msk; %% endif - +%# // Call all hardware initialize hooks table_call(__hardware_init_start, __hardware_init_end); @@ -124,16 +128,14 @@ void __modm_startup(void) table_zero(__table_zero_extern_start, __table_zero_extern_end); // Initialize heap as implemented by the heap option - extern void __modm_initialize_memory(void); __modm_initialize_memory(); // Call all constructors of static objects table_call(__init_array_start, __init_array_end); // Call the application's entry point - extern int main(void); main(); - +%# %% if with_assert // If main exits, assert here in debug mode (void) modm_assert_continue_fail_debug(0,