STM32H7 400MHz 下 FDCAN 与 TSN 时间同步的硬件级抖动补偿实现

1. 引言

在工业自动化和汽车电子领域,FDCAN(Flexible Data-rate CAN)和 TSN(时间敏感网络)常被用于实时控制与数据采集。当两者共存于一个系统时,时间同步的精度直接决定控制质量。STM32H7 系列以 400MHz 主频和丰富的外设资源,成为实现高精度时间同步的理想平台。然而,软件时间戳和中断延迟会引入微秒级抖动,无法满足 TSN 的亚微秒同步要求。本文聚焦于利用 STM32H7 的硬件特性(FDCAN 硬件时间戳、定时器输入捕获、DMA)来补偿抖动,实现硬件级的时间同步。

2. 时间同步误差来源

  • 软件时间戳:在中断中读取计数器,存在中断响应延迟(通常 1-3μs)。
  • FDCAN 协议延迟:帧传输、接收过滤、FIFO 存储等环节引入固定延迟。
  • 时钟漂移:本地晶振频率偏差导致累积误差。
  • 网络排队:TSN 交换机中的排队延迟(可通过 802.1AS 的路径延迟机制补偿)。

硬件级补偿的核心是:在报文到达/发送的物理时刻,由硬件自动捕获时间戳,并利用定时器同步机制消除抖动

3. STM32H7 硬件时间同步机制

3.1 FDCAN 硬件时间戳

STM32H7 的 FDCAN 外设内置 16 位或 32 位时间戳计数器(TSC),可配置为在帧起始(SOF)或帧结束(EOF)时自动捕获当前计数值。该计数器可由外部时钟或内部定时器驱动,支持与系统时间基准同步。

关键寄存器:

  • FDCAN_TTTC:时间戳配置,设置捕获点(SOF/EOF)和计数器使能。
  • FDCAN_RXBC:接收缓冲时间戳,每个 Rx FIFO 元素附带时间戳字段。
  • FDCAN_TXBC:发送缓冲时间戳,发送完成后自动记录。

3.2 TSN 时间同步(IEEE 802.1AS)

TSN 使用 gPTP(generalized Precision Time Protocol)实现时钟同步,通过交换 Sync 和 Follow_Up 报文计算路径延迟和时钟偏移。STM32H7 的以太网 MAC(支持 1588v2)可在硬件层捕获报文时间戳,但若与 FDCAN 桥接,需统一时间基准。

4. 硬件级抖动补偿设计

4.1 系统架构

  • 时间基准:使用 TIM2(32 位定时器)作为全局时间计数器,时钟源为 400MHz 的 PLL,分辨率 2.5ns。
  • FDCAN 时间戳:配置 FDCAN 的 TSC 由 TIM2 的 TRGO 事件驱动,确保与全局时间同步。
  • TSN 时间戳:以太网 MAC 的 1588 时间戳寄存器与 TIM2 同步(通过硬件触发)。
  • 抖动补偿:利用 TIM2 的捕获比较通道,对 FDCAN 和 TSN 事件进行硬件时间标记,并通过 DMA 将数据直接传输到内存,避免 CPU 干预。

4.2 配置步骤

  1. 初始化全局定时器 TIM2

    • 时钟源:内部时钟(400MHz),预分频器设为 0,自动重载值 0xFFFFFFFF(自由运行)。
    • 使能 TRGO 输出(用于驱动 FDCAN 和以太网)。
  2. 配置 FDCAN 硬件时间戳

    • 在 FDCAN 初始化中,设置 TTTC 寄存器,选择 SOF 捕获,使能时间戳计数器。
    • 将 FDCAN 的时钟源设为 TIM2 的 TRGO(通过 FDCAN_CCCRTSCC 字段)。
  3. 配置以太网 1588 时间戳

    • 使能 IEEE 1588 功能,设置时间戳寄存器与 TIM2 同步(通过硬件连接或软件校准)。
  4. DMA 传输

    • 为 FDCAN 接收 FIFO 和以太网 Rx 描述符配置 DMA,将时间戳字段直接搬运到内存缓冲区。

4.3 代码示例(基于 HAL 库)

// 初始化 TIM2 作为全局时间基准
void TIM2_Init(void) {
    TIM_HandleTypeDef htim2;
    htim2.Instance = TIM2;
    htim2.Init.Prescaler = 0;  // 400MHz
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim2.Init.Period = 0xFFFFFFFF;  // 自由运行
    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    HAL_TIM_Base_Init(&htim2);
    TIM_MasterConfigTypeDef sMasterConfig = {0};
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;  // 产生 TRGO
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
    HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig);
    HAL_TIM_Base_Start(&htim2);
}

// 配置 FDCAN 硬件时间戳
void FDCAN_TimeStamp_Init(FDCAN_HandleTypeDef *hfdcan) {
    FDCAN_TTTC_TypeDef tttc = {0};
    tttc.TSCC = FDCAN_TTTC_TSCC_INTERNAL;  // 内部时钟(由 TIM2 TRGO 驱动)
    tttc.TSS = FDCAN_TTTC_TSS_SOF;         // 在 SOF 捕获
    tttc.TSE = 1;                          // 使能时间戳
    hfdcan->Instance->TTTC = tttc;
}

// 读取接收帧的时间戳(在接收回调中)
void FDCAN_RxCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t fifo) {
    FDCAN_RxHeaderTypeDef rxHeader;
    uint8_t data[8];
    HAL_FDCAN_GetRxMessage(hfdcan, fifo, &rxHeader, data);
    uint32_t timestamp = rxHeader.Timestamp;  // 硬件捕获的全局时间戳
    // 将 timestamp 与 TSN 时间戳比较,计算偏移
}

// 配置以太网 1588 时间戳(简化)
void ETH_1588_Init(ETH_HandleTypeDef *heth) {
    heth->Init.TimeStamp = ETH_TIMESTAMP_ENABLE;
    // 设置时间戳寄存器更新频率等
    HAL_ETH_Init(heth);
}

4.4 抖动补偿算法

由于硬件时间戳在物理层捕获,抖动主要来自时钟源不同步。补偿策略:

  • 偏移测量:通过定期交换 Sync 报文,计算 FDCAN 与 TSN 主时钟的偏移量。
  • 速率调整:利用 TIM2 的捕获比较通道,微调定时器分频系数(通过 TIM_PrescalerConfig)以补偿晶振漂移。
  • 延迟补偿:对 FDCAN 帧的固定协议延迟(如 2 位时间)进行软件修正,因为硬件时间戳在 SOF,而应用需要数据到达时刻。

5. 注意事项

  • 时钟树设计:确保 TIM2 的时钟源为 400MHz 的 PLL,且与以太网 PTP 时钟同源,避免异步时钟域引入额外抖动。
  • DMA 优先级:为 FDCAN 和以太网 DMA 设置高优先级,防止数据覆盖。
  • 中断处理:即使有硬件时间戳,仍需在中断中快速读取数据,但时间戳读取不受中断延迟影响。
  • 测试验证:使用示波器测量 PPS(脉冲每秒)信号,验证同步精度。建议在 100Mbps 以太网和 5Mbps FDCAN 下测试,抖动应小于 100ns。
  • 固件升级:修改时间戳配置后,需重新校准偏移量,避免累积误差。

6. 总结

通过 STM32H7 的硬件时间戳和定时器同步机制,可以在 400MHz 主频下实现 FDCAN 与 TSN 的亚微秒级时间同步,抖动补偿完全由硬件完成,减轻 CPU 负担。本文提供的方案适用于工业网关、运动控制等场景,开发者可根据实际需求调整时间基准和补偿算法。