<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>Other NXP ProductsのトピックProblem writing/reading shared ocram RT1170 EVKB</title>
    <link>https://community.nxp.com/t5/Other-NXP-Products/Problem-writing-reading-shared-ocram-RT1170-EVKB/m-p/2298599#M31097</link>
    <description>&lt;P&gt;I'm having troubles setting up shared ocram between M7 and M4 core on the RT1170 using the RT1170 EVKB and was hoping someone can help me. Been pulling my hair out for two days!&lt;BR /&gt;&lt;BR /&gt;I do get it to somewhat work but it is very inconsistent. I'm trying to write data to a shared buffer from M7, signal M4 using MCMGR and then read the data from ocram.&amp;nbsp;&lt;BR /&gt;&lt;BR /&gt;I have a section specifically for this buffer in both linkers and no other data is placed here and I think I have set the MPU_Config correctly to make all of ocram non-cacheable.&amp;nbsp;&lt;BR /&gt;&lt;BR /&gt;I do get MCMGR to trigger the M4 event handler reliably, but it doesn't consistently read the latest data written by M7. When messing around trying different stuff I sometimes get it to read the data, but then reading old data on the next MCMGR interrupt. When printing from the M7 I can clearly see the correct data is being written into the shared adresses.&amp;nbsp;&lt;BR /&gt;&amp;nbsp;&lt;BR /&gt;When printing the memory addresses from each core they are the same for each field in this struct and it does sometimes read correct data so I'm pretty confident we are actually operating on the same memory.&amp;nbsp;&lt;BR /&gt;&lt;BR /&gt;For testing enter a forever loop in M7 boot_task that increments counters and writes the data to the buffer every 2 seconds and trigger the M4 to read. The purpose is to have a ring buffer the m7 writes to but I got corrupted data so I scaled back to a simpler test which revealed something is off.&amp;nbsp;&lt;BR /&gt;&lt;BR /&gt;M7 print:&lt;BR /&gt;Buffer: 20270000, Magic: 20270000, Seq: 20270004, Len: 20270008, Data: 20270010&lt;BR /&gt;M4 print:&lt;BR /&gt;Buffer: 20270000, Magic: 20270000, Seq: 20270004, Len: 20270008, Data: 20270010&lt;/P&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;LI-CODE lang="markup"&gt;typedef struct __attribute__((aligned(32)))
{
    uint32_t magic;
    volatile uint32_t seq; /* increments each write from M7 */
    uint32_t len;
    uint32_t _pad0; /* padding */
    uint8_t data[IPC_TESTBUF_BYTES];
} ipc_testbuf_t;&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="markup"&gt;// M4 boot_task.c
extern "C" void boot_task(void *param)
{
    (void)param;
    PRINTF("\nM4 boot_task started");
    PRINTF("\n[M4] build time: %s, git %s\r\n", M4_BUILD_TIME, M4_GIT_SHA);

    /* Register IPC wake event handler ONCE */
    (void)MCMGR_RegisterEvent(ipc_message,
                             M4_ipc_event_handler,
                             (void*)0);
    PRINTF("\nRegistrer mcmgr event handler");

    /* 7) Signal M7 we are ready (boot complete) */
    {
        uint32_t startupData;
        mcmgr_status_t status;
        do { status = MCMGR_GetStartupData(&amp;amp;startupData); }
        while (status != kStatus_MCMGR_Success);

        (void)MCMGR_TriggerEvent(kMCMGR_RemoteApplicationEvent, 1U);
    }

    for (;;)
        vTaskDelay(pdMS_TO_TICKS(1000));
}

// M7 boot_task.c
void boot_task(void *param)
{
    (void)param;

    (void)MCMGR_Init();

    (void)MCMGR_RegisterEvent(kMCMGR_RemoteApplicationEvent,
                             RemoteAppReadyEventHandler,
                             (void *)&amp;amp;s_m4ReadyEventData);

    ipc_print_buffer_init_primary();

    PRINTF("\nStarting M4 core");
    (void)MCMGR_StartCore(kMCMGR_Core1,
                         (void *)(char *)CORE1_BOOT_ADDRESS,
                         0,
                         kMCMGR_Start_Synchronous);

    while (APP_READY_EVENT_DATA != s_m4ReadyEventData)
    {
    }
    PRINTF("\nM4 running");

    for (;;)
    {
        vTaskDelay(pdMS_TO_TICKS(2000));

        ipc_increment_seq_and_kick_m4();
    }

    vTaskDelete(NULL);
}


code/boards/rt1170/rt1170_shared/ipc_core.h
#pragma once

#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;stddef.h&amp;gt;

#include "mcmgr.h"
#include "FreeRTOS.h"
#include "task.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifndef ipc_message
#define ipc_message kMCMGR_FreeRtosMessageBuffersEvent
#endif

typedef enum
{
    IPC_PRINT_BUF        = 3,
} ipc_event_t;

/* --------------------------------------------------------------------------
 * Linker symbols (BOTH images) - for debug/sanity only
 * -------------------------------------------------------------------------- */
extern uint8_t __SHARED_PRINTF_START[]; /* ORIGIN(m_shared_printf) */
extern uint8_t __SHARED_PRINTF_SIZE[];  /* LENGTH(m_shared_printf)  */

/* section-content boundaries (debug only) */
extern uint8_t __SHARED_PRINTF_START__[];
extern uint8_t __SHARED_PRINTF_END__[];

/* --------------------------------------------------------------------------
 * Shared test buffer (M7 writes, M4 reads)
 * Lives in m_shared_printf (2 KB) via section ".shared_printf"
 * -------------------------------------------------------------------------- */
#ifndef IPC_TESTBUF_BYTES
#define IPC_TESTBUF_BYTES 128u
#endif

#define IPC_TESTBUF_MAGIC (0x54455354u) /* 'TEST' */

typedef struct __attribute__((aligned(32)))
{
    uint32_t magic;          
    volatile uint32_t seq;    /* increments each write from M7 */
    uint32_t len;             
    uint32_t _pad0;           /* padding */

    uint8_t data[IPC_TESTBUF_BYTES];
} ipc_testbuf_t;

/* Shared object placed in ".shared_printf" */
extern volatile ipc_testbuf_t g_ipc_testbuf;

/* CM7 ONLY: clear shared printf object once at boot, set initial values*/
void ipc_print_buffer_init_primary(void);

/* Accessor */
volatile ipc_testbuf_t *ipc_testbuf(void);

/* Test function */
void ipc_increment_seq_and_kick_m4();

void M4_ipc_event_handler(uint16_t eventData, void *context);

#ifdef __cplusplus
}
#endif


}

// code/boards/rt1170/rt1170_shared/ipc_core.c 
 // code/boards/rt1170/rt1170_shared/ipc_core.c
#include "ipc_core.h"

#include &amp;lt;string.h&amp;gt;
#include "fsl_debug_console.h"

#if defined(CPU_MIMXRT1176DVMAA_cm7)
#include "core_cm7.h"   /* SCB_CleanDCache_by_Addr */
#endif

/* --------------------------------------------------------------------------
 * Shared object allocated in linker-reserved shared OCRAM
 * MUST live in ".shared_printf" (m_shared_printf, 2KB)
 * -------------------------------------------------------------------------- */
__attribute__((section(".shared_printf"), aligned(32)))
volatile ipc_testbuf_t g_ipc_testbuf;

static inline void dmb(void)
{
#if defined(__ARMCC_VERSION) || defined(__GNUC__) || defined(__ICCARM__)
    __asm volatile ("dmb" ::: "memory");
#endif
}


volatile ipc_testbuf_t *ipc_testbuf(void)
{
    return &amp;amp;g_ipc_testbuf;
}

/* --------------------------------------------------------------------------
 * CM7 ONLY: clear the shared printf object once.
 * -------------------------------------------------------------------------- */
void ipc_clear_print_buffer(void)
{
    memset((void *)&amp;amp;g_ipc_testbuf, 0, sizeof(g_ipc_testbuf));
}

/* --------------------------------------------------------------------------
 * CM7: init + write + kick
 * -------------------------------------------------------------------------- */
void ipc_print_buffer_init_primary(void)
{
    ipc_clear_print_buffer();

    volatile ipc_testbuf_t *buffer = &amp;amp;g_ipc_testbuf;

    buffer-&amp;gt;magic = IPC_TESTBUF_MAGIC;
    buffer-&amp;gt;seq   = 0u;
    buffer-&amp;gt;len   = 0u;
    memset((void*)buffer-&amp;gt;data, 0, IPC_TESTBUF_BYTES);

    PRINTF("\nMagic: %u, Seq: %u, Len: %u",
                   buffer-&amp;gt;magic,
                   buffer-&amp;gt;seq,
                   buffer-&amp;gt;len);
}

void ipc_increment_seq_and_kick_m4()
{
    volatile ipc_testbuf_t *buffer = &amp;amp;g_ipc_testbuf;

    static int testCounter = 0;

    buffer-&amp;gt;magic = IPC_TESTBUF_MAGIC;
    buffer-&amp;gt;seq = testCounter;
    buffer-&amp;gt;len = testCounter;

    testCounter++;

    PRINTF("\nMagic: %u, Seq: %u, Len: %u",
                   buffer-&amp;gt;magic,
                   buffer-&amp;gt;seq,
                   buffer-&amp;gt;len);

    /* Tried cleaning cache but makes no difference, ocram should already be configured non cacheable */
    // __DMB();
    // SCB_CleanDCache_by_Addr((uint32_t*)buffer, sizeof(*buffer)); 
    // __DMB();

    /* Doorbell */
    (void)MCMGR_TriggerEventForce(ipc_message, (uint16_t)IPC_PRINT_BUF);
}

/* --------------------------------------------------------------------------
 * M4: event handler
 * -------------------------------------------------------------------------- */
#if defined(CPU_MIMXRT1176DVMAA_cm4)
void M4_ipc_event_handler(uint16_t eventData, void *context)
{
    (void)context;
    BaseType_t hpw = pdFALSE;
    static int eventsHandled = 0;

    switch ((ipc_event_t)eventData)
    {
        case IPC_PRINT_BUF:
        {
            // PRINTF here just for testing, printing from task makes no difference
            eventsHandled++;
            __DMB();
            volatile const ipc_testbuf_t *buffer = ipc_testbuf();

            uint32_t magic = buffer-&amp;gt;magic;
            uint32_t seq   = buffer-&amp;gt;seq;
            uint32_t len   = buffer-&amp;gt;len;

            PRINTF("\nEventsHandled: %d, Magic: %lu, Seq: %lu, Len: %lu",
                eventsHandled,
                (unsigned long)magic,
                (unsigned long)seq,
                (unsigned long)len);
            break;
        }
        default:
            break;
    }
    portYIELD_FROM_ISR(hpw);
}
#endif

Linkers:
// M7/armgcc/MIMXRT1176xxxxx_cm7_flexspi_nor.ld 
 /* M7/armgcc/MIMXRT1176xxxxx_cm7_flexspi_nor.ld
** M7 XIP-from-FlexSPI with OCRAM partition + M4 core1 image
*/

ENTRY(Reset_Handler)

HEAP_SIZE  = DEFINED(__heap_size__)  ? __heap_size__  : 0x0400;
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400;
RPMSG_SHMEM_SIZE = DEFINED(__use_shmem__) ? 0x2000 : 0;
VECTOR_RAM_SIZE = DEFINED(__ram_vector_table__) ? 0x00000400 : 0;

/* --- Reserve last 10 MB of 64 MB flash for M4 --- */
CORE1IMAGE_START = DEFINED(__use_flash64MB__) ? 0x33600000 : 0x30FC0000;

/* m_text starts at 0x30002400 */
TEXT_SIZE = CORE1IMAGE_START - 0x30002400;

/* --------------------------------------------------------------------------
 * Shared OCRAM regions (ONLY TWO):
 *  - m_shared_params  : 64 KB  (DSP parameter structs etc)
 *  - m_shared_printf  : 2 KB   (M7-&amp;gt;M4 printf buffer)
 * -------------------------------------------------------------------------- */
