如何使用 M4F 内核从外部存储器执行代码?
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
要使用 M4F 从外部存储器中执行代码、请在 linker.cmd 中指定 MEMORY 区域以加载和运行程序、并在 example.syscfg 文件中添加 RAT 和 MPU 配置。 需要进行这些更改、因为 M4F 微控制器内核本身就是32b 处理器。 添加了专用 RAT 模块、允许 M4F 处理器访问完整的36B 通用 SoC 地址映射。
从外部存储器执行代码所需的步骤
${SDK 路径}\examples\hello_world\am62x-sk\m4fss0-0_freertos
下面给出了每个步骤的说明:
/* make sure below retain is there in your linker command file, it keeps the vector table in the final binary */ --retain="*(.vectors)" /* This is the stack that is used by code running within main() * In case of NORTOS, * - This means all the code outside of ISR uses this stack * In case of FreeRTOS * - This means all the code until vTaskStartScheduler() is called in main() * uses this stack. * - After vTaskStartScheduler() each task created in FreeRTOS has its own stack */ --stack_size=16384 /* This is the heap size for malloc() API in NORTOS and FreeRTOS * This is also the heap used by pvPortMalloc in FreeRTOS */ --heap_size=32768 SECTIONS { /* This has the M4F entry point and vector table, this MUST be at 0x0 */ .vectors:{} palign(8) > M4F_VECS .text: {} palign(8) > DDR_1 /* This is where code resides */ .bss: {} palign(8) > DDR_1 /* This is where uninitialized globals go */ RUN_START(__BSS_START) RUN_END(__BSS_END) .data: {} palign(8) > DDR_1 /* This is where initialized globals and static go */ .rodata: {} palign(8) > DDR_1 /* This is where const's go */ .sysmem: {} palign(8) > DDR_1 /* This is where the malloc heap goes */ .stack: {} palign(8) > DDR_1 /* This is where the main() stack goes */ GROUP { /* This is the resource table used by linux to know where the IPC "VRINGs" are located */ .resource_table: {} palign(4096) } > DDR_0 /* Sections needed for C++ projects */ .ARM.exidx: {} palign(8) > DDR_1 /* Needed for C++ exception handling */ .init_array: {} palign(8) > DDR_1 /* Contains function pointers called before main */ .fini_array: {} palign(8) > DDR_1 /* Contains function pointers called after main */ } MEMORY { M4F_VECS : ORIGIN = 0x00000000 , LENGTH = 0x00000200 M4F_IRAM : ORIGIN = 0x00000200 , LENGTH = 0x0002FE00 M4F_DRAM : ORIGIN = 0x00030000 , LENGTH = 0x00010000 /* when using multi-core application's i.e more than one R5F/M4F active, make sure * this memory does not overlap with R5F's */ /* Resource table must be placed at the start of DDR_0 when M4 core is early booting with Linux */ DDR_0 : ORIGIN = 0x9CC00000 , LENGTH = 0x1000 DDR_1 : ORIGIN = 0x9CB00000 , LENGTH = 0x100000 }
章节说明:
代码是使用 ARM Cortex-M4F 微控制器的系统的链接器脚本。 链接器脚本用于指定系统的存储器布局、它告诉链接器在何处将代码和数据的不同部分放入存储器中。
链接器脚本定义了多个段、例如:
它将这些段分配给系统中的不同存储器区域(DDR_1、DDR_0)。 Linux 使用 μ`.resource_table`部分在存储器中定位 IPC"VRINGs"、并将其分配给 DDR_0存储器区域。
此外、脚本还定义了 C++项目的段、例如`.arm.exidx`、`.init_array`和`.fini_array`。 这些段用于异常处理和 C++对象的初始化/清理、并分配给 DDR_1存储器区域。
该脚本使用"Group"和"run_start"/"run_end"命令将段组合在一起并为它们分配特定的存储器地址。 "palign"命令用于指定每个段的对齐方式。
脚本``` DDR_1`将段放置在 DDR_1存储器中、使用 DDR_0将段放置在 DDR_0存储器中。
该脚本还为`、vectors`、`、`、`、BSS`、`、data`、`、rodata`、 `.sysmem`和`.stack`、这样系统就知道段在存储器中的位置。
它还使用`run_start (__bss_start)`和`run_end (__bss_end)` 来指定`.bss`段的起始地址和结束地址。
内存说明:
上述代码是使用 ARM Cortex-M4F 微控制器的系统的存储器映射。 存储器映射定义了系统的不同存储器区域及其特定的存储器地址。
它定义了四个存储器区域:
`M4F_VECS`
:这是 M4F 的入口点和向量表所在的区域,其原点为0x00000000,长度为0x00000200。 `M4F_IRAM`
: 这是指令 RAM 所在的区域,位于0x00000200的原点,长度为0x0002FE00。 `M4F_DRAM`
:这是数据 RAM 所在的区域,其原始地址为0x00030000,长度为0x00010000。 `DDR_0`
: 这是 DDR_0存储器的区域,其原始地址为0x9CC00000,长度为0x1000。 `DDR_1`
:这是 DDR_1存储器的区域,其原始地址为0x9CB00000,长度为0x100000。 指定在使用多核应用时、例如多个处于活动状态的 R5F/M4F、请确保该存储器不会与 R5F 重叠。
它还指定当 M4内核使用 Linux 进行早期引导时、必须将资源表放置在 DDR_0的开头。
存储器区域的原点和长度以十六进制表示法定义。 存储器映射用于确保链接器脚本中定义的不同段被放置在正确的存储器区域和正确的存储器地址中。
有关何时配置 RAT 以及如何使用转换后的地址的更多信息、请参阅更新基于区域的地址转换(RAT)设置的常见问题解答。
《MCU+SDK 用户指南》中的 RAT 配置详细信息: https://software-dl.ti.com/mcu-plus-sdk/esd/AM62X/08_05_00_14/exports/docs/api_guide_am62x/KERNEL_DPL_ADDR_TRANSLATE_PAGE.html
基于区域的地址转换(RAT)是 AM62x SOC 中的存储器管理功能、允许将存储器区域映射到特定存储器地址。 这样可以创建多个虚拟存储器空间、供 SoC 的不同组件和子系统使用。
RAT 使用存储器区域表和相应的存储器地址来执行转换。 每个区域都由起始地址、结束地址和一组属性定义、这些属性指定区域的访问权限和其他属性。
RAT 可用于创建多个虚拟内存空间、每个虚拟内存空间都有自己的一组内存区域。 这样可以隔离不同的组件和子系统、并提供一种控制对存储器资源的访问的方法。
有关详细说明、请参阅 TRM 的第9.2.1节。 AM62x TRM
如何配置 RAT:
•将 CONFIG_ADDR_translation_region_0的大小从512MB 更改为256MB。
•按照以下屏幕截图中的定义、添加新的 RAT 区域 CONFIG_ADDR_TRANSLATE_4。
内存保护单元(MPU)是一个模块,用于修改处理器内存排序模型中定义的内存类型和属性。 MPU 特定于系统中的每个内核、只能修改其所连接 CPU 的存储器顺序模型。
示例项目:
我已附上 Hello World M4F 的示例项目供您参考。
M4F Hello World 代码: