STM32H7 400MHz 下 FDCAN 与 TSN 以太网协同的实时调度策略深度解析
👁 2 阅读 · 2026-08-27 · 嵌入式
在工业控制与车载网络中,STM32H7 凭借 400MHz 主频和丰富外设,常需同时处理 FDCAN 与 TSN 以太网流量。然而,两者共享中断与内存带宽,若调度不当将导致实时性崩溃。本文深入剖析 FDCAN 与 TSN 的硬件特性,提出基于优先级抢占、时间触发与 DMA 分流的三层协同调度策略,并给出完整代码示例与配置要点,帮助开发者构建确定性通信系统。
# 引言
STM32H7 系列(如 STM32H743/750)在 400MHz 下性能强劲,但面对 FDCAN(最高 8Mbps)与 TSN 以太网(100M/1G)的并发流量,CPU 中断处理与内存访问冲突成为瓶颈。TSN 要求微秒级时间同步,FDCAN 则需毫秒级确定性响应。本文从硬件架构出发,设计一套可落地的实时调度策略,确保两类总线互不干扰。
# 硬件基础:FDCAN 与 TSN 的协同难点
## 1. FDCAN 特性
- 支持 Classic CAN 与 CAN FD 格式,数据段最高 8Mbps。
- 每个 FDCAN 有独立消息 RAM(如 10KB),支持 Rx FIFO 与 Tx Event FIFO。
- 中断可配置为 FIFO 非空中断或专用事件中断。
## 2. TSN 以太网特性
- 基于 100M/1G Ethernet MAC,支持 IEEE 802.1Qbv(时间感知整形)与 802.1AS(时间同步)。
- 通常使用 DMA 描述符环,中断触发频率高(每帧或每批帧)。
## 3. 冲突根源
- 两者共享 Cortex-M7 中断控制器(NVIC)和 AXI 总线带宽。
- 高频率 TSN 中断可能饿死 FDCAN 中断,反之亦然。
- 内存拷贝(如从 DMA 缓冲区到应用缓冲区)占用大量 CPU 周期。
# 协同调度策略设计
## 策略总览
采用三层架构:
1. **优先级抢占**:基于 NVIC 中断优先级,确保 FDCAN 关键帧优先。
2. **时间触发**:利用 TSN 的 802.1Qbv 门控列表,在特定时隙暂停非关键以太网流量,为 FDCAN 留出带宽。
3. **DMA 分流**:将 FDCAN 数据直接通过 DMA 搬运至内存,减少 CPU 介入;TSN 使用独立 DMA 通道,避免竞争。
## 第一层:NVIC 优先级配置
- 将 FDCAN 中断优先级设为最高(如 0),TSN 设为次高(如 1)。
- 注意:Cortex-M7 支持 16 级优先级(0-15),数值越小优先级越高。
- 使用 `HAL_NVIC_SetPriority` 设置,并确保抢占优先级分组合理(如 Group4)。
## 第二层:TSN 门控调度
- 配置 802.1Qbv 门控列表,周期为 1ms,其中前 200μs 关闭 TSN 发送队列,专供 FDCAN 处理。
- 利用 STM32H7 的 Ethernet MAC 的 Qbv 支持(需外接 TSN 交换机或 PHY)。
- 在门控关闭期间,TSN 帧缓存于 DMA 描述符中,不触发中断。
## 第三层:DMA 分流与中断合并
- FDCAN 使用双缓冲 DMA(如 DMA1 Stream0),接收数据直接写入预分配缓冲区,仅在缓冲区满或超时触发中断。
- TSN 使用 DMA2 的独立通道,并启用中断聚合(如每 10 帧触发一次)。
- 通过 `HAL_FDCAN_ActivateNotification` 配置 FIFO 水位线,减少中断频率。
# 代码实现示例
以下代码基于 STM32H743,使用 HAL 库。
## 1. 初始化 FDCAN 与 DMA
```c
// FDCAN 配置
FDCAN_HandleTypeDef hfdcan1;
hfdcan1.Instance = FDCAN1;
hfdcan1.Init.ClockDivider = FDCAN_CLOCK_DIV1;
hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_BRS;
hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan1.Init.AutoRetransmission = ENABLE;
// ... 其他配置
HAL_FDCAN_Init(&hfdcan1);
// 配置 DMA 接收(假设使用 DMA1 Stream0)
DMA_HandleTypeDef hdma_fdcan_rx;
hdma_fdcan_rx.Instance = DMA1_Stream0;
hdma_fdcan_rx.Init.Request = DMA_REQUEST_FDCAN1;
hdma_fdcan_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_fdcan_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_fdcan_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_fdcan_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_fdcan_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_fdcan_rx.Init.Mode = DMA_CIRCULAR;
HAL_DMA_Init(&hdma_fdcan_rx);
__HAL_LINKDMA(&hfdcan1, hdma, hdma_fdcan_rx);
// 启动接收,使用 FIFO0,水位线为 1 帧
HAL_FDCAN_Start(&hfdcan1);
HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0);
```
## 2. TSN 以太网配置(简化)
```c
// 以太网 DMA 描述符配置,使用独立 DMA2
ETH_HandleTypeDef heth;
heth.Instance = ETH;
heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
// ... 其他配置
HAL_ETH_Init(&heth);
// 启用 Qbv 门控(需通过寄存器操作或 HAL 扩展)
// 假设门控列表:0-199μs 关闭发送,200-999μs 打开
ETH_QbvConfigTypeDef qbvConfig;
qbvConfig.GateControlList[0].Time = 200; // 单位 μs
qbvConfig.GateControlList[0].GateState = ETH_QBV_GATE_OPEN;
qbvConfig.GateControlList[1].Time = 800;
qbvConfig.GateControlList[1].GateState = ETH_QBV_GATE_CLOSE;
HAL_ETH_SetQbvConfig(&heth, &qbvConfig);
```
## 3. 中断处理与调度
```c
// FDCAN 中断回调(最高优先级)
void HAL_FDCAN_RxFifo0MsgPendingCallback(FDCAN_HandleTypeDef *hfdcan) {
// 直接处理,无需额外调度,因为优先级已保证
FDCAN_RxHeaderTypeDef rxHeader;
uint8_t rxData[64];
HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &rxHeader, rxData);
// 处理数据...
}
// TSN 中断回调(次高优先级)
void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth) {
// 检查门控状态,若在关闭时隙则延迟处理
if (__HAL_ETH_GET_IT_SOURCE(heth, ETH_DMACIER_RBUIE)) {
// 简单处理:将帧放入队列,由主循环处理
// 注意:避免在中断中做复杂操作
}
}
```
## 4. 主循环中的协同处理
```c
while (1) {
// 处理 TSN 接收队列(非实时部分)
process_tsn_queue();
// 检查 FDCAN 发送完成标志,若需要可触发发送
if (fdcan_tx_request) {
HAL_FDCAN_AddMessageToTxMailbox(&hfdcan1, &txHeader, txData);
}
// 其他任务...
}
```
# 注意事项与优化建议
- **中断优先级分组**:确保使用 `HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4)`,否则抢占可能失效。
- **DMA 缓冲区对齐**:FDCAN 和 TSN 的 DMA 缓冲区需 32 字节对齐,避免 cache 一致性问题。
- **Cache 管理**:在 DMA 写入后,使用 `SCB_InvalidateDCache_by_Addr` 刷新,防止读取脏数据。
- **TSN 门控时间精度**:STM32H7 的 SYSTICK 或 LPTIM 可用于微秒级定时,但建议使用硬件定时器(如 TIM2)触发门控切换。
- **负载评估**:若 TSN 流量极大,可考虑将 FDCAN 中断改为轮询模式(如每 100μs 查询一次),但需权衡 CPU 占用。
- **调试技巧**:使用逻辑分析仪同时抓取 FDCAN 和 TSN 帧,验证调度时隙是否满足要求。
# 总结
通过 NVIC 优先级抢占、TSN 门控时间隔离和 DMA 分流,STM32H7 能够有效协同 FDCAN 与 TSN 以太网,实现微秒级确定性。关键在于合理配置硬件资源,避免中断风暴和内存竞争。本文提供的策略与代码可直接应用于工业网关或车载控制器,开发者可根据实际流量调整门控周期和优先级。