SHARED_PARAMS_SIZE = 0x00010000; /* 64 KB */
SHARED_PRINTF_SIZE = 0x00000800; /* 2 KB  */

MEMORY
{
  m_flash_config   (RX) : ORIGIN = 0x30000400, LENGTH = 0x00000C00
  m_ivt            (RX) : ORIGIN = 0x30001000, LENGTH = 0x00001000
  m_interrupts     (RX) : ORIGIN = 0x30002000, LENGTH = 0x00000400
  m_text           (RX) : ORIGIN = 0x30002400, LENGTH = TEXT_SIZE

  /* Renamed for clarity */
  m_itcm           (RX) : ORIGIN = 0x00000000, LENGTH = 0x00040000
  m_dtcm           (RW) : ORIGIN = 0x20000000, LENGTH = 0x00040000

  /* OCRAM 1MB: 0x20240000..0x2033FFFF (partitioned) */
  m_ncache_local   (RW) : ORIGIN = 0x20240000, LENGTH = 0x00020000  /* 128KB */

  /* Two explicit shared regions */
  m_shared_params  (RW) : ORIGIN = 0x20260000, LENGTH = SHARED_PARAMS_SIZE /* 64KB */
  m_shared_printf  (RW) : ORIGIN = 0x20270000, LENGTH = SHARED_PRINTF_SIZE /* 2KB  */

  m_ncache_audio1  (RW) : ORIGIN = 0x20280000, LENGTH = 0x00040000  /* 256KB */
  m_ncache_audio2  (RW) : ORIGIN = 0x202C0000, LENGTH = 0x00040000  /* 256KB */
  m_ncache_audio3  (RW) : ORIGIN = 0x20300000, LENGTH = 0x00040000  /* 256KB */

  m_core1_image    (RX) : ORIGIN = CORE1IMAGE_START, LENGTH = 0x00A00000
}

SECTIONS
{
  /* For existing SDK MPU hook on CM7: cover 0x20240000..0x2027FFFF */
  __NCACHE_REGION_START = ORIGIN(m_ncache_local);
  __NCACHE_REGION_SIZE  = 0x00040000; /* 256KB */

  /* Shared region base/size symbols */
  __SHARED_PARAMS_START = ORIGIN(m_shared_params);
  __SHARED_PARAMS_SIZE  = LENGTH(m_shared_params);

  __SHARED_PRINTF_START = ORIGIN(m_shared_printf);
  __SHARED_PRINTF_SIZE  = LENGTH(m_shared_printf);

  .flash_config :
  {
    . = ALIGN(4);
    __FLASH_BASE = .;
    KEEP(* (.boot_hdr.conf))
    . = ALIGN(4);
  } &amp;gt; m_flash_config

  ivt_begin = ORIGIN(m_flash_config) + LENGTH(m_flash_config);

  .ivt : AT(ivt_begin)
  {
    . = ALIGN(4);
    KEEP(* (.boot_hdr.ivt))
    KEEP(* (.boot_hdr.boot_data))
    KEEP(* (.boot_hdr.dcd_data))
    . = ALIGN(4);
  } &amp;gt; m_ivt

  .core1_code :
  {
     . = ALIGN(4);
     KEEP (*(.core1_code))
     *(.core1_code*)
     . = ALIGN(4);
  } &amp;gt; m_core1_image

  /* --------------------------------------------------------------------
   * Shared DSP params region (NOLOAD)
   * Place double-buffered param structs here later.
   * -------------------------------------------------------------------- */
  .shared_params (NOLOAD) :
  {
    . = ALIGN(32);
    __SHARED_PARAMS_START__ = .;

    *(.shared_params*)
    *(SharedParams*)

    . = ALIGN(32);
    __SHARED_PARAMS_END__ = .;

    ASSERT((__SHARED_PARAMS_END__ - __SHARED_PARAMS_START__) &amp;lt;= LENGTH(m_shared_params),
           "shared_params section too large");
  } &amp;gt; m_shared_params

  /* --------------------------------------------------------------------
   * Shared printf region (NOLOAD) - exclusive for M7-&amp;gt;M4 print buffer
   * -------------------------------------------------------------------- */
  .shared_printf (NOLOAD) :
  {
    . = ALIGN(32);
    __SHARED_PRINTF_START__ = .;

    *(.shared_printf*)
    *(SharedPrintf*)

    . = ALIGN(32);
    __SHARED_PRINTF_END__ = .;

    ASSERT((__SHARED_PRINTF_END__ - __SHARED_PRINTF_START__) &amp;lt;= LENGTH(m_shared_printf),
           "shared_printf section too large");
  } &amp;gt; m_shared_printf

  .interrupts :
  {
    __VECTOR_TABLE = .;
    __Vectors = .;
    . = ALIGN(4);
    KEEP(*(.isr_vector))
    . = ALIGN(4);
  } &amp;gt; m_interrupts

  .text :
  {
    . = ALIGN(4);
    *(.text)
    *(.text*)
    *(.rodata)
    *(.rodata*)
    *(.glue_7)
    *(.glue_7t)
    *(.eh_frame)
    KEEP (*(.init))
    KEEP (*(.fini))
    . = ALIGN(4);
  } &amp;gt; m_text

  .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } &amp;gt; m_text

  .ARM :
  {
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
  } &amp;gt; m_text

  .ctors :
  {
    __CTOR_LIST__ = .;
    KEEP (*crtbegin.o(.ctors))
    KEEP (*crtbegin?.o(.ctors))
    KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors))
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
    __CTOR_END__ = .;
  } &amp;gt; m_text

  .dtors :
  {
    __DTOR_LIST__ = .;
    KEEP (*crtbegin.o(.dtors))
    KEEP (*crtbegin?.o(.dtors))
    KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
    __DTOR_END__ = .;
  } &amp;gt; m_text

  .preinit_array :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } &amp;gt; m_text

  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
  } &amp;gt; m_text

  .fini_array :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
  } &amp;gt; m_text

  __etext = .;
  __DATA_ROM = .;

  .interrupts_ram :
  {
    . = ALIGN(4);
    __VECTOR_RAM__ = .;
    __interrupts_ram_start__ = .;
    *(.m_interrupts_ram)
    . += VECTOR_RAM_SIZE;
    . = ALIGN(4);
    __interrupts_ram_end__ = .;
  } &amp;gt; m_dtcm

  __VECTOR_RAM = DEFINED(__ram_vector_table__) ? __VECTOR_RAM__ : ORIGIN(m_interrupts);

  .data : AT(__DATA_ROM)
  {
    . = ALIGN(4);
    __DATA_RAM = .;
    __data_start__ = .;
    *(.data)
    *(.data*)
    *(DataQuickAccess)
    KEEP(*(.jcr*))
    . = ALIGN(4);
    __data_end__ = .;
  } &amp;gt; m_dtcm

  __ram_function_flash_start = __DATA_ROM + (__data_end__ - __data_start__);

  .ram_function : AT(__ram_function_flash_start)
  {
    . = ALIGN(32);
    __ram_function_start__ = .;
    *(CodeQuickAccess)
    . = ALIGN(128);
    __ram_function_end__ = .;
  } &amp;gt; m_itcm

  __NDATA_ROM = __ram_function_flash_start + (__ram_function_end__ - __ram_function_start__);

  /* M7 local NonCacheable sections stay in dtcm (your current script behavior) */
  .ncache.init : AT(__NDATA_ROM)
  {
    __noncachedata_start__ = .;
    *(NonCacheable.init)
    . = ALIGN(4);
    __noncachedata_init_end__ = .;
  } &amp;gt; m_dtcm

  . = __noncachedata_init_end__;
  .ncache :
  {
    *(NonCacheable)
    . = ALIGN(4);
    __noncachedata_end__ = .;
  } &amp;gt; m_dtcm

  __DATA_END = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_start__);
  text_end = ORIGIN(m_text) + LENGTH(m_text);
  ASSERT(__DATA_END &amp;lt;= text_end, "region m_text overflowed with text and data")

  .bss :
  {
    . = ALIGN(4);
    __bss_start__ = .;
    *(.bss)
    *(.bss*)
    *(COMMON)
    . = ALIGN(4);
    __bss_end__ = .;
  } &amp;gt; m_dtcm

  .heap :
  {
    . = ALIGN(8);
    __end__ = .;
    PROVIDE(end = .);
    __HeapBase = .;
    . += HEAP_SIZE;
    __HeapLimit = .;
    __heap_limit = .;
  } &amp;gt; m_dtcm

  .stack :
  {
    . = ALIGN(8);
    . += STACK_SIZE;
  } &amp;gt; m_dtcm

  __StackTop   = ORIGIN(m_dtcm) + LENGTH(m_dtcm);
  __StackLimit = __StackTop - STACK_SIZE;
  PROVIDE(__stack = __StackTop);

  .ARM.attributes 0 : { *(.ARM.attributes) }
}

ASSERT(__StackLimit &amp;gt;= __HeapLimit, "region m_dtcm overflowed with stack and heap");


}

// M4/armgcc/MIMXRT1176xxxxx_cm4_flexspi_nor.ld 
 /* M4/armgcc/MIMXRT1176xxxxx_cm4_flexspi_nor.ld
 * M4 XIP-from-FlexSPI with ITCM/DTCM hot sections + SDRAM
 * OCRAM split into: 128KB local ncache + shared params + shared printf + audio banks.
 */

ENTRY(Reset_Handler)

HEAP_SIZE  = DEFINED(__heap_size__)  ? __heap_size__  : 0x0400;
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400;

/* --------------------------------------------------------------------------
 * Shared OCRAM regions (ONLY TWO):
 *  - m_shared_params  : 64 KB  (DSP parameter structs etc)
 *  - m_shared_printf  : 2 KB   (M7-&amp;gt;M4 printf buffer)
 * -------------------------------------------------------------------------- */
SHARED_PARAMS_SIZE = 0x00010000; /* 64 KB */
SHARED_PRINTF_SIZE = 0x00000800; /* 2 KB  */

SDRAM_BASE        = 0x80000000;
SDRAM_SIZE        = 0x04000000; /* 64 MB */
SDRAM_C_SIZE      = 0x00800000; /* 8 MB cacheable */
SDRAM_NC_BASE     = SDRAM_BASE + SDRAM_C_SIZE; /* 0x80800000 */
SDRAM_NC_SIZE     = SDRAM_SIZE - SDRAM_C_SIZE; /* 56 MB */

M4_FLASH_BASE = 0x33600000;
M4_FLASH_SIZE = 0x00A00000;

MEMORY
{
  m_interrupts (RX) : ORIGIN = M4_FLASH_BASE,           LENGTH = 0x00000400
  m_text       (RX) : ORIGIN = M4_FLASH_BASE + 0x400,   LENGTH = M4_FLASH_SIZE - 0x00000400

  m_itcm       (RX) : ORIGIN = 0x1FFE0000, LENGTH = 0x00020000
  m_dtcm       (RW) : ORIGIN = 0x20000000, LENGTH = 0x00020000

  /* OCRAM 1MB partition */
  m_ncache_local   (RW) : ORIGIN = 0x20240000, LENGTH = 0x00020000  /* 128KB */

  /* Two explicit shared regions */
  m_shared_params  (RW) : ORIGIN = 0x20260000, LENGTH = SHARED_PARAMS_SIZE /* 64KB */
  m_shared_printf  (RW) : ORIGIN = 0x20270000, LENGTH = SHARED_PRINTF_SIZE /* 2KB  */

  m_ncache_audio1  (RW) : ORIGIN = 0x20280000, LENGTH = 0x00040000  /* 256KB */
  m_ncache_audio2  (RW) : ORIGIN = 0x202C0000, LENGTH = 0x00040000  /* 256KB */
  m_ncache_audio3  (RW) : ORIGIN = 0x20300000, LENGTH = 0x00040000  /* 256KB */

  m_sdram_c    (RW) : ORIGIN = SDRAM_BASE,    LENGTH = SDRAM_C_SIZE
  m_sdram_nc   (RW) : ORIGIN = SDRAM_NC_BASE, LENGTH = SDRAM_NC_SIZE
}

