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!
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.
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.
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.
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.
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.
M7 print:
Buffer: 20270000, Magic: 20270000, Seq: 20270004, Len: 20270008, Data: 20270010
M4 print:
Buffer: 20270000, Magic: 20270000, Seq: 20270004, Len: 20270008, Data: 20270010
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;
// 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(&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 *)&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 <stdint.h>
#include <stddef.h>
#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 <string.h>
#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 &g_ipc_testbuf;
}
/* --------------------------------------------------------------------------
* CM7 ONLY: clear the shared printf object once.
* -------------------------------------------------------------------------- */
void ipc_clear_print_buffer(void)
{
memset((void *)&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 = &g_ipc_testbuf;
buffer->magic = IPC_TESTBUF_MAGIC;
buffer->seq = 0u;
buffer->len = 0u;
memset((void*)buffer->data, 0, IPC_TESTBUF_BYTES);
PRINTF("\nMagic: %u, Seq: %u, Len: %u",
buffer->magic,
buffer->seq,
buffer->len);
}
void ipc_increment_seq_and_kick_m4()
{
volatile ipc_testbuf_t *buffer = &g_ipc_testbuf;
static int testCounter = 0;
buffer->magic = IPC_TESTBUF_MAGIC;
buffer->seq = testCounter;
buffer->len = testCounter;
testCounter++;
PRINTF("\nMagic: %u, Seq: %u, Len: %u",
buffer->magic,
buffer->seq,
buffer->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->magic;
uint32_t seq = buffer->seq;
uint32_t len = buffer->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->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);
} > 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);
} > m_ivt
.core1_code :
{
. = ALIGN(4);
KEEP (*(.core1_code))
*(.core1_code*)
. = ALIGN(4);
} > 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__) <= LENGTH(m_shared_params),
"shared_params section too large");
} > m_shared_params
/* --------------------------------------------------------------------
* Shared printf region (NOLOAD) - exclusive for M7->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__) <= LENGTH(m_shared_printf),
"shared_printf section too large");
} > m_shared_printf
.interrupts :
{
__VECTOR_TABLE = .;
__Vectors = .;
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
} > m_interrupts
.text :
{
. = ALIGN(4);
*(.text)
*(.text*)
*(.rodata)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
} > m_text
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > m_text
.ARM :
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} > 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__ = .;
} > 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__ = .;
} > m_text
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} > m_text
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} > m_text
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} > 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__ = .;
} > 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__ = .;
} > 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__ = .;
} > 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__ = .;
} > m_dtcm
. = __noncachedata_init_end__;
.ncache :
{
*(NonCacheable)
. = ALIGN(4);
__noncachedata_end__ = .;
} > m_dtcm
__DATA_END = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_start__);
text_end = ORIGIN(m_text) + LENGTH(m_text);
ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data")
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > m_dtcm
.heap :
{
. = ALIGN(8);
__end__ = .;
PROVIDE(end = .);
__HeapBase = .;
. += HEAP_SIZE;
__HeapLimit = .;
__heap_limit = .;
} > m_dtcm
.stack :
{
. = ALIGN(8);
. += STACK_SIZE;
} > m_dtcm
__StackTop = ORIGIN(m_dtcm) + LENGTH(m_dtcm);
__StackLimit = __StackTop - STACK_SIZE;
PROVIDE(__stack = __StackTop);
.ARM.attributes 0 : { *(.ARM.attributes) }
}
ASSERT(__StackLimit >= __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->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__) <= LENGTH(m_shared_params),
"shared_params section too large");
} > m_shared_params
/* --------------------------------------------------------------------
* Shared printf region (NOLOAD) - exclusive for M7->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__) <= LENGTH(m_shared_printf),
"shared_printf section too large");
} > m_shared_printf
.interrupts :
{
__VECTOR_TABLE = .;
__Vectors = .;
. = ALIGN(4);
KEEP(*(.isr_vector))
. = ALIGN(4);
} > m_interrupts
.text :
{
. = ALIGN(4);
*(.text)
*(.text*)
*(.rodata)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
*(.eh_frame)
KEEP(*(.init))
KEEP(*(.fini))
. = ALIGN(4);
} > m_text
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > m_text
.ARM :
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} > 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__ = .;
} > 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__ = .;
} > m_text
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} > m_text
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} > m_text
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} > 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__ = .;
} > 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__ = .;
} > 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__ = .;
} > m_dtcm
__NDATA_ROM = __DATA_ROM + (__data_end__ - __data_start__);
/* M4-local NonCacheable sections -> local 128KB */
.ncache.init : AT(__NDATA_ROM)
{
__noncachedata_start__ = .;
*(NonCacheable.init)
. = ALIGN(4);
__noncachedata_init_end__ = .;
} > m_ncache_local
.ncache (NOLOAD) :
{
*(NonCacheable)
. = ALIGN(4);
__noncachedata_end__ = .;
} > m_ncache_local
.bss (NOLOAD) :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > m_dtcm
.dtcm_bss (NOLOAD) :
{
. = ALIGN(32);
__dtcm_bss_start__ = .;
*(.dtcm_bss*)
*(DTCM_BSS*)
. = ALIGN(32);
__dtcm_bss_end__ = .;
} > m_dtcm
/* ---------- Audio OCRAM banks (non-cacheable, NOLOAD) ---------- */
.audio1_bss (NOLOAD) :
{
. = ALIGN(32);
__audio1_bss_start__ = .;
*(.audio1_bss*)
. = ALIGN(32);
__audio1_bss_end__ = .;
} > m_ncache_audio1
.audio2_bss (NOLOAD) :
{
. = ALIGN(32);
__audio2_bss_start__ = .;
*(.audio2_bss*)
. = ALIGN(32);
__audio2_bss_end__ = .;
} > m_ncache_audio2
.audio3_bss (NOLOAD) :
{
. = ALIGN(32);
__audio3_bss_start__ = .;
*(.audio3_bss*)
. = ALIGN(32);
__audio3_bss_end__ = .;
} > 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__ = .;
} > 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__ = .;
} > 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__ = .;
} > m_sdram_nc
.heap :
{
. = ALIGN(8);
__end__ = .;
PROVIDE(end = .);
__HeapBase = .;
. += HEAP_SIZE;
__HeapLimit = .;
__heap_limit = .;
} > m_dtcm
.stack :
{
. = ALIGN(8);
. += STACK_SIZE;
__StackEnd = .;
} > 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)(&__base_rpmsg_sh_mem);
uint32_t size = (uint32_t)(&__top_rpmsg_sh_mem) - nonCacheStart;
#else
extern uint32_t __base_NCACHE_REGION;
extern uint32_t __top_NCACHE_REGION;
uint32_t nonCacheStart = (uint32_t)(&__base_NCACHE_REGION);
uint32_t size = (uint32_t)(&__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) && __ICACHE_PRESENT
if (SCB_CCR_IC_Msk == (SCB_CCR_IC_Msk & SCB->CCR))
{
SCB_DisableICache();
}
#endif
#if defined(__DCACHE_PRESENT) && __DCACHE_PRESENT
if (SCB_CCR_DC_Msk == (SCB_CCR_DC_Msk & SCB->CCR))
{
SCB_DisableDCache();
}
#endif
ARM_MPU_Disable();
/* Region 0: deny all (speculative prefetch workaround) */
MPU->RBAR = ARM_MPU_RBAR(0, 0x00000000U);
MPU->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->RBAR = ARM_MPU_RBAR(1, 0x80000000U);
MPU->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->RBAR = ARM_MPU_RBAR(2, 0x60000000U);
MPU->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->RBAR = ARM_MPU_RBAR(3, 0x00000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_1GB);
/* Region 4: Normal, WB */
MPU->RBAR = ARM_MPU_RBAR(4, 0x00000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_256KB);
/* Region 5: Normal, WB */
MPU->RBAR = ARM_MPU_RBAR(5, 0x20000000U);
MPU->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->RBAR = ARM_MPU_RBAR(6, 0x20240000U);
MPU->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->RBAR = ARM_MPU_RBAR(7, 0x20280000U);
MPU->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->RBAR = ARM_MPU_RBAR(10, 0x20300000U);
MPU->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) && CACHE_MODE_WRITE_THROUGH
/* --- SDRAM: default NON-cacheable 64MB --- */
MPU->RBAR = ARM_MPU_RBAR(11, 0x80000000U);
MPU->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->RBAR = ARM_MPU_RBAR(12, 0x80000000U);
MPU->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->RBAR = ARM_MPU_RBAR(11, 0x80000000U);
MPU->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->RBAR = ARM_MPU_RBAR(12, 0x80000000U);
MPU->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) && (XIP_EXTERNAL_FLASH == 1)
/* Region 8: XIP external flash, RO, WB */
MPU->RBAR = ARM_MPU_RBAR(8, 0x30000000U);
MPU->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) && CACHE_MODE_WRITE_THROUGH
/* Region 9: SDRAM overall WT */
MPU->RBAR = ARM_MPU_RBAR(9, 0x80000000U);
MPU->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->RBAR = ARM_MPU_RBAR(9, 0x80000000U);
MPU->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->RBAR = ARM_MPU_RBAR(13, 0x40000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_16MB);
MPU->RBAR = ARM_MPU_RBAR(14, 0x41000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 2, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_2MB);
MPU->RBAR = ARM_MPU_RBAR(15, 0x41400000U);
MPU->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) && __DCACHE_PRESENT
SCB_EnableDCache();
#endif
#if defined(__ICACHE_PRESENT) && __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)(&__base_NCACHE_REGION);
uint32_t nonCacheSize = (uint32_t)(&__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 >= 0x20000000U);
/* ---- Disable code bus cache (LMEM) ---- */
if (LMEM_PCCCR_ENCACHE_MASK == (LMEM_PCCCR_ENCACHE_MASK & LMEM->PCCCR))
{
LMEM->PCCCR |= LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK | LMEM_PCCCR_GO_MASK;
while ((LMEM->PCCCR & LMEM_PCCCR_GO_MASK) != 0U) {}
LMEM->PCCCR &= ~(LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK);
LMEM->PCCCR &= ~LMEM_PCCCR_ENCACHE_MASK;
}
/* ---- Disable system bus cache (LMEM) ---- */
if (LMEM_PSCCR_ENCACHE_MASK == (LMEM_PSCCR_ENCACHE_MASK & LMEM->PSCCR))
{
LMEM->PSCCR |= LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK | LMEM_PSCCR_GO_MASK;
while ((LMEM->PSCCR & LMEM_PSCCR_GO_MASK) != 0U) {}
LMEM->PSCCR &= ~(LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK);
LMEM->PSCCR &= ~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->RBAR = ARM_MPU_RBAR(0, 0x20240000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL,
1, /* TypeExtField=1 => Normal non-cacheable */
1, /* Shareable = 1 */
0, /* Cacheable */
0, /* Bufferable */
0,
ARM_MPU_REGION_SIZE_256KB);
/* Region 1: OCRAM 512KB (SHAREABLE, non-cacheable) */
MPU->RBAR = ARM_MPU_RBAR(1, 0x20280000U);
MPU->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->RBAR = ARM_MPU_RBAR(2, 0x20300000U);
MPU->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 >= 0x20240000U) && (nonCacheStart < 0x20340000U));
ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_HFNMIENA_Msk);
/* Invalidate and enable system bus cache */
LMEM->PSCCR |= LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK | LMEM_PSCCR_GO_MASK;
while ((LMEM->PSCCR & LMEM_PSCCR_GO_MASK) != 0U) {}
LMEM->PSCCR &= ~(LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK);
LMEM->PSCCR |= LMEM_PSCCR_ENCACHE_MASK;
/* Invalidate and enable code bus cache */
LMEM->PCCCR |= LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_GO_MASK;
while ((LMEM->PCCCR & LMEM_PCCCR_GO_MASK) != 0U) {}
LMEM->PCCCR &= ~(LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK);
LMEM->PCCCR |= LMEM_PCCCR_ENCACHE_MASK;
}
#endif /* __CORTEX_M == 4 */
Print log:
EventsHandled: 1, Magic: 1413829460, Seq: 0, Len: 0
EventsHandled: 2, Magic: 1413829460, Seq: 0, Len: 0
EventsHandled: 3, Magic: 1413829460, Seq: 0, Len: 0
EventsHandled: 4, Magic: 1413829460, Seq: 0, Len: 0
EventsHandled: 5, Magic: 1413829460, Seq: 0, Len: 0
EventsHandled: 6, Magic: 1413829460, Seq: 0, Len: 0
EventsHandled: 7, Magic: 1413829460, Seq: 0, Len: 0
EventsHandled: 8, Magic: 1413829460, Seq: 0, Len: 0
EventsHandled: 9, Magic: 1413829460, Seq: 0, Len: 0
EventsHandled: 10, Magic: 1413829460, Seq: 0, Len: 0