第二章:硬件平台介绍

做Bootloader,说白了就是跟硬件打交道。你代码写得再漂亮,硬件不支持也是白搭。这一章,我带你看看我们选型时是怎么考虑的。

2.1 主控芯片选型:STM32 vs GD32

先聊聊芯片选型。我个人习惯,做车灯控制这类产品,首选就是ARM Cortex-M系列。为什么?生态好、资料多、坑少。

STM32和GD32,这两家我都用过。STM32F103算是经典款,我最早的项目就是用它。后来国产化要求上来,开始用GD32F103。说实话,两者在Bootloader层面差别不大,但有几个细节要注意:

对比项 STM32F103 GD32F103
Flash容量 64KB~512KB 64KB~256KB
SRAM 20KB~64KB 8KB~96KB
主频 72MHz 108MHz
Flash擦写次数 1万次(典型) 10万次(官方宣称)
价格 偏高 便宜30%~50%

我的建议:如果项目对成本敏感,GD32完全够用。但要注意,GD32的Flash擦写时序和STM32略有不同,驱动代码不能直接复制。我曾经吃过这个亏,烧录到一半芯片锁死了...嗯,后来老老实实改了驱动。

2.2 Flash分区规划

Flash分区是Bootloader的核心。你想想看,代码要升级,总得有个地方放新程序吧?

我一般这样分:

Flash布局(以256KB为例):
0x08000000 - 0x08003FFF  →  Bootloader区(16KB)
0x08004000 - 0x08007FFF  →  参数存储区(16KB)
0x08008000 - 0x0801FFFF  →  应用程序区(96KB)
0x08020000 - 0x0803FFFF  →  升级缓存区(128KB)

为什么这么分?

  • Bootloader区:16KB够用了。我习惯放最精简的代码,只做跳转和升级。
  • 参数存储区:放校准数据、配置参数。注意,这里要预留备份,防止写一半掉电。
  • 应用程序区:正常跑业务逻辑的地方。
  • 升级缓存区:接收新固件时先放这里,校验通过再搬移到应用程序区。

避坑指南:我曾经把参数区和Bootloader区挨得太近,结果一次升级把参数区擦掉了。客户的车灯全部恢复出厂设置...从那以后,我强制要求分区之间留4KB的空白区域,物理隔离。

2.3 通信接口:UART / CAN / LIN

Bootloader总得跟外界通信吧?车灯控制单元常用的就这三种。

2.3.1 UART(通用异步收发器)

最简单、最常用。我调试阶段基本都用UART。三根线:TX、RX、GND,搞定。

  • 波特率:115200bps最常见,但车规级建议用9600或19200,抗干扰强。
  • 协议:我一般用Ymodem协议,简单可靠。网上有现成代码,改改就能用。
  • 缺点:距离短(1米以内),没有校验机制。

小技巧:量产时可以用UART做Bootloader,但记得加个硬件流控(RTS/CTS)。我遇到过线缆太长导致数据错位的,加了流控就稳了。

2.3.2 CAN(控制器局域网)

车灯控制的主流接口。为什么?因为车灯通常挂在CAN总线上,跟BCM(车身控制器)通信。

  • 速率:250kbps或500kbps,车规标准。
  • 协议:基于CAN的UDS(统一诊断服务)协议,0x34服务用于下载,0x36服务用于数据传输。
  • 优点:距离远(40米@1Mbps),抗干扰强,有CRC校验。

我记得第一次做CAN Bootloader时,被UDS协议折腾得够呛。后来发现,其实核心就几个ID:

物理请求ID:0x7E0
物理响应ID:0x7E8
功能请求ID:0x7DF

说白了,就是往0x7E0发数据,从0x7E8收回复。搞懂这个,剩下的就是填数据了。

2.3.3 LIN(本地互联网络)

LIN是CAN的廉价替代方案。车灯里的小灯、氛围灯常用。

  • 速率:最高20kbps,慢但够用。
  • 协议:基于LIN 2.1规范,用NAD(节点地址)区分设备。
  • 优点:成本低,一根线就能通信。
  • 缺点:速度慢,升级一个64KB的固件要半分钟。

我的经验:LIN Bootloader最头疼的是时间同步。因为LIN是主从结构,升级时从机不能主动发数据。我一般让主机每发一包数据,等从机回复确认,再发下一包。虽然慢,但稳。

2.4 接口选型建议

说了这么多,到底选哪个?我列个表,你一看就明白:

应用场景 推荐接口 理由
研发调试 UART 简单、快速、工具多
前大灯控制 CAN 主流、可靠、支持UDS
氛围灯/小灯 LIN 成本低、够用
OTA远程升级 CAN + 4G模块 远程、安全、可管理

嗯,这一章就到这里。硬件平台选好了,下一章我们开始写代码。你想想看,Bootloader的入口函数怎么写?中断向量表怎么重映射?到时候我手把手带你过一遍。

课后思考:如果你的Flash只有64KB,怎么规划分区?试试看,把Bootloader压缩到8KB,应用程序留56KB,升级缓存区放哪里?