SECTIONS
{
  /* Shared region base/size symbols */
  __SHARED_PARAMS_START = ORIGIN(m_shared_params);
  __SHARED_PARAMS_SIZE  = LENGTH(m_shared_params);

  __SHARED_PRINTF_START = ORIGIN(m_shared_printf);
  __SHARED_PRINTF_SIZE  = LENGTH(m_shared_printf);

  /* M4 local non-cache region (used by your M4 MPU code path) */
  __NCACHE_REGION_START = ORIGIN(m_ncache_local);
  __NCACHE_REGION_SIZE  = LENGTH(m_ncache_local);

  /* --------------------------------------------------------------------
   * Shared DSP params region (NOLOAD)
   * -------------------------------------------------------------------- */
  .shared_params (NOLOAD) :
  {
    . = ALIGN(32);
    __SHARED_PARAMS_START__ = .;

    *(.shared_params*)
    *(SharedParams*)

    . = ALIGN(32);
    __SHARED_PARAMS_END__ = .;

    ASSERT((__SHARED_PARAMS_END__ - __SHARED_PARAMS_START__) &amp;lt;= LENGTH(m_shared_params),
           "shared_params section too large");
  } &amp;gt; m_shared_params

  /* --------------------------------------------------------------------
   * Shared printf region (NOLOAD) - exclusive for M7-&amp;gt;M4 print buffer
   * -------------------------------------------------------------------- */
  .shared_printf (NOLOAD) :
  {
    . = ALIGN(32);
    __SHARED_PRINTF_START__ = .;

    *(.shared_printf*)
    *(SharedPrintf*)

    . = ALIGN(32);
    __SHARED_PRINTF_END__ = .;

    ASSERT((__SHARED_PRINTF_END__ - __SHARED_PRINTF_START__) &amp;lt;= LENGTH(m_shared_printf),
           "shared_printf section too large");
  } &amp;gt; m_shared_printf

  .interrupts :
  {
    __VECTOR_TABLE = .;
    __Vectors = .;
    . = ALIGN(4);
    KEEP(*(.isr_vector))
    . = ALIGN(4);
  } &amp;gt; m_interrupts

  .text :
  {
    . = ALIGN(4);
    *(.text)
    *(.text*)
    *(.rodata)
    *(.rodata*)
    *(.glue_7)
    *(.glue_7t)
    *(.eh_frame)
    KEEP(*(.init))
    KEEP(*(.fini))
    . = ALIGN(4);
  } &amp;gt; m_text

  .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } &amp;gt; m_text

  .ARM :
  {
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
  } &amp;gt; m_text

  .ctors :
  {
    __CTOR_LIST__ = .;
    KEEP (*crtbegin.o(.ctors))
    KEEP (*crtbegin?.o(.ctors))
    KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors))
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
    __CTOR_END__ = .;
  } &amp;gt; m_text

  .dtors :
  {
    __DTOR_LIST__ = .;
    KEEP (*crtbegin.o(.dtors))
    KEEP (*crtbegin?.o(.dtors))
    KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
    __DTOR_END__ = .;
  } &amp;gt; m_text

  .preinit_array :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } &amp;gt; m_text

  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
  } &amp;gt; m_text

  .fini_array :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
  } &amp;gt; m_text

  __etext = .;
  __DATA_ROM = .;

  __itcm_text_load__ = __DATA_ROM;
  .itcm_text : AT(__itcm_text_load__)
  {
    . = ALIGN(32);
    __itcm_text_start__ = .;
    *(.itcm_text*)
    *(ITCM_TEXT*)
    . = ALIGN(32);
    __itcm_text_end__ = .;
  } &amp;gt; m_itcm

  __DATA_ROM_AFTER_ITCM = __itcm_text_load__ + (__itcm_text_end__ - __itcm_text_start__);

  __dtcm_data_load__ = __DATA_ROM_AFTER_ITCM;
  .dtcm_data : AT(__dtcm_data_load__)
  {
    . = ALIGN(32);
    __dtcm_data_start__ = .;
    *(.dtcm_data*)
    *(DTCM_DATA*)
    . = ALIGN(32);
    __dtcm_data_end__ = .;
  } &amp;gt; m_dtcm

  __DATA_ROM_AFTER_DTCM = __dtcm_data_load__ + (__dtcm_data_end__ - __dtcm_data_start__);
  __DATA_ROM = __DATA_ROM_AFTER_DTCM;

  .data : AT(__DATA_ROM)
  {
    . = ALIGN(4);
    __DATA_RAM = .;
    __data_start__ = .;
    *(.data)
    *(.data*)
    *(DataQuickAccess)
    KEEP(*(.jcr*))
    . = ALIGN(4);
    __data_end__ = .;
  } &amp;gt; m_dtcm

  __NDATA_ROM = __DATA_ROM + (__data_end__ - __data_start__);

  /* M4-local NonCacheable sections -&amp;gt; local 128KB */
  .ncache.init : AT(__NDATA_ROM)
  {
    __noncachedata_start__ = .;
    *(NonCacheable.init)
    . = ALIGN(4);
    __noncachedata_init_end__ = .;
  } &amp;gt; m_ncache_local

  .ncache (NOLOAD) :
  {
    *(NonCacheable)
    . = ALIGN(4);
    __noncachedata_end__ = .;
  } &amp;gt; m_ncache_local

  .bss (NOLOAD) :
  {
    . = ALIGN(4);
    __bss_start__ = .;
    *(.bss)
    *(.bss*)
    *(COMMON)
    . = ALIGN(4);
    __bss_end__ = .;
  } &amp;gt; m_dtcm

  .dtcm_bss (NOLOAD) :
  {
    . = ALIGN(32);
    __dtcm_bss_start__ = .;
    *(.dtcm_bss*)
    *(DTCM_BSS*)
    . = ALIGN(32);
    __dtcm_bss_end__ = .;
  } &amp;gt; m_dtcm

  /* ---------- Audio OCRAM banks (non-cacheable, NOLOAD) ---------- */
  .audio1_bss (NOLOAD) :
  {
    . = ALIGN(32);
    __audio1_bss_start__ = .;
    *(.audio1_bss*)
    . = ALIGN(32);
    __audio1_bss_end__ = .;
  } &amp;gt; m_ncache_audio1

  .audio2_bss (NOLOAD) :
  {
    . = ALIGN(32);
    __audio2_bss_start__ = .;
    *(.audio2_bss*)
    . = ALIGN(32);
    __audio2_bss_end__ = .;
  } &amp;gt; m_ncache_audio2

  .audio3_bss (NOLOAD) :
  {
    . = ALIGN(32);
    __audio3_bss_start__ = .;
    *(.audio3_bss*)
    . = ALIGN(32);
    __audio3_bss_end__ = .;
  } &amp;gt; m_ncache_audio3

  /* ---------- Cacheable SDRAM (8MB) ---------- */
  __SDRAM_C_DATA_ROM = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_start__);

  .sdram_c_data : AT(__SDRAM_C_DATA_ROM)
  {
    . = ALIGN(32);
    __sdram_c_data_start__ = .;
    *(.sdram_c_data*)
    *(SDRAM_C_DATA*)
    . = ALIGN(32);
    __sdram_c_data_end__ = .;
  } &amp;gt; m_sdram_c

  __sdram_c_data_load__ = __SDRAM_C_DATA_ROM;

  .sdram_c_bss (NOLOAD) :
  {
    . = ALIGN(32);
    __sdram_c_bss_start__ = .;
    *(.sdram_c_bss*)
    *(SDRAM_C_BSS*)
    . = ALIGN(32);
    __sdram_c_bss_end__ = .;
  } &amp;gt; m_sdram_c

  .sdram_nc_bss (NOLOAD) :
  {
    . = ALIGN(32);
    __sdram_nc_bss_start__ = .;
    *(.sdram_nc_bss*)
    *(SDRAM_NC_BSS*)
    . = ALIGN(32);
    __sdram_nc_bss_end__ = .;
  } &amp;gt; m_sdram_nc

  .heap :
  {
    . = ALIGN(8);
    __end__ = .;
    PROVIDE(end = .);
    __HeapBase = .;
    . += HEAP_SIZE;
    __HeapLimit = .;
    __heap_limit = .;
  } &amp;gt; m_dtcm

  .stack :
  {
    . = ALIGN(8);
    . += STACK_SIZE;
    __StackEnd = .;
  } &amp;gt; m_dtcm

  __StackTop   = ORIGIN(m_dtcm) + LENGTH(m_dtcm);
  __StackLimit = __StackTop - STACK_SIZE;
  PROVIDE(__stack = __StackTop);

  .ARM.attributes 0 : { *(.ARM.attributes) }

  __SDRAM_BASE      = SDRAM_BASE;
  __SDRAM_SIZE      = SDRAM_SIZE;
  __SDRAM_C_BASE    = SDRAM_BASE;
  __SDRAM_C_SIZE    = SDRAM_C_SIZE;
  __SDRAM_NC_BASE   = SDRAM_NC_BASE;
  __SDRAM_NC_SIZE   = SDRAM_NC_SIZE;
}
}

/* MPU configuration. */
#if __CORTEX_M == 7

