引言

在工业自动化、机器人协同和车载网络中,时间同步是确保数据一致性和动作协调的基石。传统软件同步(如 PTP 软件实现)受中断延迟和调度抖动影响,精度仅达微秒级。STM32H7 系列(如 H745/H747)内置 FDCAN 控制器和 TSN(时间敏感网络)以太网 MAC,支持硬件时间戳,可在 400MHz 主频下实现纳秒级同步。本文将聚焦 FDCAN 与 TSN 的硬件级时间对齐,提供从原理到落地的完整方案。

硬件时间同步原理

1. 时间基准与时钟树

STM32H7 内部有一个 64 位自由运行定时器(如 TIM2/TIM5),可作为全局时间基准。FDCAN 和 TSN 外设均能捕获该定时器的值作为硬件时间戳。关键在于:

  • FDCAN:每个消息帧的 SOF(帧起始)和 EOF(帧结束)均产生时间戳,由硬件自动捕获,无需 CPU 干预。
  • TSN 以太网:支持 IEEE 802.1AS(gPTP),MAC 在帧的特定位置(如 SFD 后)打时间戳,精度可达 10ns 级。

2. 对齐策略

FDCAN 和 TSN 时间同步的核心是共享同一时间基准。STM32H7 允许将 TIM2 配置为“系统时间”源,FDCAN 和 TSN 均引用该定时器。通过软件校准,使两者时间戳偏差小于一个时钟周期(2.5ns @ 400MHz)。

硬件配置步骤

1. 时钟树配置

  • 使用 HSE(25MHz)经 PLL1 倍频至 400MHz 系统时钟。
  • 配置 TIM2 时钟源为 APB1 定时器时钟(通常为 200MHz),并启用 64 位计数模式(通过级联 TIM2+TIM3 实现)。

2. FDCAN 时间戳使能

  • 在 FDCAN 初始化中,设置 Timestamp 选项,选择内部定时器作为时间戳源。
  • 启用 Timestamp 捕获于 SOF 和 EOF。

3. TSN 以太网配置

  • 使用 STM32H7 的 Ethernet MAC(支持 TSN),启用 802.1AS 协议栈(如 FreeRTOS+TCP 或 lwIP 的 PTP 扩展)。
  • 配置 MAC 的 Timestamp 寄存器,选择与 FDCAN 相同的 TIM2 作为时间源。

代码示例

以下代码基于 STM32H7 HAL 库,演示如何配置 TIM2 为时间基准,并同步 FDCAN 与 TSN 时间戳。

// 1. 初始化 TIM2 为 64 位时间基准
void TIM2_TimeBase_Init(void) {
    TIM_HandleTypeDef htim2;
    htim2.Instance = TIM2;
    htim2.Init.Prescaler = 0; // 200MHz 直接计数
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim2.Init.Period = 0xFFFFFFFF; // 32 位,配合 TIM3 级联
    HAL_TIM_Base_Init(&htim2);
    HAL_TIM_Base_Start(&htim2);
}

// 2. FDCAN 时间戳配置
void FDCAN_Timestamp_Config(FDCAN_HandleTypeDef *hfdcan) {
    hfdcan->Init.TimestampConfig = FDCAN_TIMESTAMP_INTERNAL;
    hfdcan->Init.TimestampPrescaler = 1; // 每个 CAN 位时间计数一次
    hfdcan->Init.TimestampSource = FDCAN_TIMESTAMP_SOURCE_TIM2; // 选择 TIM2
    HAL_FDCAN_Init(hfdcan);
    HAL_FDCAN_Start(hfdcan);
}

// 3. TSN 以太网时间戳配置(简化)
void TSN_Timestamp_Config(ETH_HandleTypeDef *heth) {
    // 启用 MAC 时间戳
    heth->Init.TimestampConfig = ETH_TIMESTAMP_ENABLE;
    heth->Init.TimestampSource = ETH_TIMESTAMP_SOURCE_TIM2; // 与 FDCAN 同源
    HAL_ETH_Init(heth);
    // 配置 PTP 消息过滤
    HAL_ETH_PTP_Config(heth, ETH_PTP_MASTER_NODE);
}

// 4. 读取时间戳并计算偏差
uint64_t Get_FDCAN_Timestamp(FDCAN_HandleTypeDef *hfdcan, uint32_t fifo) {
    FDCAN_RxHeaderTypeDef rxHeader;
    uint8_t data[8];
    HAL_FDCAN_GetRxMessage(hfdcan, fifo, &rxHeader, data);
    return rxHeader.Timestamp; // 硬件捕获的 TIM2 值
}

uint64_t Get_TSN_Timestamp(ETH_HandleTypeDef *heth) {
    ETH_PTP_TimeStampTypeDef ts;
    HAL_ETH_GetRxTimestamp(heth, &ts);
    return ((uint64_t)ts.Seconds << 32) | ts.Nanoseconds; // 需转换为 TIM2 计数
}

// 5. 对齐校准函数(示例)
void Align_TimeSync(void) {
    uint64_t fdcan_ts = Get_FDCAN_Timestamp(&hfdcan1, FDCAN_RX_FIFO0);
    uint64_t tsn_ts = Get_TSN_Timestamp(&heth);
    int64_t delta = (int64_t)(fdcan_ts - tsn_ts);
    // 若 delta 大于阈值,则调整 TIM2 或软件补偿
    if (delta > 10) { // 10 个计数约 50ns
        __HAL_TIM_SET_COUNTER(&htim2, (uint32_t)(tsn_ts + 5)); // 简单校正
    }
}

注意事项

  • 时钟同步精度:确保 TIM2 时钟源稳定(使用 HSE 而非 HSI),否则温度漂移会导致偏差累积。
  • 中断优先级:时间戳读取应在高优先级中断中完成,避免被其他中断延迟。
  • FDCAN 位时间:FDCAN 的位时间需与 TIM2 计数周期匹配,否则时间戳分辨率不足。建议设置 TimestampPrescaler=1
  • TSN 协议栈:802.1AS 需要硬件辅助,若使用软件实现,精度会下降,务必启用 MAC 硬件时间戳。
  • 调试技巧:使用逻辑分析仪同时抓取 FDCAN 帧和以太网 PTP 帧,对比时间戳偏差,验证对齐效果。

总结

通过 STM32H7 的硬件时间戳机制,FDCAN 与 TSN 以太网可共享同一时间基准,实现纳秒级同步。本文提供的配置和代码可直接应用于工业控制或车载网关设计。实际项目中,建议结合 RTOS 和 PTP 协议栈进行动态校准,以应对环境变化。掌握这一技术,将显著提升系统的实时性和可靠性。