4. AURIX存储映射

AURIX TC3xx 系列采用统一编址的 32 位地址空间,将本地存储、全局存储、外设寄存器以及系统资源映射到同一线性地址视图中。理解这套映射规则,是进行链接脚本编写、MPU 配置、DMA 描述符设计以及多核数据共享的前提。本章从地址空间划分入手,逐步展开到存储保护单元(MPU/SMPU)与访问权限的配置方法。

一、核心原理:统一地址空间与区域划分

AURIX 的地址空间并非"内存与外设分离",而是通过高位地址段区分不同物理资源。CPU 发出的地址先经过总线交叉开关(SRI/SPB),再根据地址区间路由到对应从设备。典型 TC3xx 的地址划分如下:

  • 本地存储区(Local Memory):每个 CPU 私有的 DSPR(数据暂存 RAM)与 PSPR(程序暂存 RAM),地址通常位于 0x7000_0000 与 0x6000_0000 附近,仅本核访问延迟最低。
  • 全局存储区(Global Memory):LMU、EMEM、外部总线映射区,所有核与 DMA 均可访问,用于核间共享数据与大数据缓冲。
  • 外设空间(Peripheral Space):SPB 外设(如 ASCLIN、QSPI、GPT)与 SRI 外设(如 CAN、以太网、DMA)寄存器,地址集中在 0xF000_0000 以上。
  • 系统与启动区:Boot ROM、PFlash、DFlash 及系统寄存器,承担启动、代码存储与配置功能。

关键点在于:同一物理 RAM 可能通过不同地址别名访问,例如 DSPR 既可通过本地地址访问,也可通过全局地址访问,但两者的访问延迟与权限检查路径不同。

AURIX TC3xx 统一地址空间映射视图 CPU0 本地 DSPR/PSPR CPU1 本地 DSPR/PSPR CPU2 本地 DSPR/PSPR SRI 总线交叉开关 地址路由 全局存储 LMU / EMEM 0x9000_0000 起 外设空间 SPB / SRI 外设 0xF000_0000 起 程序/数据 Flash PFlash / DFlash 0x8000_0000 起 存储保护单元 MPU / SMPU 区域基址 + 大小 读 / 写 / 执行权限 特权级 / 用户级 越权触发 Trap 地址映射规则要点 • 高位地址段决定路由目标(SRI/SPB) • 本地别名与全局别名指向同一物理 RAM • 外设寄存器按 32 位对齐访问 • 未映射地址访问触发总线错误 Trap • MPU 区域不可重叠,优先级由区域号决定

二、方法流程:从链接脚本到 MPU 配置

实际工程中,存储映射的落地分为四步:

  1. 规划地址布局:根据数据量决定哪些段放 DSPR、哪些放 LMU。核间共享队列放全局存储,核私有栈放本地 DSPR。
  2. 编写链接脚本:在 LSL 文件中定义 memory 与 section,将代码段、数据段、堆栈段分配到具体地址区间。
  3. 配置 MPU 区域:为每个区域设置基址、大小、权限位,确保代码区只读可执行、数据区可读写不可执行。
  4. 验证访问行为:通过越权访问测试确认 Trap 正确触发,并检查 DMA 描述符地址是否落在允许区域。
/* 链接脚本片段:本地 DSPR 与全局 LMU 分配 */
memory dspr0
{
  mau = 8;
  size = 240k;
  type = ram;
  map (dest=bus:sri, src_offset=0, dest_offset=0x70000000, size=240k);
}

memory lmu0
{
  mau = 8;
  size = 128k;
  type = ram;
  map (dest=bus:sri, src_offset=0, dest_offset=0x90000000, size=128k);
}

section_layout :tc0:linear
{
  group (ordered, run_addr=0x70000000)
  {
    select ".data.Cpu0Var";
  }
  group (ordered, run_addr=0x90000000)
  {
    select ".bss.SharedBuffer";
  }
}

三、存储保护单元与访问权限

AURIX 的 MPU 以"区域"为粒度进行权限检查。每个区域包含基址寄存器、结束地址寄存器和权限寄存器。权限位通常包括读(R)、写(W)、执行(X)以及特权级限定。当 CPU 访问某个地址时,硬件并行比较所有区域,若命中某区域则按该区域权限判定;若未命中任何区域,则按默认策略处理(通常拒绝)。

区域类型 典型地址 推荐权限 说明
代码区(PFlash) 0x8000_0000 R + X,禁止 W 防止运行时篡改代码
本地数据区(DSPR) 0x7000_0000 R + W,禁止 X 栈与私有变量
全局共享区(LMU) 0x9000_0000 R + W,禁止 X 核间通信缓冲
外设寄存器区 0xF000_0000 R + W,特权级 仅驱动层访问
Boot ROM 0x8FFF_0000 R + X,只读 启动代码与固件
MPU 区域配置后并非立即生效,部分器件需要执行同步屏障指令(如 isync 或 dsync)以确保流水线中的访问使用新权限。修改 MPU 寄存器后建议插入屏障再继续执行。

四、案例与场景:核间共享缓冲的权限设计

假设 CPU0 与 CPU1 通过 LMU 中的环形缓冲区交换 CAN 报文。设计要点如下:

  • 缓冲区放在 LMU 全局地址段,两个核均配置 R+W 权限,但禁止执行权限,防止跳转到数据区执行。
  • 写指针由生产者核独占写权限,读指针由消费者核独占写权限,通过 MPU 区域拆分实现"单写者"约束。
  • DMA 搬运描述符指向 LMU 地址,需确认 DMA 通道的 MPU 视图与 CPU 一致,否则会出现"CPU 能访问、DMA 报错"的现象。
  • 若某核误将数据区配置为可执行,攻击者可通过缓冲区溢出跳转执行恶意代码,因此 X 权限必须严格关闭。
常见误区:认为"本地地址访问更快所以全部放本地"。实际上多核共享数据若放在某核本地 DSPR,其他核只能通过全局别名访问,延迟反而升高,且该核复位后数据丢失。共享数据应优先放 LMU 或 EMEM。

五、复盘与检查清单

在项目集成阶段,建议按以下清单逐项核对存储映射与权限配置:

  1. 链接脚本中的地址区间是否与芯片数据手册的 memory map 一致,有无重叠。
  2. 每个 MPU 区域的基址与结束地址是否按区域粒度对齐(通常为 2 的幂次大小)。
  3. 代码区是否禁止写、数据区是否禁止执行,外设区是否限定特权级。
  4. DMA 访问的地址是否落在 DMA 可访问的全局区域,而非某核私有 DSPR。
  5. 越权访问测试是否触发预期 Trap,Trap 处理程序能否正确记录故障地址。
  6. 多核启动后各核 MPU 配置是否一致,是否存在某核未初始化 MPU 就访问共享区的窗口。