void BOARD_ConfigMPU(void)
{
#if defined(__CC_ARM) || defined(__ARMCC_VERSION)
    extern uint32_t Image$$RW_m_ncache$$Base[];
    extern uint32_t Image$$RW_m_ncache_unused$$Base[];
    extern uint32_t Image$$RW_m_ncache_unused$$ZI$$Limit[];
    uint32_t nonCacheStart = (uint32_t)Image$$RW_m_ncache$$Base;
    uint32_t size          = ((uint32_t)Image$$RW_m_ncache_unused$$Base == nonCacheStart) ?
                                 0U :
                                 ((uint32_t)Image$$RW_m_ncache_unused$$ZI$$Limit - nonCacheStart);
#elif defined(__MCUXPRESSO)
#if defined(__USE_SHMEM)
    extern uint32_t __base_rpmsg_sh_mem;
    extern uint32_t __top_rpmsg_sh_mem;
    uint32_t nonCacheStart = (uint32_t)(&amp;amp;__base_rpmsg_sh_mem);
    uint32_t size          = (uint32_t)(&amp;amp;__top_rpmsg_sh_mem) - nonCacheStart;
#else
    extern uint32_t __base_NCACHE_REGION;
    extern uint32_t __top_NCACHE_REGION;
    uint32_t nonCacheStart = (uint32_t)(&amp;amp;__base_NCACHE_REGION);
    uint32_t size          = (uint32_t)(&amp;amp;__top_NCACHE_REGION) - nonCacheStart;
#endif
#elif defined(__ICCARM__) || defined(__GNUC__)
    extern uint32_t __NCACHE_REGION_START[];
    extern uint32_t __NCACHE_REGION_SIZE[];
    uint32_t nonCacheStart = (uint32_t)__NCACHE_REGION_START;
    uint32_t size          = (uint32_t)__NCACHE_REGION_SIZE;
#endif
    (void)nonCacheStart;
    (void)size;

#if defined(__ICACHE_PRESENT) &amp;amp;&amp;amp; __ICACHE_PRESENT
    if (SCB_CCR_IC_Msk == (SCB_CCR_IC_Msk &amp;amp; SCB-&amp;gt;CCR))
    {
        SCB_DisableICache();
    }
#endif
#if defined(__DCACHE_PRESENT) &amp;amp;&amp;amp; __DCACHE_PRESENT
    if (SCB_CCR_DC_Msk == (SCB_CCR_DC_Msk &amp;amp; SCB-&amp;gt;CCR))
    {
        SCB_DisableDCache();
    }
#endif

    ARM_MPU_Disable();

    /* Region 0: deny all (speculative prefetch workaround) */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(0, 0x00000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(1, ARM_MPU_AP_NONE, 0, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_4GB);

    /* Region 1: Device, not shareable, non-cacheable */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(1, 0x80000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_512MB);

    /* Region 2: Device, not shareable, non-cacheable */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(2, 0x60000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_512MB);

    /* Region 3: Device, not shareable, non-cacheable */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(3, 0x00000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1GB);

    /* Region 4: Normal, WB */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(4, 0x00000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_256KB);

    /* Region 5: Normal, WB */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(5, 0x20000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_256KB);

    /* --------------------------------------------------------------------
     * OCRAM (0x2024_0000..0x2033_FFFF, 1MB) must be NORMAL + NON-CACHEABLE + SHAREABLE.
     * Use 3 aligned regions:
     *   - 0x2024_0000 size 256KB
     *   - 0x2028_0000 size 512KB
     *   - 0x2030_0000 size 256KB
     *
     * Attributes: Normal, SHAREABLE, non-cacheable (TypeExt=1, S=1, C=0, B=0)
     * -------------------------------------------------------------------- */

    /* Region 6: OCRAM 256KB (SHAREABLE, non-cacheable) */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(6, 0x20240000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 1, 0, 0, 0, ARM_MPU_REGION_SIZE_256KB);

    /* Region 7: OCRAM 512KB (SHAREABLE, non-cacheable) */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(7, 0x20280000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 1, 0, 0, 0, ARM_MPU_REGION_SIZE_512KB);

    /* Region 10: OCRAM 256KB (SHAREABLE, non-cacheable) */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(10, 0x20300000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 1, 0, 0, 0, ARM_MPU_REGION_SIZE_256KB);

#if defined(CACHE_MODE_WRITE_THROUGH) &amp;amp;&amp;amp; CACHE_MODE_WRITE_THROUGH
    /* --- SDRAM: default NON-cacheable 64MB --- */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(11, 0x80000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_64MB);

    /* --- SDRAM: overlay first 8MB as cacheable (WT) --- */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(12, 0x80000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 0, 0, ARM_MPU_REGION_SIZE_8MB);
#else
    /* --- SDRAM: default NON-cacheable 64MB --- */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(11, 0x80000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_64MB);

    /* --- SDRAM: overlay first 8MB as cacheable (WB) --- */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(12, 0x80000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_8MB);
#endif

#if defined(XIP_EXTERNAL_FLASH) &amp;amp;&amp;amp; (XIP_EXTERNAL_FLASH == 1)
    /* Region 8: XIP external flash, RO, WB */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(8, 0x30000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_RO, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_16MB);
#endif

#ifdef USE_SDRAM
#if defined(CACHE_MODE_WRITE_THROUGH) &amp;amp;&amp;amp; CACHE_MODE_WRITE_THROUGH
    /* Region 9: SDRAM overall WT */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(9, 0x80000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 0, 0, ARM_MPU_REGION_SIZE_64MB);
#else
    /* Region 9: SDRAM overall WB */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(9, 0x80000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_64MB);
#endif
#endif

    /* Region 13..15: Device peripheral windows */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(13, 0x40000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_16MB);

    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(14, 0x41000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_2MB);

    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(15, 0x41400000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1MB);

    ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_HFNMIENA_Msk);

#if defined(__DCACHE_PRESENT) &amp;amp;&amp;amp; __DCACHE_PRESENT
    SCB_EnableDCache();
#endif
#if defined(__ICACHE_PRESENT) &amp;amp;&amp;amp; __ICACHE_PRESENT
    SCB_EnableICache();
#endif
}

#elif __CORTEX_M == 4

void BOARD_ConfigMPU(void)
{
    /* We still read these linker symbols for sanity/compatibility,
       but OCRAM MPU policy is configured explicitly below. */
#if defined(__CC_ARM) || defined(__ARMCC_VERSION)
    extern uint32_t Image$$RW_m_ncache$$Base[];
    extern uint32_t Image$$RW_m_ncache_unused$$Base[];
    extern uint32_t Image$$RW_m_ncache_unused$$ZI$$Limit[];
    uint32_t nonCacheStart = (uint32_t)Image$$RW_m_ncache$$Base;
    uint32_t nonCacheSize  = ((uint32_t)Image$$RW_m_ncache_unused$$Base == nonCacheStart) ?
                                 0U :
                                 ((uint32_t)Image$$RW_m_ncache_unused$$ZI$$Limit - nonCacheStart);
#elif defined(__MCUXPRESSO)
    extern uint32_t __base_NCACHE_REGION;
    extern uint32_t __top_NCACHE_REGION;
    uint32_t nonCacheStart = (uint32_t)(&amp;amp;__base_NCACHE_REGION);
    uint32_t nonCacheSize  = (uint32_t)(&amp;amp;__top_NCACHE_REGION) - nonCacheStart;
#elif defined(__ICCARM__) || defined(__GNUC__)
    extern uint32_t __NCACHE_REGION_START[];
    extern uint32_t __NCACHE_REGION_SIZE[];
    uint32_t nonCacheStart = (uint32_t)__NCACHE_REGION_START;
    uint32_t nonCacheSize  = (uint32_t)__NCACHE_REGION_SIZE;
#endif

    /* Only config non-cacheable region on system bus */
    assert(nonCacheStart &amp;gt;= 0x20000000U);

    /* ---- Disable code bus cache (LMEM) ---- */
    if (LMEM_PCCCR_ENCACHE_MASK == (LMEM_PCCCR_ENCACHE_MASK &amp;amp; LMEM-&amp;gt;PCCCR))
    {
        LMEM-&amp;gt;PCCCR |= LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK | LMEM_PCCCR_GO_MASK;
        while ((LMEM-&amp;gt;PCCCR &amp;amp; LMEM_PCCCR_GO_MASK) != 0U) {}
        LMEM-&amp;gt;PCCCR &amp;amp;= ~(LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK);
        LMEM-&amp;gt;PCCCR &amp;amp;= ~LMEM_PCCCR_ENCACHE_MASK;
    }

    /* ---- Disable system bus cache (LMEM) ---- */
    if (LMEM_PSCCR_ENCACHE_MASK == (LMEM_PSCCR_ENCACHE_MASK &amp;amp; LMEM-&amp;gt;PSCCR))
    {
        LMEM-&amp;gt;PSCCR |= LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK | LMEM_PSCCR_GO_MASK;
        while ((LMEM-&amp;gt;PSCCR &amp;amp; LMEM_PSCCR_GO_MASK) != 0U) {}
        LMEM-&amp;gt;PSCCR &amp;amp;= ~(LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK);
        LMEM-&amp;gt;PSCCR &amp;amp;= ~LMEM_PSCCR_ENCACHE_MASK;
    }

    ARM_MPU_Disable();

    /* --------------------------------------------------------------------
     * OCRAM (0x2024_0000..0x2033_FFFF, 1MB) must be NORMAL + NON-CACHEABLE + SHAREABLE.
     * Use 3 aligned regions:
     *   - 0x2024_0000 size 256KB
     *   - 0x2028_0000 size 512KB
     *   - 0x2030_0000 size 256KB
     *
     * Attributes: Normal, SHAREABLE, non-cacheable (TypeExt=1, S=1, C=0, B=0)
     * -------------------------------------------------------------------- */

    /* Region 0: OCRAM 256KB (SHAREABLE, non-cacheable) */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(0, 0x20240000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL,
                             1, /* TypeExtField=1 =&amp;gt; Normal non-cacheable */
                             1, /* Shareable = 1 */
                             0, /* Cacheable */
                             0, /* Bufferable */
                             0,
                             ARM_MPU_REGION_SIZE_256KB);

    /* Region 1: OCRAM 512KB (SHAREABLE, non-cacheable) */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(1, 0x20280000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 1, 0, 0, 0, ARM_MPU_REGION_SIZE_512KB);

    /* Region 2: OCRAM 256KB (SHAREABLE, non-cacheable) */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(2, 0x20300000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 1, 0, 0, 0, ARM_MPU_REGION_SIZE_256KB);

    /* Optional sanity check: local ncache region should live inside OCRAM. */
    (void)nonCacheSize;
    assert((nonCacheStart &amp;gt;= 0x20240000U) &amp;amp;&amp;amp; (nonCacheStart &amp;lt; 0x20340000U));

    ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_HFNMIENA_Msk);

    /* Invalidate and enable system bus cache */
    LMEM-&amp;gt;PSCCR |= LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK | LMEM_PSCCR_GO_MASK;
    while ((LMEM-&amp;gt;PSCCR &amp;amp; LMEM_PSCCR_GO_MASK) != 0U) {}
    LMEM-&amp;gt;PSCCR &amp;amp;= ~(LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK);
    LMEM-&amp;gt;PSCCR |= LMEM_PSCCR_ENCACHE_MASK;

    /* Invalidate and enable code bus cache */
    LMEM-&amp;gt;PCCCR |= LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_GO_MASK;
    while ((LMEM-&amp;gt;PCCCR &amp;amp; LMEM_PCCCR_GO_MASK) != 0U) {}
    LMEM-&amp;gt;PCCCR &amp;amp;= ~(LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK);
    LMEM-&amp;gt;PCCCR |= LMEM_PCCCR_ENCACHE_MASK;
}

#endif /* __CORTEX_M == 4 */&lt;/LI-CODE&gt;&lt;P&gt;&lt;BR /&gt;Print log:&amp;nbsp;&lt;/P&gt;&lt;P class=""&gt;EventsHandled: 1, Magic: 1413829460, Seq: 0, Len: 0&lt;BR /&gt;EventsHandled: 2, Magic: 1413829460, Seq: 0, Len: 0&lt;BR /&gt;EventsHandled: 3, Magic: 1413829460, Seq: 0, Len: 0&lt;BR /&gt;EventsHandled: 4, Magic: 1413829460, Seq: 0, Len: 0&lt;BR /&gt;EventsHandled: 5, Magic: 1413829460, Seq: 0, Len: 0&lt;BR /&gt;EventsHandled: 6, Magic: 1413829460, Seq: 0, Len: 0&lt;BR /&gt;EventsHandled: 7, Magic: 1413829460, Seq: 0, Len: 0&lt;BR /&gt;EventsHandled: 8, Magic: 1413829460, Seq: 0, Len: 0&lt;BR /&gt;EventsHandled: 9, Magic: 1413829460, Seq: 0, Len: 0&lt;BR /&gt;EventsHandled: 10, Magic: 1413829460, Seq: 0, Len: 0&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;</description>
    <pubDate>Thu, 22 Jan 2026 23:27:17 GMT</pubDate>
    <dc:creator>cyberhelmer</dc:creator>
    <dc:date>2026-01-22T23:27:17Z</dc:date>
    <item>
      <title>Problem writing/reading shared ocram RT1170 EVKB</title>
      <link>https://community.nxp.com/t5/Other-NXP-Products/Problem-writing-reading-shared-ocram-RT1170-EVKB/m-p/2298599#M31097</link>
      <description>&lt;P&gt;I'm having troubles setting up shared ocram between M7 and M4 core on the RT1170 using the RT1170 EVKB and was hoping someone can help me. Been pulling my hair out for two days!&lt;BR /&gt;&lt;BR /&gt;I do get it to somewhat work but it is very inconsistent. I'm trying to write data to a shared buffer from M7, signal M4 using MCMGR and then read the data from ocram.&amp;nbsp;&lt;BR /&gt;&lt;BR /&gt;I have a section specifically for this buffer in both linkers and no other data is placed here and I think I have set the MPU_Config correctly to make all of ocram non-cacheable.&amp;nbsp;&lt;BR /&gt;&lt;BR /&gt;I do get MCMGR to trigger the M4 event handler reliably, but it doesn't consistently read the latest data written by M7. When messing around trying different stuff I sometimes get it to read the data, but then reading old data on the next MCMGR interrupt. When printing from the M7 I can clearly see the correct data is being written into the shared adresses.&amp;nbsp;&lt;BR /&gt;&amp;nbsp;&lt;BR /&gt;When printing the memory addresses from each core they are the same for each field in this struct and it does sometimes read correct data so I'm pretty confident we are actually operating on the same memory.&amp;nbsp;&lt;BR /&gt;&lt;BR /&gt;For testing enter a forever loop in M7 boot_task that increments counters and writes the data to the buffer every 2 seconds and trigger the M4 to read. The purpose is to have a ring buffer the m7 writes to but I got corrupted data so I scaled back to a simpler test which revealed something is off.&amp;nbsp;&lt;BR /&gt;&lt;BR /&gt;M7 print:&lt;BR /&gt;Buffer: 20270000, Magic: 20270000, Seq: 20270004, Len: 20270008, Data: 20270010&lt;BR /&gt;M4 print:&lt;BR /&gt;Buffer: 20270000, Magic: 20270000, Seq: 20270004, Len: 20270008, Data: 20270010&lt;/P&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;LI-CODE lang="markup"&gt;typedef struct __attribute__((aligned(32)))
{
    uint32_t magic;
    volatile uint32_t seq; /* increments each write from M7 */
    uint32_t len;
    uint32_t _pad0; /* padding */
    uint8_t data[IPC_TESTBUF_BYTES];
} ipc_testbuf_t;&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="markup"&gt;// M4 boot_task.c
extern "C" void boot_task(void *param)
{
    (void)param;
    PRINTF("\nM4 boot_task started");
    PRINTF("\n[M4] build time: %s, git %s\r\n", M4_BUILD_TIME, M4_GIT_SHA);

    /* Register IPC wake event handler ONCE */
    (void)MCMGR_RegisterEvent(ipc_message,
                             M4_ipc_event_handler,
                             (void*)0);
    PRINTF("\nRegistrer mcmgr event handler");

    /* 7) Signal M7 we are ready (boot complete) */
    {
        uint32_t startupData;
        mcmgr_status_t status;
        do { status = MCMGR_GetStartupData(&amp;amp;startupData); }
        while (status != kStatus_MCMGR_Success);

        (void)MCMGR_TriggerEvent(kMCMGR_RemoteApplicationEvent, 1U);
    }

    for (;;)
        vTaskDelay(pdMS_TO_TICKS(1000));
}

