4. AURIX启动流程与启动代码定制

AURIX TC3xx从上电复位到用户main()执行,中间要经过BootROM、SSW(Startup Software)、用户启动代码三段接力。理解这三段的分工与交接点,是定制启动代码、压缩启动时间的前提。很多“程序跑不起来”“多核只跑了一个核”“看门狗莫名复位”的问题,根因都落在这一段。

三段接力:BootROM、SSW与用户启动代码

上电后首先运行的是固化在芯片内的BootROM。它负责最底层的自检与启动模式判定:读取启动模式引脚(如TC3xx的HWCFG引脚组合),决定从内部Flash、外部Flash还是串口等模式启动,并完成基础时钟与内部SRAM的初步可用性检查。BootROM是只读的,用户无法修改,但可以通过配置区(如UCB中的启动配置)影响它的行为。

BootROM之后进入SSW。SSW同样由英飞凌提供,主要职责是:根据启动配置初始化PFlash访问、设置初始时钟、把CPU0的PC指向用户启动代码入口(通常是_START或复位向量表项),并完成必要的安全启动校验(如HSM相关流程)。SSW执行完毕后,控制权交给用户代码,这才是工程师真正能定制的地方。

用户启动代码通常由编译器启动文件(如crt0、startup_tc3xx.c)和用户自定义初始化组成,典型顺序是:设置栈指针→初始化数据段(.data从Flash搬到RAM、.bss清零)→调用时钟初始化→释放看门狗→启动从核→跳转main()。这个顺序不能随意颠倒,例如数据段未初始化就调用C函数,全局变量值不可预期。

AURIX TC3xx 上电启动链路与用户可定制边界 BootROM(固化) 读HWCFG启动模式 基础自检 / SRAM初检 选择启动源 用户不可修改 SSW(英飞凌提供) PFlash访问初始化 初始时钟 / 安全校验 PC指向用户入口 用户不可修改 用户启动代码(可定制) 栈指针 → .data搬运 / .bss清零 时钟/PLL初始化 → 看门狗释放 多核启动 → 跳转 main() 工程师主战场 t=0 复位 BootROM结束 SSW结束 main() 用户启动代码内部执行顺序(不可随意颠倒) ① 设置栈指针 SP / ISP ② .data搬运 .bss清零 ③ 时钟/PLL配置 CCUCON / PLL ④ 看门狗释放 ENDINIT ⑤ 多核启动 CPU1/2… 关键约束:③必须在②之后(时钟未稳时访问外设可能挂死);④必须在访问受保护寄存器前完成

时钟初始化与PLL配置

SSW给出的初始时钟通常较低(例如基于备份时钟的几MHz),用户启动代码需要把系统时钟提升到目标频率。TC3xx的时钟树核心是PLL与CCUCON寄存器组。以常见的20MHz外部晶振、目标200MHz系统时钟为例,配置思路是:先确认PLL输入参考时钟(PLLCON0.VCOBYP等),设置NDIV、PDIV、K2DIV等分频/倍频参数,等待PLL锁定标志PLLSTAT.LOCK置位,再通过CCUCON0/1/2把各总线(SPB、SRI、STM等)切换到PLL输出。

关键点是先等锁定再切源。若在LOCK未置位时就切换时钟源,CPU可能取到不稳定时钟导致跑飞。切换后还应回读CCUCON的LOCK位确认切换完成。示例参数(假设值,非实测):NDIV=50, PDIV=1, K2DIV=2,配合20MHz参考,可得到约200MHz的PLL输出,再经各分频器分配给不同总线。

看门狗释放与ENDINIT保护

AURIX的安全看门狗(Safety WDT)和CPU看门狗(CPU WDT)在复位后默认处于激活状态,且受ENDINIT保护。ENDINIT是一道写保护闸门:未清除它之前,对WDT、CCUCON、PLL等安全相关寄存器的写操作会被忽略。因此启动代码中必须先执行清ENDINIT序列(写WDT_CON0的ENDINIT位并配合密码),完成时钟与看门狗配置后,再重新置位ENDINIT恢复保护。

常见坑:在ENDINIT未清除时配置PLL,寄存器写入无效但代码不报错,表现为“时钟没变、程序变慢”。排查时先读回寄存器确认写入是否生效。

看门狗释放的实质是:把看门狗超时时间设为足够长(或先禁用再按需启用),并在main()循环或定时任务中定期喂狗。若启动阶段耗时较长(如大容量数据段搬运),必须在搬运过程中插入喂狗,否则会在启动中途被复位。

多核启动顺序

TC3xx上电后默认只有CPU0运行,CPU1、CPU2等从核处于halt状态。用户启动代码需要显式唤醒从核:通常由CPU0配置从核的启动地址(CPU1_PC等寄存器),然后写CPU1_KRST或通过PMI相关寄存器释放从核。从核被唤醒后,各自从指定入口开始执行自己的启动代码,完成各自的栈、数据段初始化,再进入各自的main或任务循环。

多核启动的同步很关键。常见做法是用一个全局标志或__sync()屏障,让CPU0在从核就绪后再继续后续初始化,避免从核访问尚未初始化的共享资源。启动顺序上,建议先完成CPU0的时钟与看门狗配置,再唤醒从核,这样从核继承的是已稳定的时钟环境。

启动时间优化实战

启动时间优化的核心是找出耗时大头并针对性削减。典型耗时项包括:PLL锁定等待、数据段搬运、从核唤醒与同步、外设初始化。优化手段有:

  • 并行化:CPU0配置时钟的同时,让从核先做各自的数据段初始化,减少串行等待。
  • 精简搬运:只把真正需要初始化的.data搬入RAM,未用段不链接;大数组用const留在Flash。
  • 缩短PLL等待:在PLL锁定期间插入有用的初始化工作,而不是空等。
  • 按需初始化外设:把非关键外设初始化从启动阶段移到main之后按需执行。

判断优化是否有效,应在启动代码的关键节点翻转GPIO或用STM打时间戳,测量各段耗时。例如在SSW结束、时钟切换完成、从核就绪、进入main四个点各翻转一次IO,用示波器观察各段宽度,就能定位瓶颈。示例目标(假设):将启动时间从约80ms压缩到40ms以内,其中PLL等待与数据段搬运各占约30%。

启动代码定制后,务必在冷启动、热复位、看门狗复位三种场景下分别验证,确认多核都能正常进入各自任务,且没有因ENDINIT或看门狗配置不当导致的偶发复位。