2. AURIX内存架构与标定数据组织

在AURIX TC3xx这类多核MCU上做XCP标定,第一件必须搞清楚的事不是XCP命令怎么发,而是“我要改的那个数,到底住在哪块存储器里”。因为XCP的读写最终会落到具体物理地址上,而AURIX的地址空间并不是一整块连续RAM,它由PFlash、DFlash、LMU、DSPR、PSPR等多类存储介质拼成,各自有独立的访问属性、总线归属和权限。标定工程师如果只会在A2L里点“标定”,却不知道这个量在Flash还是RAM,就很容易遇到“改了不生效”“写进去报错”“复位后恢复原值”这类问题。

一、AURIX TC3xx的存储分区与地址映射

以TC3xx典型配置为例,程序代码主要放在PFlash(Program Flash),容量从2MB到16MB不等,按Sector划分,每个Sector可独立擦除。PFlash的访问是只读的,运行时代码从这里取指,标定数据如果直接放在PFlash里,XCP只能读、不能在线写——除非先擦除整个Sector再重写,这显然不适合在线标定。

DFlash(Data Flash)是另一块独立的非易失存储,容量通常128KB~1MB,专门用于存放需要掉电保持、又需要频繁更新的数据,比如EEPROM仿真、故障码、标定备份。DFlash支持按Page擦写,粒度比PFlash小,但写入速度慢,不适合高频刷新的标定量。

SRAM方面,每个CPU核有自己私有的DSPR(Data Scratch Pad RAM),容量几十KB到几百KB,访问延迟最低,但只有本核能直接访问。跨核共享的数据通常放在LMU(Local Memory Unit)或全局SRAM。LMU是TC3xx里一块重要的共享存储,容量可达512KB甚至更大,所有核都能访问,常被用作核间通信缓冲区、共享标定数据区、XCP测量数据缓存。

地址映射上,TC3xx采用统一的32位地址空间。以TC375为例,PFlash通常映射在0x8000_0000起始的段,DFlash在0xAF00_0000附近,LMU在0x9000_0000段,DSPR在0x7000_0000段(各核有偏移)。这些地址在链接脚本(.ld文件)里被明确划分,编译器据此把不同段的数据放到不同物理位置。

AURIX TC3xx 存储分区与标定数据落位 PFlash (Program Flash) 0x8000_0000 起 只读 · Sector擦除 代码 + 常量标定初值 XCP: 只读,不可在线写 DFlash (Data Flash) 0xAF00_0000 起 Page擦写 · 掉电保持 标定备份 / 故障码 XCP: 可读写,速度慢 LMU (Local Memory Unit) 0x9000_0000 起 多核共享 · 大容量 共享标定区 / 测量缓存 XCP: 可读写,推荐标定RAM DSPR (每核私有) 0x7000_0000 起 最低延迟 · 核内独占 高频测量变量 PSPR (每核私有) 0x7010_0000 起 核内程序RAM 时间关键代码 标定数据段 .calib / .measure 链接到LMU或DSPR 由链接脚本定位 A2L ↔ ELF 对应关系 A2L中的 MEMORY_SEGMENT 定义地址范围与访问权限; MEASUREMENT / CHARACTERISTIC 的 ECU_ADDRESS 直接取自 ELF 符号表; 链接脚本决定 .calib 段落在 LMU 还是 DSPR,A2L 必须与之一致,否则 XCP 读写地址错位。

二、标定数据段的链接与定位

标定数据在C代码里通常以全局变量或数组形式声明,但默认的.data或.bss段会被链接器随机分配到普通RAM,地址不固定,A2L无法预先知道。工程上的标准做法是:在链接脚本里专门划出一块“标定段”,比如命名为 .calib,并指定它落在LMU的某个固定地址区间。然后在C代码里用 #pragma section 或 __attribute__((section(".calib"))) 把标定变量强制放入该段。

以TC375为例,链接脚本中常见写法如下:

MEMORY
{
  lmu_calib (rw) : ORIGIN = 0x90010000, LENGTH = 0x00010000
}

SECTIONS
{
  .calib : 
  {
    *(.calib)
    *(.calib.*)
  } > lmu_calib
}

这样,所有被标记为 .calib 的变量都会被链接到0x90010000开始的64KB LMU区域。编译完成后,ELF文件里会记录每个符号的最终地址,例如 EngSpd_Cal 位于0x90010020,InjTiming_Map 位于0x90010100。这些地址就是A2L里 ECU_ADDRESS 的来源。

测量量的处理略有不同。测量量通常是运行时变量,需要高频刷新,放在DSPR或LMU都可以,但必须保证XCP能读到。如果测量量是局部变量或寄存器变量,编译器可能把它优化掉,导致A2L里找不到符号。因此测量量应声明为 volatile 全局变量,并放入 .measure 段,链接到LMU的测量缓存区。

三、A2L文件与ELF的对应关系

A2L文件本质上是ECU描述文件,它告诉标定工具“有哪些量、在哪里、怎么解释”。其中最关键的三类信息:

  • MEASUREMENT:测量量,包含名称、数据类型、转换规则、ECU_ADDRESS。地址必须与ELF符号表一致。
  • CHARACTERISTIC:标定量,包含名称、类型(VALUE/CURVE/MAP)、维度、ECU_ADDRESS、RECORD_LAYOUT。
  • MEMORY_SEGMENT:存储段描述,定义地址范围、访问权限(R/W/RW)、页大小。XCP的 SET_MTA 和 UPLOAD/DOWNLOAD 会依据它判断目标地址是否合法。

生成A2L的常见流程是:编译得到ELF → 用工具(如Infineon的A2L Generator或第三方脚本)解析ELF的符号表和DWARF调试信息 → 提取变量名、地址、数据类型、数组维度 → 按ASAM MCD-2 MC标准生成A2L。如果链接脚本改了地址,必须重新生成A2L,否则工具会按旧地址读写,轻则数据错位,重则触发总线错误。

实际工程中,建议把标定段和测量段的地址范围在链接脚本里固定下来,并在A2L的MEMORY_SEGMENT中显式声明。这样即使代码迭代,只要段布局不变,A2L的地址映射就保持稳定,减少反复生成和验证的工作量。
注意:DFlash虽然可写,但擦写寿命有限(通常10万次量级),且写入耗时远高于LMU。不要把高频刷新的标定量放在DFlash,否则既影响XCP响应速度,又加速存储器磨损。DFlash更适合存放“标定结果备份”或“掉电需保留的标定版本号”。