// M7 boot_task.c
void boot_task(void *param)
{
    (void)param;

    (void)MCMGR_Init();

    (void)MCMGR_RegisterEvent(kMCMGR_RemoteApplicationEvent,
                             RemoteAppReadyEventHandler,
                             (void *)&amp;amp;s_m4ReadyEventData);

    ipc_print_buffer_init_primary();

    PRINTF("\nStarting M4 core");
    (void)MCMGR_StartCore(kMCMGR_Core1,
                         (void *)(char *)CORE1_BOOT_ADDRESS,
                         0,
                         kMCMGR_Start_Synchronous);

    while (APP_READY_EVENT_DATA != s_m4ReadyEventData)
    {
    }
    PRINTF("\nM4 running");

    for (;;)
    {
        vTaskDelay(pdMS_TO_TICKS(2000));

        ipc_increment_seq_and_kick_m4();
    }

    vTaskDelete(NULL);
}


code/boards/rt1170/rt1170_shared/ipc_core.h
#pragma once

#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;stddef.h&amp;gt;

#include "mcmgr.h"
#include "FreeRTOS.h"
#include "task.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifndef ipc_message
#define ipc_message kMCMGR_FreeRtosMessageBuffersEvent
#endif

typedef enum
{
    IPC_PRINT_BUF        = 3,
} ipc_event_t;

/* --------------------------------------------------------------------------
 * Linker symbols (BOTH images) - for debug/sanity only
 * -------------------------------------------------------------------------- */
extern uint8_t __SHARED_PRINTF_START[]; /* ORIGIN(m_shared_printf) */
extern uint8_t __SHARED_PRINTF_SIZE[];  /* LENGTH(m_shared_printf)  */

/* section-content boundaries (debug only) */
extern uint8_t __SHARED_PRINTF_START__[];
extern uint8_t __SHARED_PRINTF_END__[];

/* --------------------------------------------------------------------------
 * Shared test buffer (M7 writes, M4 reads)
 * Lives in m_shared_printf (2 KB) via section ".shared_printf"
 * -------------------------------------------------------------------------- */
#ifndef IPC_TESTBUF_BYTES
#define IPC_TESTBUF_BYTES 128u
#endif

#define IPC_TESTBUF_MAGIC (0x54455354u) /* 'TEST' */

typedef struct __attribute__((aligned(32)))
{
    uint32_t magic;          
    volatile uint32_t seq;    /* increments each write from M7 */
    uint32_t len;             
    uint32_t _pad0;           /* padding */

    uint8_t data[IPC_TESTBUF_BYTES];
} ipc_testbuf_t;

/* Shared object placed in ".shared_printf" */
extern volatile ipc_testbuf_t g_ipc_testbuf;

/* CM7 ONLY: clear shared printf object once at boot, set initial values*/
void ipc_print_buffer_init_primary(void);

/* Accessor */
volatile ipc_testbuf_t *ipc_testbuf(void);

/* Test function */
void ipc_increment_seq_and_kick_m4();

void M4_ipc_event_handler(uint16_t eventData, void *context);

#ifdef __cplusplus
}
#endif


}

// code/boards/rt1170/rt1170_shared/ipc_core.c 
 // code/boards/rt1170/rt1170_shared/ipc_core.c
#include "ipc_core.h"

#include &amp;lt;string.h&amp;gt;
#include "fsl_debug_console.h"

#if defined(CPU_MIMXRT1176DVMAA_cm7)
#include "core_cm7.h"   /* SCB_CleanDCache_by_Addr */
#endif

/* --------------------------------------------------------------------------
 * Shared object allocated in linker-reserved shared OCRAM
 * MUST live in ".shared_printf" (m_shared_printf, 2KB)
 * -------------------------------------------------------------------------- */
__attribute__((section(".shared_printf"), aligned(32)))
volatile ipc_testbuf_t g_ipc_testbuf;

static inline void dmb(void)
{
#if defined(__ARMCC_VERSION) || defined(__GNUC__) || defined(__ICCARM__)
    __asm volatile ("dmb" ::: "memory");
#endif
}


volatile ipc_testbuf_t *ipc_testbuf(void)
{
    return &amp;amp;g_ipc_testbuf;
}

/* --------------------------------------------------------------------------
 * CM7 ONLY: clear the shared printf object once.
 * -------------------------------------------------------------------------- */
void ipc_clear_print_buffer(void)
{
    memset((void *)&amp;amp;g_ipc_testbuf, 0, sizeof(g_ipc_testbuf));
}

/* --------------------------------------------------------------------------
 * CM7: init + write + kick
 * -------------------------------------------------------------------------- */
void ipc_print_buffer_init_primary(void)
{
    ipc_clear_print_buffer();

    volatile ipc_testbuf_t *buffer = &amp;amp;g_ipc_testbuf;

    buffer-&amp;gt;magic = IPC_TESTBUF_MAGIC;
    buffer-&amp;gt;seq   = 0u;
    buffer-&amp;gt;len   = 0u;
    memset((void*)buffer-&amp;gt;data, 0, IPC_TESTBUF_BYTES);

    PRINTF("\nMagic: %u, Seq: %u, Len: %u",
                   buffer-&amp;gt;magic,
                   buffer-&amp;gt;seq,
                   buffer-&amp;gt;len);
}

void ipc_increment_seq_and_kick_m4()
{
    volatile ipc_testbuf_t *buffer = &amp;amp;g_ipc_testbuf;

    static int testCounter = 0;

    buffer-&amp;gt;magic = IPC_TESTBUF_MAGIC;
    buffer-&amp;gt;seq = testCounter;
    buffer-&amp;gt;len = testCounter;

    testCounter++;

    PRINTF("\nMagic: %u, Seq: %u, Len: %u",
                   buffer-&amp;gt;magic,
                   buffer-&amp;gt;seq,
                   buffer-&amp;gt;len);

    /* Tried cleaning cache but makes no difference, ocram should already be configured non cacheable */
    // __DMB();
    // SCB_CleanDCache_by_Addr((uint32_t*)buffer, sizeof(*buffer)); 
    // __DMB();

    /* Doorbell */
    (void)MCMGR_TriggerEventForce(ipc_message, (uint16_t)IPC_PRINT_BUF);
}

/* --------------------------------------------------------------------------
 * M4: event handler
 * -------------------------------------------------------------------------- */
#if defined(CPU_MIMXRT1176DVMAA_cm4)
void M4_ipc_event_handler(uint16_t eventData, void *context)
{
    (void)context;
    BaseType_t hpw = pdFALSE;
    static int eventsHandled = 0;

    switch ((ipc_event_t)eventData)
    {
        case IPC_PRINT_BUF:
        {
            // PRINTF here just for testing, printing from task makes no difference
            eventsHandled++;
            __DMB();
            volatile const ipc_testbuf_t *buffer = ipc_testbuf();

            uint32_t magic = buffer-&amp;gt;magic;
            uint32_t seq   = buffer-&amp;gt;seq;
            uint32_t len   = buffer-&amp;gt;len;

            PRINTF("\nEventsHandled: %d, Magic: %lu, Seq: %lu, Len: %lu",
                eventsHandled,
                (unsigned long)magic,
                (unsigned long)seq,
                (unsigned long)len);
            break;
        }
        default:
            break;
    }
    portYIELD_FROM_ISR(hpw);
}
#endif

Linkers:
// M7/armgcc/MIMXRT1176xxxxx_cm7_flexspi_nor.ld 
 /* M7/armgcc/MIMXRT1176xxxxx_cm7_flexspi_nor.ld
** M7 XIP-from-FlexSPI with OCRAM partition + M4 core1 image
*/

ENTRY(Reset_Handler)

HEAP_SIZE  = DEFINED(__heap_size__)  ? __heap_size__  : 0x0400;
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400;
RPMSG_SHMEM_SIZE = DEFINED(__use_shmem__) ? 0x2000 : 0;
VECTOR_RAM_SIZE = DEFINED(__ram_vector_table__) ? 0x00000400 : 0;

/* --- Reserve last 10 MB of 64 MB flash for M4 --- */
CORE1IMAGE_START = DEFINED(__use_flash64MB__) ? 0x33600000 : 0x30FC0000;

/* m_text starts at 0x30002400 */
TEXT_SIZE = CORE1IMAGE_START - 0x30002400;

/* --------------------------------------------------------------------------
 * Shared OCRAM regions (ONLY TWO):
 *  - m_shared_params  : 64 KB  (DSP parameter structs etc)
 *  - m_shared_printf  : 2 KB   (M7-&amp;gt;M4 printf buffer)
 * -------------------------------------------------------------------------- */
SHARED_PARAMS_SIZE = 0x00010000; /* 64 KB */
SHARED_PRINTF_SIZE = 0x00000800; /* 2 KB  */

MEMORY
{
  m_flash_config   (RX) : ORIGIN = 0x30000400, LENGTH = 0x00000C00
  m_ivt            (RX) : ORIGIN = 0x30001000, LENGTH = 0x00001000
  m_interrupts     (RX) : ORIGIN = 0x30002000, LENGTH = 0x00000400
  m_text           (RX) : ORIGIN = 0x30002400, LENGTH = TEXT_SIZE

  /* Renamed for clarity */
  m_itcm           (RX) : ORIGIN = 0x00000000, LENGTH = 0x00040000
  m_dtcm           (RW) : ORIGIN = 0x20000000, LENGTH = 0x00040000

  /* OCRAM 1MB: 0x20240000..0x2033FFFF (partitioned) */
  m_ncache_local   (RW) : ORIGIN = 0x20240000, LENGTH = 0x00020000  /* 128KB */

  /* Two explicit shared regions */
  m_shared_params  (RW) : ORIGIN = 0x20260000, LENGTH = SHARED_PARAMS_SIZE /* 64KB */
  m_shared_printf  (RW) : ORIGIN = 0x20270000, LENGTH = SHARED_PRINTF_SIZE /* 2KB  */

  m_ncache_audio1  (RW) : ORIGIN = 0x20280000, LENGTH = 0x00040000  /* 256KB */
  m_ncache_audio2  (RW) : ORIGIN = 0x202C0000, LENGTH = 0x00040000  /* 256KB */
  m_ncache_audio3  (RW) : ORIGIN = 0x20300000, LENGTH = 0x00040000  /* 256KB */

  m_core1_image    (RX) : ORIGIN = CORE1IMAGE_START, LENGTH = 0x00A00000
}

