1. DSP28035 CAN总线固件升级方案概述
在工业控制和嵌入式系统开发中,现场固件升级是一个关键需求。基于TI DSP28035处理器的CAN总线升级方案,提供了一种稳定可靠的远程更新方式。这个方案包含三个核心组件:DSP28035端的Bootloader程序、用于测试的应用程序固件,以及采用C#开发的上位机工具。
我曾在多个工业电机控制项目中采用类似的方案,相比传统的串口或JTAG升级方式,CAN总线升级具有明显的优势。首先,CAN总线天生具备抗干扰能力,适合工业环境;其次,双绞线传输距离可达数千米,满足大多数现场需求;最重要的是,这种方案允许在不拆机的情况下完成固件更新,大幅降低维护成本。
2. 硬件与通信协议设计
2.1 DSP28035硬件配置要点
DSP28035的CAN模块需要正确初始化才能保证稳定通信。以下是关键配置参数:
c复制// CAN模块初始化代码片段
ECanaRegs.CANMC.bit.STM = 1; // 自测试模式
ECanaRegs.CANMC.bit.ABO = 1; // 自动总线恢复
ECanaRegs.CANMC.bit.CCR = 1; // 改变配置请求
ECanaRegs.CANBTC.bit.BRP = 9; // 波特率预分频
ECanaRegs.CANBTC.bit.TSEG1 = 6; // 时间段1
ECanaRegs.CANBTC.bit.TSEG2 = 1; // 时间段2
ECanaRegs.CANMC.bit.CCR = 0; // 完成配置
注意:波特率计算需与实际物理层匹配。例如当DSP主频60MHz,BRP=9时,波特率=60MHz/((BRP+1)*(TSEG1+TSEG2+3))=500kbps
2.2 自定义通信协议设计
一个可靠的升级协议需要包含以下要素:
| 字段 | 长度 | 说明 |
|---|---|---|
| 帧头 | 2字节 | 固定为0xAA55 |
| 命令字 | 1字节 | 读/写/擦除等操作 |
| 地址 | 4字节 | Flash操作地址 |
| 长度 | 2字节 | 数据段长度 |
| 数据 | N字节 | 有效载荷 |
| CRC16 | 2字节 | 校验整个数据包 |
我在实际项目中发现,增加超时重传机制非常必要。建议设置300ms的响应超时,最多重试3次。同时,每个数据包应包含序列号,便于检测丢包和乱序情况。
3. Bootloader实现细节
3.1 内存布局规划
合理的存储器分配是Bootloader稳定运行的基础:
code复制0x3F8000 - 0x3FFFFF Bootloader区 (32KB)
0x3E0000 - 0x3F7FFF 应用程序区 (96KB)
0x000000 - 0x3DFFFF 预留其他用途
提示:TI DSP的Flash分为多个扇区,擦除时必须按扇区操作。DSP28035的每个扇区大小为4KB
3.2 关键操作流程
- Flash擦除:必须关闭中断,使用专用API
c复制void Flash_Erase(uint32 addr) {
EALLOW;
Flash_CPUScaleFactor = SCALE_FACTOR;
Flash_Erase((Uint32 *)addr);
EDIS;
}
- 数据写入:采用64位写入模式
c复制void Flash_Write(uint32 addr, uint32 *data) {
EALLOW;
Flash_CPUScaleFactor = SCALE_FACTOR;
Flash_Program((Uint32 *)addr, data, 2); // 2表示64位
EDIS;
}
- 跳转应用程序:
c复制void JumpToApp() {
void (*app_entry)(void) = (void (*)(void))0x3E0000;
EALLOW;
PieCtrlRegs.PIEIER1.all = 0;
IER = 0;
EDIS;
app_entry();
}
4. 上位机开发要点
4.1 C# CAN通信实现
使用PCAN-USB适配器时,典型初始化代码:
csharp复制TPCANHandle channel = TPCANHandle.PCAN_USBBUS1;
TPCANBaudrate baudrate = TPCANBaudrate.PCAN_BAUD_500K;
TPCANStatus result = PCANBasic.Initialize(channel, baudrate);
if (result != TPCANStatus.PCAN_ERROR_OK) {
// 错误处理
}
4.2 文件分片与传输策略
为提高传输效率,我建议采用以下策略:
- 将HEX或BIN文件按1KB分块
- 每个CAN帧携带8字节有效数据
- 实现滑动窗口协议,窗口大小建议4-8个包
- 添加进度显示和断点续传功能
典型的数据发送代码:
csharp复制void SendDataPacket(byte[] data, uint address) {
TPCANMsg msg = new TPCANMsg();
msg.ID = 0x100; // 目标设备ID
msg.LEN = 8;
msg.MSGTYPE = TPCANMessageType.PCAN_MESSAGE_STANDARD;
// 构造协议帧
byte[] packet = new byte[8];
packet[0] = 0xAA; // 帧头
packet[1] = 0x55;
packet[2] = 0x02; // 写命令
Buffer.BlockCopy(BitConverter.GetBytes(address), 0, packet, 3, 4);
packet[7] = CalculateChecksum(packet);
PCANBasic.Write(channel, ref msg);
}
5. 测试与验证方案
5.1 测试固件设计
建议测试固件包含以下功能验证:
- LED闪烁(系统运行指示)
- 按键响应(用户交互)
- ADC采样(模拟信号处理)
- PWM输出(驱动能力测试)
5.2 升级过程验证步骤
- 连接CAN总线,确保物理层正常
- 上位机发送握手命令,确认Bootloader响应
- 擦除目标扇区,验证返回状态
- 分块传输固件数据,每块校验CRC
- 发送跳转命令,观察设备行为
- 验证新固件功能是否正常
6. 常见问题与解决方案
我在实际部署中遇到过几个典型问题:
问题1:升级后程序无法运行
- 检查向量表重映射是否正确
- 验证应用程序的入口地址是否与Bootloader跳转地址一致
- 确认编译器生成的代码未超出预留空间
问题2:CAN通信不稳定
- 检查终端电阻(120Ω)是否安装
- 测量总线差分电压(正常应在1.5-2.5V之间)
- 降低波特率测试(如从500kbps降到250kbps)
问题3:Flash写入失败
- 确保在操作前禁用中断
- 检查电源电压是否稳定(≥3.3V)
- 验证Flash等待状态配置是否正确
7. 性能优化建议
经过多次项目实践,我总结出以下优化技巧:
- 压缩传输:在C#端使用LZ77算法压缩固件,DSP端解压,可减少40%传输时间
- 差分升级:只传输有变化的存储区域,适合小规模更新
- 双Bank设计:保留两个完整固件副本,升级失败自动回滚
- 后台验证:在应用程序中校验固件完整性,发现损坏时主动请求更新
对于需要更高安全性的场景,可以考虑添加AES-128加密和数字签名验证机制。虽然会增加一些代码量,但能有效防止未经授权的固件写入。
