在 STM32G0 系列 MCU 的工业通信场景中,FDCAN(Flexible Data Rate CAN)因高速率、大带宽特性被广泛应用。然而,某客户在使用 STM32G0B1 的 FDCAN 外设时,遇到了罕见的 “双重异常”—— 既存在接收丢包,又出现接收多包(主机发 3000 包,从机收 3006 包),且异常随机触发,CAN 分析仪抓包也未能直接定位原因。本文基于 ST 官方技术文档 LAT1509(Rev 1.0),从现场调研、问题复现、根源拆解到代码优化,全面解析这两类异常的核心诱因,提供可直接复用的排查方法与解决方案。
资料获取:开发经验 | LAT1509 STM32G0B1的FDCAN进行通信丢包和多包案例分享
1. 问题背景:罕见的 FDCAN 双重通信异常
客户基于 STM32G0B1 开发工业控制设备,核心需求是通过 FDCAN 与主机进行可靠数据交互。但实际测试中出现两大关键异常:
- 多包异常:主机固定发送 3000 包数据(100ms / 包),STM32G0B1 接收端偶尔收到 3006 包等超出发送量的数据包,且多余数据包为无效数据;
- 丢包异常:当主机发送间隔缩短至 3-5ms / 包时,接收端出现明显丢包,FDCAN 状态寄存器触发 “Overrun(溢出)” 标志;
- 异常特征:双重异常随机触发,无固定规律,直连 CAN 总线无线路故障,排除物理层问题。
2. 问题复现与核心现象捕捉
为定位根源,技术团队前往客户现场搭建同步测试环境,通过代码 Debug 与硬件波形测量,精准捕捉异常触发条件。
2.1 测试环境配置
- 硬件平台:STM32G0B1 开发板、CAN FD 分析仪、主机发送端(专业 CAN 测试工具);
- 软件工具:STM32CubeIDE、HAL 库 FDCAN 驱动;
- 关键参数:FDCAN 数据包大小 64Byte,STM32G0B1 主频 64MHz,FDCAN RxFIFO 容量 64Byte(默认配置)。
2.2 丢包异常复现与波形测量
通过调整主机发送间隔,复现丢包场景,并在 FDCAN 中断服务函数(ISR)中嵌入 GPIO 电平翻转逻辑,测量 ISR 实际处理时间:
- 发送端单包发送时间(t2-t1):约 2ms;
- 接收端 ISR 处理时间(t4-t3):约 3.5ms;
- 异常触发条件:当主机发送间隔(T5-T2)≤ ISR 处理时间(3.5ms)时,前一帧数据的 ISR 未执行完毕,后一帧数据已到达,导致 RxFIFO 溢出丢包。
2.3 多包异常复现与错误码捕捉
暂停程序运行后,查看 FDCAN 全局错误码,发现hfdcan1.ErrorCode被置位HAL_FDCAN_ERROR_FIFO_EMPTY(RxFIFO 空时读取)。结合接收回调函数逻辑,确认多包异常与代码读取 FIFO 的逻辑错误直接相关。
3. 根源拆解:丢包与多包的核心诱因
(一)丢包异常:Overrun 溢出的本质 —— 性能与时序不匹配
STM32G0B1 作为入门级、低成本 MCU,其 FDCAN IP 为精简版本,存在两大性能约束,叠加时序设计不当,导致丢包:
1. 核心约束条件
- 硬件约束:RxFIFO 容量仅 64Byte,与客户的 64Byte 数据包大小完全一致,无冗余缓存空间;
- 性能约束:主频 64MHz,HAL 库 FDCAN 中断处理(数据拷贝、校验等)耗时较长(实测 3.5ms)。
2. 溢出丢包的触发逻辑
FDCAN 接收端的 RxFIFO 采用 “阻塞模式”(默认配置,RXGFC.FnOM=0),即 FIFO 满后不再接收新数据。结合时序分析,丢包原因如下:
- 主机发送间隔(3-5ms)≤ ISR 处理时间(3.5ms):前一帧数据的 ISR 未完成(数据未从 FIFO 读出),后一帧数据已到达,导致 FIFO 溢出;
- 时序关系要求:可靠传输需满足「主机发送间隔(T5-T2)> ISR 处理时间(t4-t3)」,客户场景未满足该条件;
- 直观波形示意:
阶段 发送端行为 接收端行为 异常触发点 正常时序 发送间隔 > ISR 耗时 前一 ISR 完成后,新帧到达 无 异常时序 发送间隔 < ISR 耗时 前一 ISR 未完成,新帧到达 RxFIFO 溢出,触发 Overrun
176