SECTIONS
{
  /* For existing SDK MPU hook on CM7: cover 0x20240000..0x2027FFFF */
  __NCACHE_REGION_START = ORIGIN(m_ncache_local);
  __NCACHE_REGION_SIZE  = 0x00040000; /* 256KB */

  /* Shared region base/size symbols */
  __SHARED_PARAMS_START = ORIGIN(m_shared_params);
  __SHARED_PARAMS_SIZE  = LENGTH(m_shared_params);

  __SHARED_PRINTF_START = ORIGIN(m_shared_printf);
  __SHARED_PRINTF_SIZE  = LENGTH(m_shared_printf);

  .flash_config :
  {
    . = ALIGN(4);
    __FLASH_BASE = .;
    KEEP(* (.boot_hdr.conf))
    . = ALIGN(4);
  } &amp;gt; m_flash_config

  ivt_begin = ORIGIN(m_flash_config) + LENGTH(m_flash_config);

  .ivt : AT(ivt_begin)
  {
    . = ALIGN(4);
    KEEP(* (.boot_hdr.ivt))
    KEEP(* (.boot_hdr.boot_data))
    KEEP(* (.boot_hdr.dcd_data))
    . = ALIGN(4);
  } &amp;gt; m_ivt

  .core1_code :
  {
     . = ALIGN(4);
     KEEP (*(.core1_code))
     *(.core1_code*)
     . = ALIGN(4);
  } &amp;gt; m_core1_image

  /* --------------------------------------------------------------------
   * Shared DSP params region (NOLOAD)
   * Place double-buffered param structs here later.
   * -------------------------------------------------------------------- */
  .shared_params (NOLOAD) :
  {
    . = ALIGN(32);
    __SHARED_PARAMS_START__ = .;

    *(.shared_params*)
    *(SharedParams*)

    . = ALIGN(32);
    __SHARED_PARAMS_END__ = .;

    ASSERT((__SHARED_PARAMS_END__ - __SHARED_PARAMS_START__) &amp;lt;= LENGTH(m_shared_params),
           "shared_params section too large");
  } &amp;gt; m_shared_params

  /* --------------------------------------------------------------------
   * Shared printf region (NOLOAD) - exclusive for M7-&amp;gt;M4 print buffer
   * -------------------------------------------------------------------- */
  .shared_printf (NOLOAD) :
  {
    . = ALIGN(32);
    __SHARED_PRINTF_START__ = .;

    *(.shared_printf*)
    *(SharedPrintf*)

    . = ALIGN(32);
    __SHARED_PRINTF_END__ = .;

    ASSERT((__SHARED_PRINTF_END__ - __SHARED_PRINTF_START__) &amp;lt;= LENGTH(m_shared_printf),
           "shared_printf section too large");
  } &amp;gt; m_shared_printf

  .interrupts :
  {
    __VECTOR_TABLE = .;
    __Vectors = .;
    . = ALIGN(4);
    KEEP(*(.isr_vector))
    . = ALIGN(4);
  } &amp;gt; m_interrupts

  .text :
  {
    . = ALIGN(4);
    *(.text)
    *(.text*)
    *(.rodata)
    *(.rodata*)
    *(.glue_7)
    *(.glue_7t)
    *(.eh_frame)
    KEEP (*(.init))
    KEEP (*(.fini))
    . = ALIGN(4);
  } &amp;gt; m_text

  .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } &amp;gt; m_text

  .ARM :
  {
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
  } &amp;gt; m_text

  .ctors :
  {
    __CTOR_LIST__ = .;
    KEEP (*crtbegin.o(.ctors))
    KEEP (*crtbegin?.o(.ctors))
    KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors))
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
    __CTOR_END__ = .;
  } &amp;gt; m_text

  .dtors :
  {
    __DTOR_LIST__ = .;
    KEEP (*crtbegin.o(.dtors))
    KEEP (*crtbegin?.o(.dtors))
    KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
    __DTOR_END__ = .;
  } &amp;gt; m_text

  .preinit_array :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } &amp;gt; m_text

  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
  } &amp;gt; m_text

  .fini_array :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
  } &amp;gt; m_text

  __etext = .;
  __DATA_ROM = .;

  .interrupts_ram :
  {
    . = ALIGN(4);
    __VECTOR_RAM__ = .;
    __interrupts_ram_start__ = .;
    *(.m_interrupts_ram)
    . += VECTOR_RAM_SIZE;
    . = ALIGN(4);
    __interrupts_ram_end__ = .;
  } &amp;gt; m_dtcm

  __VECTOR_RAM = DEFINED(__ram_vector_table__) ? __VECTOR_RAM__ : ORIGIN(m_interrupts);

  .data : AT(__DATA_ROM)
  {
    . = ALIGN(4);
    __DATA_RAM = .;
    __data_start__ = .;
    *(.data)
    *(.data*)
    *(DataQuickAccess)
    KEEP(*(.jcr*))
    . = ALIGN(4);
    __data_end__ = .;
  } &amp;gt; m_dtcm

  __ram_function_flash_start = __DATA_ROM + (__data_end__ - __data_start__);

  .ram_function : AT(__ram_function_flash_start)
  {
    . = ALIGN(32);
    __ram_function_start__ = .;
    *(CodeQuickAccess)
    . = ALIGN(128);
    __ram_function_end__ = .;
  } &amp;gt; m_itcm

  __NDATA_ROM = __ram_function_flash_start + (__ram_function_end__ - __ram_function_start__);

  /* M7 local NonCacheable sections stay in dtcm (your current script behavior) */
  .ncache.init : AT(__NDATA_ROM)
  {
    __noncachedata_start__ = .;
    *(NonCacheable.init)
    . = ALIGN(4);
    __noncachedata_init_end__ = .;
  } &amp;gt; m_dtcm

  . = __noncachedata_init_end__;
  .ncache :
  {
    *(NonCacheable)
    . = ALIGN(4);
    __noncachedata_end__ = .;
  } &amp;gt; m_dtcm

  __DATA_END = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_start__);
  text_end = ORIGIN(m_text) + LENGTH(m_text);
  ASSERT(__DATA_END &amp;lt;= text_end, "region m_text overflowed with text and data")

  .bss :
  {
    . = ALIGN(4);
    __bss_start__ = .;
    *(.bss)
    *(.bss*)
    *(COMMON)
    . = ALIGN(4);
    __bss_end__ = .;
  } &amp;gt; m_dtcm

  .heap :
  {
    . = ALIGN(8);
    __end__ = .;
    PROVIDE(end = .);
    __HeapBase = .;
    . += HEAP_SIZE;
    __HeapLimit = .;
    __heap_limit = .;
  } &amp;gt; m_dtcm

  .stack :
  {
    . = ALIGN(8);
    . += STACK_SIZE;
  } &amp;gt; m_dtcm

  __StackTop   = ORIGIN(m_dtcm) + LENGTH(m_dtcm);
  __StackLimit = __StackTop - STACK_SIZE;
  PROVIDE(__stack = __StackTop);

  .ARM.attributes 0 : { *(.ARM.attributes) }
}

ASSERT(__StackLimit &amp;gt;= __HeapLimit, "region m_dtcm overflowed with stack and heap");


}

// M4/armgcc/MIMXRT1176xxxxx_cm4_flexspi_nor.ld 
 /* M4/armgcc/MIMXRT1176xxxxx_cm4_flexspi_nor.ld
 * M4 XIP-from-FlexSPI with ITCM/DTCM hot sections + SDRAM
 * OCRAM split into: 128KB local ncache + shared params + shared printf + audio banks.
 */

ENTRY(Reset_Handler)

HEAP_SIZE  = DEFINED(__heap_size__)  ? __heap_size__  : 0x0400;
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400;

/* --------------------------------------------------------------------------
 * Shared OCRAM regions (ONLY TWO):
 *  - m_shared_params  : 64 KB  (DSP parameter structs etc)
 *  - m_shared_printf  : 2 KB   (M7-&amp;gt;M4 printf buffer)
 * -------------------------------------------------------------------------- */
SHARED_PARAMS_SIZE = 0x00010000; /* 64 KB */
SHARED_PRINTF_SIZE = 0x00000800; /* 2 KB  */

SDRAM_BASE        = 0x80000000;
SDRAM_SIZE        = 0x04000000; /* 64 MB */
SDRAM_C_SIZE      = 0x00800000; /* 8 MB cacheable */
SDRAM_NC_BASE     = SDRAM_BASE + SDRAM_C_SIZE; /* 0x80800000 */
SDRAM_NC_SIZE     = SDRAM_SIZE - SDRAM_C_SIZE; /* 56 MB */

M4_FLASH_BASE = 0x33600000;
M4_FLASH_SIZE = 0x00A00000;

MEMORY
{
  m_interrupts (RX) : ORIGIN = M4_FLASH_BASE,           LENGTH = 0x00000400
  m_text       (RX) : ORIGIN = M4_FLASH_BASE + 0x400,   LENGTH = M4_FLASH_SIZE - 0x00000400

  m_itcm       (RX) : ORIGIN = 0x1FFE0000, LENGTH = 0x00020000
  m_dtcm       (RW) : ORIGIN = 0x20000000, LENGTH = 0x00020000

  /* OCRAM 1MB partition */
  m_ncache_local   (RW) : ORIGIN = 0x20240000, LENGTH = 0x00020000  /* 128KB */

  /* Two explicit shared regions */
  m_shared_params  (RW) : ORIGIN = 0x20260000, LENGTH = SHARED_PARAMS_SIZE /* 64KB */
  m_shared_printf  (RW) : ORIGIN = 0x20270000, LENGTH = SHARED_PRINTF_SIZE /* 2KB  */

  m_ncache_audio1  (RW) : ORIGIN = 0x20280000, LENGTH = 0x00040000  /* 256KB */
  m_ncache_audio2  (RW) : ORIGIN = 0x202C0000, LENGTH = 0x00040000  /* 256KB */
  m_ncache_audio3  (RW) : ORIGIN = 0x20300000, LENGTH = 0x00040000  /* 256KB */

  m_sdram_c    (RW) : ORIGIN = SDRAM_BASE,    LENGTH = SDRAM_C_SIZE
  m_sdram_nc   (RW) : ORIGIN = SDRAM_NC_BASE, LENGTH = SDRAM_NC_SIZE
}

