2. AURIX存储与启动架构

要理解AURIX上的双分区OTA与回滚,必须先建立一张清晰的“存储—启动”地图。AURIX TC3xx系列的片上非易失存储并不是一个整体,而是由PFlash、DFlash、UCB和BMHD等不同角色共同构成。它们各自承担代码存放、数据保存、配置锁定和启动决策的职责,任何一次OTA升级或回滚,本质上都是在这张地图上移动指针、改写标志并触发复位。

PFlash与DFlash:代码与数据的物理分工

PFlash(Program Flash)是主程序存储区,用于存放启动代码、应用程序、标定数据和OTA相关逻辑。TC3xx的PFlash通常按物理Bank划分,例如TC375拥有多个PFlash Bank,每个Bank又由若干Logical Sector组成。Logical Sector是擦除的最小单位,典型大小为16 KB或更大,具体取决于型号。写入时以Page为单位,常见Page大小为32字节。理解“擦除按Sector、写入按Page”这一约束,是后续设计双分区布局的基础。

DFlash(Data Flash)则用于存放需要频繁更新或掉电保持的数据,例如EEPROM仿真、故障码、里程信息以及OTA状态标志。DFlash的擦写粒度通常比PFlash更细,适合保存升级进度、分区有效标志和回滚计数等小数据。在双分区方案中,DFlash往往承担“元数据仓库”的角色,记录当前活动分区、待激活分区、升级结果和回滚原因。

UCB与BMHD:启动配置的锁定层

UCB(User Configuration Block)是AURIX中一组受保护的非易失配置块,用于保存芯片级配置,包括启动模式、调试保护、时钟和Flash保护设置等。UCB的写入不是普通写操作,而是通过“擦除—写入—确认”的受控流程完成,一旦锁定便难以随意更改。因此,UCB通常只在产线或首次部署时配置,不应在每次OTA中频繁修改。

BMHD(Boot Mode Header)是UCB中的关键结构,它告诉芯片上电后从哪里开始取指令。BMHD包含启动模式、入口地址、校验和以及有效性标志。TC3xx通常提供多个BMHD副本,芯片启动时会按顺序检查BMHD的有效性,选择第一个有效的BMHD来引导。如果主BMHD损坏,备用BMHD可以接管,这为回滚提供了硬件级容错基础。

AURIX TC3xx 存储与启动架构总览 UCB 用户配置块(受保护,产线配置) BMHD0 启动模式 + 入口地址 BMHD1(备用) 校验和 + 有效标志 其他 UCB 配置 调试保护 / Flash 保护 启动决策 选择有效 BMHD PFlash 主程序存储区(按 Bank / Logical Sector 组织) Bank A — 分区 A(活动) Bootloader + 应用代码 A 版本号 / 校验信息 Bank B — 分区 B(待激活/回滚) 应用代码 B(新版本) 版本号 / 校验信息 双分区映射关系 • 活动分区由 DFlash 中的“当前分区指针”决定 • BMHD 入口地址指向 Bootloader,由 Bootloader 跳转 • 升级时写入非活动分区,校验通过后切换指针并复位 DFlash 数据存储区 当前活动分区指针 active_partition = A / B 升级状态标志 idle / writing / verifying / pending 回滚计数与原因 rollback_count / last_error 掉电保持,复位后仍有效 分区选择 上电复位 → 读取 BMHD → 跳转 Bootloader 擦除单位:Logical Sector(典型 16 KB)|写入单位:Page(典型 32 B)|BMHD 提供硬件级启动容错

启动模式与BMHD的配合

TC3xx的启动模式由BMHD中的启动模式字段和外部引脚共同决定。常见模式包括内部启动、外部启动、备用启动和调试启动。在双分区OTA场景中,我们通常使用内部启动模式,让芯片从PFlash中的Bootloader开始执行。Bootloader是唯一固定不变、不参与OTA的代码段,它负责读取DFlash中的分区指针,决定跳转到分区A还是分区B。

BMHD的入口地址应指向Bootloader的起始地址,而不是直接指向应用分区。这样设计的好处是:无论活动分区如何切换,BMHD始终有效,不需要在每次OTA时修改UCB。Bootloader承担分区选择逻辑,使启动过程与分区切换解耦。如果Bootloader本身需要升级,则必须通过UCB重写或专用刷写流程完成,风险较高,因此Bootloader应尽量精简稳定。

双分区映射关系的实际组织

假设TC375的PFlash总容量为4 MB,我们将其划分为两个等大的应用分区:分区A位于0xA0000000起始的2 MB区域,分区B位于0xA0200000起始的2 MB区域。每个分区内部再细分为应用代码区、标定数据区和版本信息区。Bootloader放在PFlash最前面的独立Sector中,不参与分区切换。

DFlash中保存一个结构化的元数据块,至少包含以下字段:

typedef struct {
    uint32_t magic;              // 固定标识,如 0x4F544131
    uint8_t  active_partition;   // 0 = A, 1 = B
    uint8_t  pending_partition;  // 待激活分区
    uint8_t  upgrade_state;      // 0=idle, 1=writing, 2=verifying, 3=pending
    uint8_t  rollback_count;     // 回滚次数
    uint32_t version_a;          // 分区A版本号
    uint32_t version_b;          // 分区B版本号
    uint32_t crc_a;              // 分区A校验值
    uint32_t crc_b;              // 分区B校验值
} ota_metadata_t;

上电后,Bootloader首先读取该结构,检查magic是否有效。若有效,则根据active_partition跳转到对应分区;若无效,则使用默认分区A并触发恢复流程。升级时,Bootloader或应用将新固件写入pending_partition指向的分区,写入完成后计算CRC并更新元数据,将upgrade_state置为pending,然后复位。复位后Bootloader发现pending状态,验证新分区CRC,通过则将active_partition切换为pending_partition,清除pending状态;不通过则保持原活动分区,并增加rollback_count。

启动模式与回滚的联动

回滚的触发条件通常有三类:新分区CRC校验失败、新分区启动后看门狗超时、或应用主动请求回滚。前两类由Bootloader在启动阶段判断,第三类由应用在运行阶段写入DFlash标志,复位后由Bootloader执行。无论哪种方式,最终都通过修改DFlash中的active_partition字段实现分区切换,而不需要改动BMHD或UCB。

BMHD和UCB是“芯片级”配置,修改风险高、次数有限;DFlash中的分区指针是“应用级”配置,可以频繁读写。双分区OTA的设计原则就是:把频繁变化的决策放在DFlash,把稳定的启动入口固定在BMHD和Bootloader中。
不要将BMHD入口地址直接指向应用分区A或B。一旦这样做,每次分区切换都需要重写UCB,而UCB的擦写寿命和操作风险都不适合OTA场景。Bootloader必须作为固定跳转层存在。

关键参数与布局检查表

项目 典型值/要求 说明
PFlash Logical Sector 16 KB(以具体型号为准) 擦除最小单位,分区边界应对齐Sector
PFlash Page 32 B 写入最小单位,不足需补齐
分区大小 ≥ 应用镜像 + 版本信息 + 余量 两个分区应等大或按最大镜像预留
BMHD入口 Bootloader起始地址 不随分区切换变化
DFlash元数据 带magic和CRC 防止误读和掉电损坏
回滚计数上限 建议3~5次 超过后进入安全模式或强制恢复

理解这张存储与启动地图后,后续的OTA流程设计、Bootloader实现和回滚策略才有稳固的落脚点。PFlash提供双分区空间,DFlash保存切换决策,UCB和BMHD锁定启动入口,三者各司其职,共同支撑起可靠的双分区升级与回滚机制。