Files
half-steering-basic-framework/.Doc/CAN发送非阻塞改造隐患.md

57 lines
3.1 KiB
Markdown
Raw Permalink Normal View History

2026-08-29 19:55:45 +08:00
# 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.c`
- `modules/can_comm/can_comm.c`
- `Src/can.c`