SECTIONS
{
  /* Shared region base/size symbols */
  __SHARED_PARAMS_START = ORIGIN(m_shared_params);
  __SHARED_PARAMS_SIZE  = LENGTH(m_shared_params);

  __SHARED_PRINTF_START = ORIGIN(m_shared_printf);
  __SHARED_PRINTF_SIZE  = LENGTH(m_shared_printf);

  /* M4 local non-cache region (used by your M4 MPU code path) */
  __NCACHE_REGION_START = ORIGIN(m_ncache_local);
  __NCACHE_REGION_SIZE  = LENGTH(m_ncache_local);

  /* --------------------------------------------------------------------
   * Shared DSP params region (NOLOAD)
   * -------------------------------------------------------------------- */
  .shared_params (NOLOAD) :
  {
    . = ALIGN(32);
    __SHARED_PARAMS_START__ = .;

    *(.shared_params*)
    *(SharedParams*)

    . = ALIGN(32);
    __SHARED_PARAMS_END__ = .;

    ASSERT((__SHARED_PARAMS_END__ - __SHARED_PARAMS_START__) &amp;lt;= LENGTH(m_shared_params),
           "shared_params section too large");
  } &amp;gt; m_shared_params

  /* --------------------------------------------------------------------
   * Shared printf region (NOLOAD) - exclusive for M7-&amp;gt;M4 print buffer
   * -------------------------------------------------------------------- */
  .shared_printf (NOLOAD) :
  {
    . = ALIGN(32);
    __SHARED_PRINTF_START__ = .;

    *(.shared_printf*)
    *(SharedPrintf*)

    . = ALIGN(32);
    __SHARED_PRINTF_END__ = .;

    ASSERT((__SHARED_PRINTF_END__ - __SHARED_PRINTF_START__) &amp;lt;= LENGTH(m_shared_printf),
           "shared_printf section too large");
  } &amp;gt; m_shared_printf

  .interrupts :
  {
    __VECTOR_TABLE = .;
    __Vectors = .;
    . = ALIGN(4);
    KEEP(*(.isr_vector))
    . = ALIGN(4);
  } &amp;gt; m_interrupts

  .text :
  {
    . = ALIGN(4);
    *(.text)
    *(.text*)
    *(.rodata)
    *(.rodata*)
    *(.glue_7)
    *(.glue_7t)
    *(.eh_frame)
    KEEP(*(.init))
    KEEP(*(.fini))
    . = ALIGN(4);
  } &amp;gt; m_text

  .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } &amp;gt; m_text

  .ARM :
  {
    __exidx_start = .;
    *(.ARM.exidx*)
    __exidx_end = .;
  } &amp;gt; m_text

  .ctors :
  {
    __CTOR_LIST__ = .;
    KEEP (*crtbegin.o(.ctors))
    KEEP (*crtbegin?.o(.ctors))
    KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors))
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
    __CTOR_END__ = .;
  } &amp;gt; m_text

  .dtors :
  {
    __DTOR_LIST__ = .;
    KEEP (*crtbegin.o(.dtors))
    KEEP (*crtbegin?.o(.dtors))
    KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
    __DTOR_END__ = .;
  } &amp;gt; m_text

  .preinit_array :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  } &amp;gt; m_text

  .init_array :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);
  } &amp;gt; m_text

  .fini_array :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);
  } &amp;gt; m_text

  __etext = .;
  __DATA_ROM = .;

  __itcm_text_load__ = __DATA_ROM;
  .itcm_text : AT(__itcm_text_load__)
  {
    . = ALIGN(32);
    __itcm_text_start__ = .;
    *(.itcm_text*)
    *(ITCM_TEXT*)
    . = ALIGN(32);
    __itcm_text_end__ = .;
  } &amp;gt; m_itcm

  __DATA_ROM_AFTER_ITCM = __itcm_text_load__ + (__itcm_text_end__ - __itcm_text_start__);

  __dtcm_data_load__ = __DATA_ROM_AFTER_ITCM;
  .dtcm_data : AT(__dtcm_data_load__)
  {
    . = ALIGN(32);
    __dtcm_data_start__ = .;
    *(.dtcm_data*)
    *(DTCM_DATA*)
    . = ALIGN(32);
    __dtcm_data_end__ = .;
  } &amp;gt; m_dtcm

  __DATA_ROM_AFTER_DTCM = __dtcm_data_load__ + (__dtcm_data_end__ - __dtcm_data_start__);
  __DATA_ROM = __DATA_ROM_AFTER_DTCM;

  .data : AT(__DATA_ROM)
  {
    . = ALIGN(4);
    __DATA_RAM = .;
    __data_start__ = .;
    *(.data)
    *(.data*)
    *(DataQuickAccess)
    KEEP(*(.jcr*))
    . = ALIGN(4);
    __data_end__ = .;
  } &amp;gt; m_dtcm

  __NDATA_ROM = __DATA_ROM + (__data_end__ - __data_start__);

  /* M4-local NonCacheable sections -&amp;gt; local 128KB */
  .ncache.init : AT(__NDATA_ROM)
  {
    __noncachedata_start__ = .;
    *(NonCacheable.init)
    . = ALIGN(4);
    __noncachedata_init_end__ = .;
  } &amp;gt; m_ncache_local

  .ncache (NOLOAD) :
  {
    *(NonCacheable)
    . = ALIGN(4);
    __noncachedata_end__ = .;
  } &amp;gt; m_ncache_local

  .bss (NOLOAD) :
  {
    . = ALIGN(4);
    __bss_start__ = .;
    *(.bss)
    *(.bss*)
    *(COMMON)
    . = ALIGN(4);
    __bss_end__ = .;
  } &amp;gt; m_dtcm

  .dtcm_bss (NOLOAD) :
  {
    . = ALIGN(32);
    __dtcm_bss_start__ = .;
    *(.dtcm_bss*)
    *(DTCM_BSS*)
    . = ALIGN(32);
    __dtcm_bss_end__ = .;
  } &amp;gt; m_dtcm

  /* ---------- Audio OCRAM banks (non-cacheable, NOLOAD) ---------- */
  .audio1_bss (NOLOAD) :
  {
    . = ALIGN(32);
    __audio1_bss_start__ = .;
    *(.audio1_bss*)
    . = ALIGN(32);
    __audio1_bss_end__ = .;
  } &amp;gt; m_ncache_audio1

  .audio2_bss (NOLOAD) :
  {
    . = ALIGN(32);
    __audio2_bss_start__ = .;
    *(.audio2_bss*)
    . = ALIGN(32);
    __audio2_bss_end__ = .;
  } &amp;gt; m_ncache_audio2

  .audio3_bss (NOLOAD) :
  {
    . = ALIGN(32);
    __audio3_bss_start__ = .;
    *(.audio3_bss*)
    . = ALIGN(32);
    __audio3_bss_end__ = .;
  } &amp;gt; m_ncache_audio3

  /* ---------- Cacheable SDRAM (8MB) ---------- */
  __SDRAM_C_DATA_ROM = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_start__);

  .sdram_c_data : AT(__SDRAM_C_DATA_ROM)
  {
    . = ALIGN(32);
    __sdram_c_data_start__ = .;
    *(.sdram_c_data*)
    *(SDRAM_C_DATA*)
    . = ALIGN(32);
    __sdram_c_data_end__ = .;
  } &amp;gt; m_sdram_c

  __sdram_c_data_load__ = __SDRAM_C_DATA_ROM;

  .sdram_c_bss (NOLOAD) :
  {
    . = ALIGN(32);
    __sdram_c_bss_start__ = .;
    *(.sdram_c_bss*)
    *(SDRAM_C_BSS*)
    . = ALIGN(32);
    __sdram_c_bss_end__ = .;
  } &amp;gt; m_sdram_c

  .sdram_nc_bss (NOLOAD) :
  {
    . = ALIGN(32);
    __sdram_nc_bss_start__ = .;
    *(.sdram_nc_bss*)
    *(SDRAM_NC_BSS*)
    . = ALIGN(32);
    __sdram_nc_bss_end__ = .;
  } &amp;gt; m_sdram_nc

  .heap :
  {
    . = ALIGN(8);
    __end__ = .;
    PROVIDE(end = .);
    __HeapBase = .;
    . += HEAP_SIZE;
    __HeapLimit = .;
    __heap_limit = .;
  } &amp;gt; m_dtcm

  .stack :
  {
    . = ALIGN(8);
    . += STACK_SIZE;
    __StackEnd = .;
  } &amp;gt; m_dtcm

  __StackTop   = ORIGIN(m_dtcm) + LENGTH(m_dtcm);
  __StackLimit = __StackTop - STACK_SIZE;
  PROVIDE(__stack = __StackTop);

  .ARM.attributes 0 : { *(.ARM.attributes) }

  __SDRAM_BASE      = SDRAM_BASE;
  __SDRAM_SIZE      = SDRAM_SIZE;
  __SDRAM_C_BASE    = SDRAM_BASE;
  __SDRAM_C_SIZE    = SDRAM_C_SIZE;
  __SDRAM_NC_BASE   = SDRAM_NC_BASE;
  __SDRAM_NC_SIZE   = SDRAM_NC_SIZE;
}
}

/* MPU configuration. */
#if __CORTEX_M == 7

void BOARD_ConfigMPU(void)
{
#if defined(__CC_ARM) || defined(__ARMCC_VERSION)
    extern uint32_t Image$$RW_m_ncache$$Base[];
    extern uint32_t Image$$RW_m_ncache_unused$$Base[];
    extern uint32_t Image$$RW_m_ncache_unused$$ZI$$Limit[];
    uint32_t nonCacheStart = (uint32_t)Image$$RW_m_ncache$$Base;
    uint32_t size          = ((uint32_t)Image$$RW_m_ncache_unused$$Base == nonCacheStart) ?
                                 0U :
                                 ((uint32_t)Image$$RW_m_ncache_unused$$ZI$$Limit - nonCacheStart);
#elif defined(__MCUXPRESSO)
#if defined(__USE_SHMEM)
    extern uint32_t __base_rpmsg_sh_mem;
    extern uint32_t __top_rpmsg_sh_mem;
    uint32_t nonCacheStart = (uint32_t)(&amp;amp;__base_rpmsg_sh_mem);
    uint32_t size          = (uint32_t)(&amp;amp;__top_rpmsg_sh_mem) - nonCacheStart;
#else
    extern uint32_t __base_NCACHE_REGION;
    extern uint32_t __top_NCACHE_REGION;
    uint32_t nonCacheStart = (uint32_t)(&amp;amp;__base_NCACHE_REGION);
    uint32_t size          = (uint32_t)(&amp;amp;__top_NCACHE_REGION) - nonCacheStart;
#endif
#elif defined(__ICCARM__) || defined(__GNUC__)
    extern uint32_t __NCACHE_REGION_START[];
    extern uint32_t __NCACHE_REGION_SIZE[];
    uint32_t nonCacheStart = (uint32_t)__NCACHE_REGION_START;
    uint32_t size          = (uint32_t)__NCACHE_REGION_SIZE;
#endif
    (void)nonCacheStart;
    (void)size;

#if defined(__ICACHE_PRESENT) &amp;amp;&amp;amp; __ICACHE_PRESENT
    if (SCB_CCR_IC_Msk == (SCB_CCR_IC_Msk &amp;amp; SCB-&amp;gt;CCR))
    {
        SCB_DisableICache();
    }
#endif
#if defined(__DCACHE_PRESENT) &amp;amp;&amp;amp; __DCACHE_PRESENT
    if (SCB_CCR_DC_Msk == (SCB_CCR_DC_Msk &amp;amp; SCB-&amp;gt;CCR))
    {
        SCB_DisableDCache();
    }
#endif

    ARM_MPU_Disable();

    /* Region 0: deny all (speculative prefetch workaround) */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(0, 0x00000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(1, ARM_MPU_AP_NONE, 0, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_4GB);

    /* Region 1: Device, not shareable, non-cacheable */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(1, 0x80000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_512MB);

    /* Region 2: Device, not shareable, non-cacheable */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(2, 0x60000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_512MB);

    /* Region 3: Device, not shareable, non-cacheable */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(3, 0x00000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1GB);

    /* Region 4: Normal, WB */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(4, 0x00000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_256KB);

    /* Region 5: Normal, WB */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(5, 0x20000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_256KB);

    /* --------------------------------------------------------------------
     * OCRAM (0x2024_0000..0x2033_FFFF, 1MB) must be NORMAL + NON-CACHEABLE + SHAREABLE.
     * Use 3 aligned regions:
     *   - 0x2024_0000 size 256KB
     *   - 0x2028_0000 size 512KB
     *   - 0x2030_0000 size 256KB
     *
     * Attributes: Normal, SHAREABLE, non-cacheable (TypeExt=1, S=1, C=0, B=0)
     * -------------------------------------------------------------------- */

    /* Region 6: OCRAM 256KB (SHAREABLE, non-cacheable) */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(6, 0x20240000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 1, 0, 0, 0, ARM_MPU_REGION_SIZE_256KB);

    /* Region 7: OCRAM 512KB (SHAREABLE, non-cacheable) */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(7, 0x20280000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 1, 0, 0, 0, ARM_MPU_REGION_SIZE_512KB);

    /* Region 10: OCRAM 256KB (SHAREABLE, non-cacheable) */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(10, 0x20300000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 1, 0, 0, 0, ARM_MPU_REGION_SIZE_256KB);

#if defined(CACHE_MODE_WRITE_THROUGH) &amp;amp;&amp;amp; CACHE_MODE_WRITE_THROUGH
    /* --- SDRAM: default NON-cacheable 64MB --- */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(11, 0x80000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_64MB);

    /* --- SDRAM: overlay first 8MB as cacheable (WT) --- */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(12, 0x80000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 0, 0, ARM_MPU_REGION_SIZE_8MB);
#else
    /* --- SDRAM: default NON-cacheable 64MB --- */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(11, 0x80000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_64MB);

    /* --- SDRAM: overlay first 8MB as cacheable (WB) --- */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(12, 0x80000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_8MB);
#endif

#if defined(XIP_EXTERNAL_FLASH) &amp;amp;&amp;amp; (XIP_EXTERNAL_FLASH == 1)
    /* Region 8: XIP external flash, RO, WB */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(8, 0x30000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_RO, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_16MB);
#endif

#ifdef USE_SDRAM
#if defined(CACHE_MODE_WRITE_THROUGH) &amp;amp;&amp;amp; CACHE_MODE_WRITE_THROUGH
    /* Region 9: SDRAM overall WT */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(9, 0x80000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 0, 0, ARM_MPU_REGION_SIZE_64MB);
#else
    /* Region 9: SDRAM overall WB */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(9, 0x80000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_64MB);
#endif
#endif

    /* Region 13..15: Device peripheral windows */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(13, 0x40000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_16MB);

    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(14, 0x41000000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_2MB);

    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(15, 0x41400000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1MB);

    ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_HFNMIENA_Msk);

#if defined(__DCACHE_PRESENT) &amp;amp;&amp;amp; __DCACHE_PRESENT
    SCB_EnableDCache();
#endif
#if defined(__ICACHE_PRESENT) &amp;amp;&amp;amp; __ICACHE_PRESENT
    SCB_EnableICache();
#endif
}

