引言

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

// 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 以太网配置(简化)

// 以太网 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. 中断处理与调度

// 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. 主循环中的协同处理

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 以太网,实现微秒级确定性。关键在于合理配置硬件资源,避免中断风暴和内存竞争。本文提供的策略与代码可直接应用于工业网关或车载控制器,开发者可根据实际流量调整门控周期和优先级。