mirror of
https://gitee.com/dlmu-cone/half-steering-basic-framework
synced 2026-10-24 01:52:20 +08:00
3.1 KiB
3.1 KiB
CAN 非阻塞发送改造 · 隐患记录
记录时间:2026-08-29 背景:修复“拔掉 CAN1 后,CAN2 上的 pitch / 摩擦轮 / 拨盘电机明显抖动”的问题。
一、本次改动摘要
| 文件 | 改动 | 目的 |
|---|---|---|
| bsp/can/bsp_can.c | CANTransmit() 由忙等改为非阻塞 |
避免某一路 CAN 离线时拖慢电机控制任务 |
| bsp/can/bsp_can.c | CANAddFilter() 对 can_filter_conf 先 memset 清零 |
避免未初始化字段成为垃圾匹配 ID |
| Src/can.c | CAN1/CAN2 的 AutoBusOff 改为 ENABLE |
断开后重新连接能自动从 bus-off 恢复 |
二、隐患与风险
1. 双板模式下的 CANCommSend 多帧发送可能丢包(当前为休眠隐患)
- 相关位置:
modules/can_comm/can_comm.c的CANCommSend()(约 106、116、121 行)。 CANCommSend()按每 8 字节一帧连续发送。当待发送数据超过 24 字节(即超过 3 帧)时,第 4 帧起会因为 3 个发送邮箱都还在忙碌而被直接丢弃。- 原来的忙等版本会等待邮箱空闲后继续发完,非阻塞版本不会。
- 当前工程为
ONE_BOARD,该路径未参与编译,暂无影响;一旦切换到CHASSIS_BOARD/GIMBAL_BOARD,此问题会暴露。
2. 丢帧变为静默,失去诊断信息
- 相关位置:
bsp/can/bsp_can.c的CANTransmit()(约 107 行)。 - 原实现邮箱满时会打印
LOGWARNING;现在直接return 0,不重试、不记录。 - 未来若总线设备增多或发送频率升高出现真实拥塞,丢帧将不可见,排查难度增加。
- 对 DJI 电机本身影响较小:500 Hz 控制帧偶尔丢一两帧,电机内部看门狗时间远大于 2 ms,不会触发保护。
3. timeout 参数实际失效
CANTransmit()签名仍保留float timeout,但函数内部用(void)timeout忽略了它。- 调用方传入的
1、0.2、0.5等值已不再生效,存在可读性与预期一致性隐患。
4. AutoBusOff 行为变化 + CubeMX 覆盖风险
- 相关位置:
Src/can.c(约 48、80 行)。 - 改为
ENABLE后,持续总线故障(如短路)会导致控制器在 bus-off ↔ 恢复之间反复循环;当前未开启 CAN 错误中断,不会产生中断风暴,但行为不同于DISABLE时的锁死状态。 Src/can.c是 CubeMX 生成文件,从basic_framework.ioc重新生成工程时会被覆盖回DISABLE,需要同步修改.ioc中的 Automatic Bus-Off Management 选项。
5. 过滤器配置 memset(基本无风险)
- 相关位置:
bsp/can/bsp_can.c的CANAddFilter()(约 32 行)。 - 属于纯修正,无副作用。
三、建议后续动作
- 若将来启用双板,给
CANCommSend()的多帧发送增加“短且有界”的等待/重试,避免丢中间帧。 - 评估是否为
CANTransmit()增加可选的丢帧统计或低频告警,在“不阻塞任务”与“可诊断”之间取得平衡。 - 在
basic_framework.ioc中同步开启两个 CAN 的 Automatic Bus-Off Management,避免重新生成代码时被覆盖。
四、相关文件
bsp/can/bsp_can.cmodules/can_comm/can_comm.cSrc/can.c