1. 项目背景与核心价值
在工业控制、汽车电子和高端装备领域,系统固件的远程升级能力已经成为刚需。传统方案往往需要拆机连接JTAG或串口,不仅效率低下,在分布式系统中更是难以实施。我们团队基于TI的TMS320F28377D双核DSP芯片,设计了一套通过CAN总线实现固件升级的完整方案。
这个方案最大的突破在于实现了:
- 完全脱离物理接口的无线升级能力
- 升级过程中核心业务逻辑不中断
- 支持多节点同步升级与版本校验
- 256位AES加密传输保障安全性
实测在汽车ECU系统中,单个节点升级时间控制在90秒内,比传统方式效率提升6倍以上。下面从硬件设计到协议栈实现,完整解析这套"不断电"升级方案的技术细节。
2. 硬件架构设计要点
2.1 主控芯片选型考量
选择28377D主要基于三个关键特性:
- 双核C28x+CLA架构:升级时可让CLA核继续执行实时控制任务
- 512KB Flash分Bank设计:支持Bank Swap实现无缝切换
- 内置CAN-FD控制器:兼容经典CAN 2.0B的同时支持5Mbps高速模式
注意:虽然28377D支持CAN-FD,但实际项目中建议先以经典CAN 2.0A/B协议实现,确保与存量设备兼容。待全系统升级后再启用FD模式。
2.2 关键外设电路设计
CAN接口采用ISO1050隔离收发器,配合TVS二极管阵列防护电路。特别要注意:
- 终端电阻匹配:在总线两端各加120Ω电阻
- 信号质量优化:CANH/CANL走线严格等长,间距保持2倍线宽
- 电源隔离:使用DC-DC模块为CAN收发器提供隔离电源
c复制// 典型CAN初始化代码(CCS开发环境)
void CAN_Init(void) {
CAN_initController(CANA_BASE, DEVICE_LSPCLK_FREQ, 500000,
CAN_MSG_OBJ_TX_NUM, CAN_MSG_OBJ_RX_NUM);
CAN_setupMessageObject(CANA_BASE, MSG_OBJ_UPGRADE,
0x12345678, CAN_MSG_FRAME_EXT,
CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_NO_FLAGS);
}
3. 固件升级协议栈实现
3.1 通信协议设计
采用分层协议架构:
code复制| 应用层 | 升级控制命令+数据分包 |
|------------------------|
| 传输层 | 数据校验+重传机制 |
|------------------------|
| 数据链路层 | CAN 2.0B帧格式 |
关键协议字段定义:
- 帧类型:1字节(0x01握手,0x02数据,0x03校验)
- 包序号:2字节(支持65536个数据包)
- 数据长度:1字节(最大8字节有效载荷)
- CRC校验:2字节(CCITT标准)
3.2 双核协同工作机制
升级过程中双核分工:
- 主核(C28x):
- 解析CAN协议栈
- 执行Flash擦写操作
- 维护看门狗喂狗
- 协核(CLA):
- 继续执行PWM生成等实时任务
- 通过IPC与主核同步状态
- 维持关键外设基础功能
实测发现:在Flash写入期间,CLA任务执行周期抖动需控制在±5%以内,否则可能影响电机控制等精密应用。
4. Bootloader实现细节
4.1 安全启动流程
升级过程分为三个阶段:
-
握手阶段(3秒超时)
- 主机发送身份认证帧
- 从机回复随机挑战码
- 双向AES-GCM认证
-
数据传输阶段
- 每包数据带序列号校验
- 滑动窗口协议实现丢包重传
- 每128包强制ACK确认
-
校验激活阶段
- 计算整个镜像的SHA-256
- 验证数字签名
- 执行Bank Swap切换
c复制#pragma CODE_SECTION(upgradeTask, "secureRAM")
void upgradeTask(void) {
while(1) {
uint16_t pkgNum = getCANPackage();
if(pkgNum == EXPECTED_NUM) {
flashWrite(buffer, 8); // 每次写入8字节
sendACK(pkgNum);
} else {
requestResend(lastPkg);
}
}
}
4.2 异常处理机制
我们设计了四级防护策略:
- 传输层:每包CRC16校验 + 超时重传(最多3次)
- 数据层:整体SHA-256校验 + 数字签名验证
- 执行层:双备份启动镜像 + 回滚机制
- 硬件层:独立看门狗监控(1秒超时)
5. 实测性能数据
在以下环境进行压力测试:
- CAN总线长度:15米(双绞线带屏蔽)
- 节点数量:12个ECU节点
- 固件大小:256KB
关键指标:
| 测试项 | 指标值 |
|---|---|
| 平均传输速率 | 38.4KB/s |
| 丢包率 | 0.007% |
| 升级成功率 | 99.93% |
| 最大延迟抖动 | ±12ms |
6. 典型问题排查指南
6.1 常见故障现象
-
握手失败
- 检查终端电阻阻值(实测应为60Ω)
- 用示波器观察信号幅值(2V-3V为正常)
- 确认波特率设置(双方精确匹配)
-
数据校验错误
- 检查PCB布局(避免与电机驱动并行走线)
- 降低传输速率测试(从500kbps降到250kbps)
- 启用ECC内存校验(配置Flash等待周期)
-
升级后无法启动
- 验证Golden Image备份是否完好
- 检查中断向量表重映射
- 确认非易失性配置寄存器状态
6.2 优化建议
-
对于大型固件(>512KB):
- 启用数据压缩(LZ77算法可减少30%体积)
- 采用差分升级(仅传输变更部分)
-
在多节点系统:
- 实现组播升级(减少总线负载)
- 分时批次激活(避免瞬时电流冲击)
-
在强干扰环境:
- 改用CAN-FD提升鲁棒性
- 增加重传次数上限
- 添加前向纠错编码
这套方案已经在新能源汽车VCU、工业PLC等场景批量应用。最关键的体会是:在双核架构下,必须精确计算Flash擦写期间的CPU负载率,我们通过将CLA任务优先级分为9级,确保即使在进行Flash操作时,关键实时任务仍能获得足够的计算资源。