1. 深入理解DSP28335 CAN Bootloader的核心架构
大家好,我是老李,在工业控制领域摸爬滚打十多年了,今天想和大家聊聊DSP28335的CAN Bootloader方案。这个方案在实际项目中特别实用,特别是对于那些需要远程升级固件的工业设备。简单来说,Bootloader就是设备上电后运行的第一段程序,它决定是进入升级模式还是直接跳转到应用程序。
我见过很多工程师在实现Bootloader时遇到的坑,最常见的就是中断处理不当导致系统卡死,或者Flash操作失败让设备变砖。其实这些问题都可以通过合理的设计来避免。DSP28335的CAN Bootloader核心在于三个模块的协同:CAN通信模块负责数据传输,Flash操作模块负责固件存储,主控制模块负责整体调度。
在实际项目中,我一般会把Bootloader放在Flash的SECTORA和SECTORB,这两个扇区不会被升级过程擦除,相当于一个安全的"保险区"。应用程序则放在SECTORC到SECTORH,升级时这些区域会被完全擦除重写。这样的分区设计确保了即使升级过程中断电,Bootloader也不会被破坏,设备仍然可以重新进入升级流程。
2. CAN通信模块的中断机制深度解析
CAN通信是整个Bootloader的血液系统,负责从上位机接收固件数据。DSP28335的eCAN模块相当强大,支持32个邮箱,我们可以灵活配置发送和接收邮箱。
2.1 中断配置的关键细节
在我的实际项目中,配置CAN中断时有几个关键点需要特别注意。首先是波特率设置,基于150MHz的系统时钟,我通常这样配置:
// CAN波特率配置为500kbps
ECanaRegs.CANBTC.bit.BRPREG = 9; // 波特率预分频
ECanaRegs.CANBTC.bit.TSEG2REG = 2; // 时间段2
ECanaRegs.CANBTC.bit.TSEG1REG = 10; // 时间段1
这样配置出来的波特率非常稳定,我在工业现场测试过,距离200米通信依然可靠。然后是接收邮箱的配置,我习惯用邮箱31作为专用接收邮箱:
// 配置接收邮箱31
ECanaMboxes.MBOX31.MSGID.all = 0x1340; // 设置接收ID
ECanaMboxes.MBOX31.MSGID.bit.AME = 1; // 启用接收屏蔽
ECanaMboxes.MBOX31.MSGID.bit.AAM = 0; // 非自动应答模式
ECanaMboxes.MBOX31.MSGCTRL.bit.DLC = 8; // 数据长度8字节
接收中断的配置尤为重要,我建议把CAN接收中断连接到PIE组的第6个中断:
// 配置CAN接收中断
PieCtrlRegs.PIEIER9.bit.INTx6 = 1; // 使能PIE组9的第6中断
IER |= M_INT9; // 使能CPU第9级中断
EALLOW;
PieVectTable.ECAN1INTA = &ECana1_ISR; // 设置中断服务函数
EDIS;
2.2 中断服务函数的实战经验
中断服务函数是CAN通信的核心,这里我分享一个经过实战检验的写法:
__interrupt void ECana1_ISR(void)
{
// 检查是否是邮箱31接收中断
if (ECanaRegs.CANRMP.bit.RMP31 == 1)
{
// 读取接收到的数据
CanRxMsg.data[0] = ECanaMboxes.MBOX31.MDL.all;
CanRxMsg.data[1] = ECanaMboxes.MBOX31.MDH.all;
// 设置数据更新标志
rx_update = UPDATE;
// 清除中断标志
ECanaRegs.CANRMP.bit.RMP31 = 1;
}
// 清除PIE中断应答
PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
}
这里有个坑我踩过:一定要先读取数据再清除中断标志,否则可能会出现数据丢失。另外,中断服务函数要尽可能简洁,只做必要的操作,长时间的操作应该放到主循环中处理。
3. Flash操作模块的安全机制
Flash操作是Bootloader中最危险的部分,一旦出错就可能让设备变砖。我在项目中总结了一套安全的Flash操作流程。
3.1 Flash初始化和解锁
首先是要正确初始化Flash API,这个步骤很多人会忽略:
void FlashAPI_Init(void)
{
// 设置CPU频率缩放因子
Flash_CPUScaleFactor = 150 / 100; // 150MHz系统时钟
// 初始化回调函数指针
Flash_CallbackPtr = NULL;
// 检查Flash API版本
if (Flash_API_Version < 2.10)
{
// 版本过低,需要更新API
HandleError(FLASH_API_ERROR);
}
}
</



被折叠的 条评论
为什么被折叠?



