第2章 车规MCU基础:主流架构与存储映射

各位同学,咱们今天聊聊车规MCU的底子。说实话,我刚入行那会儿,面对ARM Cortex-M、RH850、TriCore这些架构,也是一头雾水。但干久了你会发现,万变不离其宗。

车规MCU和普通MCU最大的区别在哪?说白了就三个字:可靠性。你想想看,车上跑的程序要是出了bug,轻则黑屏重启,重则...嗯,你懂的。所以车规芯片在设计上,天生就带着「冗余」和「安全」的基因。

2.1 三大主流架构速览

目前车规市场,基本是ARM、瑞萨、英飞凌三足鼎立。我个人的经验是,选架构主要看应用场景:

架构 代表厂商 典型应用 我的评价
ARM Cortex-M/R NXP、TI、ST 车身控制、网关 生态最好,上手快
RH850 瑞萨 动力总成、底盘 硬核,适合老手
TriCore 英飞凌 ADAS、域控制器 性能怪兽,但贵

2.2 ARM Cortex-M/R系列

ARM架构大家应该最熟悉。Cortex-M系列主打低功耗,M7性能最强,带双精度浮点。Cortex-R系列呢?它有个绝活——硬件锁步。什么意思?就是两个核跑同样的代码,结果一比对,不一致就报错。

避坑指南:我曾经在一个项目中,用了Cortex-R5做安全启动。结果发现,如果锁步模式没配置好,两个核的时序偏差会导致误报。后来我加了个同步窗口,才搞定。

ARM的存储映射比较规整。以Cortex-M7为例:

0x00000000 - 0x1FFFFFFF: Code区(Flash)
0x20000000 - 0x3FFFFFFF: SRAM区
0x40000000 - 0x5FFFFFFF: 外设区
0xE0000000 - 0xE00FFFFF: 系统控制区(NVIC、MPU等)

嗯,这里要注意,Bootloader通常放在0x0000开头,也就是Flash的起始地址。为什么?因为芯片上电后,PC指针默认指向这里。

2.3 RH850架构

瑞萨的RH850,说实话,我第一次接触时挺不习惯的。它用的是自家G4MH内核,指令集和ARM完全不同。但它的强项在于功能安全——硬件自检、ECC、双核锁步,这些都是标配。

RH850的存储映射比较特殊。它有个「本地RAM」和「全局RAM」的概念。本地RAM每个核独享,全局RAM大家共享。我当年做Bootloader时,就踩过这个坑——把全局变量放到了本地RAM里,结果另一个核死活访问不到。

小技巧:RH850的Flash通常分多个Bank。做OTA升级时,可以利用Bank切换实现「乒乓升级」——一个Bank跑程序,另一个Bank写新固件。

2.4 TriCore架构

英飞凌的TriCore,性能是真的猛。它把RISC和DSP揉在一起,一个核能干MCU和DSP的活。AURIX系列是主流,TC3xx已经支持到6核了。

TriCore的存储映射有个特点——统一编址。Flash、RAM、外设都在同一个地址空间里。这给Bootloader开发带来了便利,因为不用来回切换模式。

0x80000000 - 0x8FFFFFFF: PFlash(程序Flash)
0x60000000 - 0x6FFFFFFF: DFlash(数据Flash)
0x70000000 - 0x7FFFFFFF: LMU(本地内存单元)
0xF0000000 - 0xF00FFFFF: 系统寄存器

我个人习惯,把Bootloader放在PFlash的低地址区,应用程序放在高地址区。中间留个隔离区,防止意外覆盖。

2.5 内存保护单元(MPU)

MPU这东西,说白了就是给内存上锁。车规MCU必须用MPU,因为要防止应用程序把Bootloader区域给踩了。

ARM的MPU最多支持16个区域。每个区域可以设置起始地址、大小、权限(读/写/执行)。我一般这样配置:

  • 区域0:Bootloader区(只读+执行)
  • 区域1:应用程序区(读+执行)
  • 区域2:RAM区(读写,不可执行)
  • 区域3:外设区(按需配置)

警告:我曾经犯过一个低级错误——把MPU的优先级搞反了。ARM的MPU规则是:区域号越小,优先级越高。如果你把应用程序区设为区域0,Bootloader区设为区域1,那应用程序就能随意访问Bootloader了。嗯,后果你懂的。

RH850的MPU叫「Memory Protection Unit」,但用法和ARM不太一样。它支持「背景区域」的概念——没被MPU覆盖的区域,默认是禁止访问的。这比ARM更严格,也更安全。

TriCore的MPU更复杂,它分「全局保护」和「本地保护」。全局保护由系统级配置决定,本地保护每个核可以单独设置。我建议做Bootloader时,把全局保护设为「只允许Bootloader修改MPU配置」,这样应用程序就动不了安全机制了。

2.6 存储映射实战要点

做Bootloader,存储映射是第一步。我总结了几条经验:

  1. Flash布局要留余量:Bootloader至少留128KB,别抠门。万一以后要加功能呢?
  2. 中断向量表要重定向:应用程序的中断向量表不能和Bootloader冲突。ARM用VTOR寄存器,RH850用INTC,TriCore用BIV。
  3. RAM分区要隔离:Bootloader和应用程序的RAM区域要分开。我习惯把Bootloader的栈放在RAM开头,应用程序的栈放在RAM末尾。
  4. MPU配置要固化:Bootloader启动时就把MPU配好,之后不再修改。这样即使应用程序跑飞了,也伤不到Bootloader。

核心观点:车规Bootloader的本质,就是「在安全的前提下,完成固件更新」。而安全的前提,就是存储映射和MPU配置。这两步做扎实了,后面的事就顺了。

好了,这一章的内容就到这。下一章咱们聊聊Bootloader的启动流程——从复位到跳转,每一步都有讲究。到时候我会拿一个实际项目中的代码来拆解,保证干货满满。