#elif __CORTEX_M == 4

void BOARD_ConfigMPU(void)
{
    /* We still read these linker symbols for sanity/compatibility,
       but OCRAM MPU policy is configured explicitly below. */
#if defined(__CC_ARM) || defined(__ARMCC_VERSION)
    extern uint32_t Image$$RW_m_ncache$$Base[];
    extern uint32_t Image$$RW_m_ncache_unused$$Base[];
    extern uint32_t Image$$RW_m_ncache_unused$$ZI$$Limit[];
    uint32_t nonCacheStart = (uint32_t)Image$$RW_m_ncache$$Base;
    uint32_t nonCacheSize  = ((uint32_t)Image$$RW_m_ncache_unused$$Base == nonCacheStart) ?
                                 0U :
                                 ((uint32_t)Image$$RW_m_ncache_unused$$ZI$$Limit - nonCacheStart);
#elif defined(__MCUXPRESSO)
    extern uint32_t __base_NCACHE_REGION;
    extern uint32_t __top_NCACHE_REGION;
    uint32_t nonCacheStart = (uint32_t)(&amp;amp;__base_NCACHE_REGION);
    uint32_t nonCacheSize  = (uint32_t)(&amp;amp;__top_NCACHE_REGION) - nonCacheStart;
#elif defined(__ICCARM__) || defined(__GNUC__)
    extern uint32_t __NCACHE_REGION_START[];
    extern uint32_t __NCACHE_REGION_SIZE[];
    uint32_t nonCacheStart = (uint32_t)__NCACHE_REGION_START;
    uint32_t nonCacheSize  = (uint32_t)__NCACHE_REGION_SIZE;
#endif

    /* Only config non-cacheable region on system bus */
    assert(nonCacheStart &amp;gt;= 0x20000000U);

    /* ---- Disable code bus cache (LMEM) ---- */
    if (LMEM_PCCCR_ENCACHE_MASK == (LMEM_PCCCR_ENCACHE_MASK &amp;amp; LMEM-&amp;gt;PCCCR))
    {
        LMEM-&amp;gt;PCCCR |= LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK | LMEM_PCCCR_GO_MASK;
        while ((LMEM-&amp;gt;PCCCR &amp;amp; LMEM_PCCCR_GO_MASK) != 0U) {}
        LMEM-&amp;gt;PCCCR &amp;amp;= ~(LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK);
        LMEM-&amp;gt;PCCCR &amp;amp;= ~LMEM_PCCCR_ENCACHE_MASK;
    }

    /* ---- Disable system bus cache (LMEM) ---- */
    if (LMEM_PSCCR_ENCACHE_MASK == (LMEM_PSCCR_ENCACHE_MASK &amp;amp; LMEM-&amp;gt;PSCCR))
    {
        LMEM-&amp;gt;PSCCR |= LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK | LMEM_PSCCR_GO_MASK;
        while ((LMEM-&amp;gt;PSCCR &amp;amp; LMEM_PSCCR_GO_MASK) != 0U) {}
        LMEM-&amp;gt;PSCCR &amp;amp;= ~(LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK);
        LMEM-&amp;gt;PSCCR &amp;amp;= ~LMEM_PSCCR_ENCACHE_MASK;
    }

    ARM_MPU_Disable();

    /* --------------------------------------------------------------------
     * OCRAM (0x2024_0000..0x2033_FFFF, 1MB) must be NORMAL + NON-CACHEABLE + SHAREABLE.
     * Use 3 aligned regions:
     *   - 0x2024_0000 size 256KB
     *   - 0x2028_0000 size 512KB
     *   - 0x2030_0000 size 256KB
     *
     * Attributes: Normal, SHAREABLE, non-cacheable (TypeExt=1, S=1, C=0, B=0)
     * -------------------------------------------------------------------- */

    /* Region 0: OCRAM 256KB (SHAREABLE, non-cacheable) */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(0, 0x20240000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL,
                             1, /* TypeExtField=1 =&amp;gt; Normal non-cacheable */
                             1, /* Shareable = 1 */
                             0, /* Cacheable */
                             0, /* Bufferable */
                             0,
                             ARM_MPU_REGION_SIZE_256KB);

    /* Region 1: OCRAM 512KB (SHAREABLE, non-cacheable) */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(1, 0x20280000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 1, 0, 0, 0, ARM_MPU_REGION_SIZE_512KB);

    /* Region 2: OCRAM 256KB (SHAREABLE, non-cacheable) */
    MPU-&amp;gt;RBAR = ARM_MPU_RBAR(2, 0x20300000U);
    MPU-&amp;gt;RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 1, 0, 0, 0, ARM_MPU_REGION_SIZE_256KB);

    /* Optional sanity check: local ncache region should live inside OCRAM. */
    (void)nonCacheSize;
    assert((nonCacheStart &amp;gt;= 0x20240000U) &amp;amp;&amp;amp; (nonCacheStart &amp;lt; 0x20340000U));

    ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_HFNMIENA_Msk);

    /* Invalidate and enable system bus cache */
    LMEM-&amp;gt;PSCCR |= LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK | LMEM_PSCCR_GO_MASK;
    while ((LMEM-&amp;gt;PSCCR &amp;amp; LMEM_PSCCR_GO_MASK) != 0U) {}
    LMEM-&amp;gt;PSCCR &amp;amp;= ~(LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK);
    LMEM-&amp;gt;PSCCR |= LMEM_PSCCR_ENCACHE_MASK;

    /* Invalidate and enable code bus cache */
    LMEM-&amp;gt;PCCCR |= LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_GO_MASK;
    while ((LMEM-&amp;gt;PCCCR &amp;amp; LMEM_PCCCR_GO_MASK) != 0U) {}
    LMEM-&amp;gt;PCCCR &amp;amp;= ~(LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK);
    LMEM-&amp;gt;PCCCR |= LMEM_PCCCR_ENCACHE_MASK;
}

#endif /* __CORTEX_M == 4 */&lt;/LI-CODE&gt;&lt;P&gt;&lt;BR /&gt;Print log:&amp;nbsp;&lt;/P&gt;&lt;P class=""&gt;EventsHandled: 1, Magic: 1413829460, Seq: 0, Len: 0&lt;BR /&gt;EventsHandled: 2, Magic: 1413829460, Seq: 0, Len: 0&lt;BR /&gt;EventsHandled: 3, Magic: 1413829460, Seq: 0, Len: 0&lt;BR /&gt;EventsHandled: 4, Magic: 1413829460, Seq: 0, Len: 0&lt;BR /&gt;EventsHandled: 5, Magic: 1413829460, Seq: 0, Len: 0&lt;BR /&gt;EventsHandled: 6, Magic: 1413829460, Seq: 0, Len: 0&lt;BR /&gt;EventsHandled: 7, Magic: 1413829460, Seq: 0, Len: 0&lt;BR /&gt;EventsHandled: 8, Magic: 1413829460, Seq: 0, Len: 0&lt;BR /&gt;EventsHandled: 9, Magic: 1413829460, Seq: 0, Len: 0&lt;BR /&gt;EventsHandled: 10, Magic: 1413829460, Seq: 0, Len: 0&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 22 Jan 2026 23:27:17 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Other-NXP-Products/Problem-writing-reading-shared-ocram-RT1170-EVKB/m-p/2298599#M31097</guid>
      <dc:creator>cyberhelmer</dc:creator>
      <dc:date>2026-01-22T23:27:17Z</dc:date>
    </item>
    <item>
      <title>Re: Problem writing/reading shared ocram RT1170 EVKB</title>
      <link>https://community.nxp.com/t5/Other-NXP-Products/Problem-writing-reading-shared-ocram-RT1170-EVKB/m-p/2300710#M31106</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://community.nxp.com/t5/user/viewprofilepage/user-id/251274"&gt;@cyberhelmer&lt;/a&gt;,&lt;/P&gt;
&lt;P&gt;I do see your setup to make OCRAM non-cacheable on&amp;nbsp;BOARD_ConfigMPU(), but at the very end of this routine, you have the following:&lt;/P&gt;
&lt;PRE class="lia-code-sample  language-markup"&gt;&lt;CODE&gt;    /* Invalidate and enable system bus cache */
    LMEM-&amp;gt;PSCCR |= LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK | LMEM_PSCCR_GO_MASK;
    while ((LMEM-&amp;gt;PSCCR &amp;amp; LMEM_PSCCR_GO_MASK) != 0U) {}
    LMEM-&amp;gt;PSCCR &amp;amp;= ~(LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK);
    LMEM-&amp;gt;PSCCR |= LMEM_PSCCR_ENCACHE_MASK;

    /* Invalidate and enable code bus cache */
    LMEM-&amp;gt;PCCCR |= LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_GO_MASK;
    while ((LMEM-&amp;gt;PCCCR &amp;amp; LMEM_PCCCR_GO_MASK) != 0U) {}
    LMEM-&amp;gt;PCCCR &amp;amp;= ~(LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK);
    LMEM-&amp;gt;PCCCR |= LMEM_PCCCR_ENCACHE_MASK;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;By the end of&amp;nbsp;BOARD_ConfigMPU(), which is basically the start of your application, you re-enable system and code bus cache, which might be causing a mismatch between what the M7 is writing vs what the M4 is reading.&lt;/P&gt;
&lt;P&gt;Try commenting out these lines as a quick test to see if this changes anything between the reading/writing of the shared memory address.&lt;/P&gt;
&lt;P&gt;BR,&lt;BR /&gt;Edwin.&lt;/P&gt;</description>
      <pubDate>Mon, 26 Jan 2026 22:39:43 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Other-NXP-Products/Problem-writing-reading-shared-ocram-RT1170-EVKB/m-p/2300710#M31106</guid>
      <dc:creator>EdwinHz</dc:creator>
      <dc:date>2026-01-26T22:39:43Z</dc:date>
    </item>
    <item>
      <title>Re: Problem writing/reading shared ocram RT1170 EVKB</title>
      <link>https://community.nxp.com/t5/Other-NXP-Products/Problem-writing-reading-shared-ocram-RT1170-EVKB/m-p/2304837#M31147</link>
      <description>&lt;P&gt;Thanks, but I think the problem was with the linker and the memory I was testing was actually not ending up at the correct region which the mpu config had set to non cacheable!&amp;nbsp;&lt;BR /&gt;&lt;BR /&gt;So I think it's solved, need to do some more test to me 100% sure.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 02 Feb 2026 21:41:12 GMT</pubDate>
      <guid>https://community.nxp.com/t5/Other-NXP-Products/Problem-writing-reading-shared-ocram-RT1170-EVKB/m-p/2304837#M31147</guid>
      <dc:creator>cyberhelmer</dc:creator>
      <dc:date>2026-02-02T21:41:12Z</dc:date>
    </item>
  </channel>
</rss>

