本文系统配置/拓扑(Topology):Raspberry Pi 3 (Grandmaster) → KSZ9477 (E2E TC) → AT32F403A (End Slave)
摘要
本文为上篇,介紹如何將 AT32F403A 微控制器搭配 DM9058 网络控制器作为 PTP End Slave 的完整环境建置流程,包括硬件连接、软件初始化、以及平台 bring-up 的详细步骤。
关键特色:
- ✅ 完整的三层 PTP 拓扑(Topology):GM → TC → ES
- ✅ PTP One-Step 模式 + E2E Transparent Clock
- ✅ 硬件时间戳記支援(DM9058)
- ✅ 详细的 AT32F403A + DM9058 Bring-up / 环境建置(⭐ 本文重點)
- ✅ 完整程序码范例与验证方法
适用读者:
- 嵌入式系统工程師
- 工業自動化开发者
- 时间同步系统研發人員
- 對 IEEE 1588 PTP 感興趣的技術人員
目录
1. 引言与背景
1.1 为什麼需要 PTP?
在現代工業自動化、测试測量、音視頻傳輸等領域,多个設備之間的高精度时间同步至關重要。傳統的 NTP(Network Time Protocol)只能提供毫秒级精度,無法滿足許多應用需求。
IEEE 1588 PTP 能夠实现:
- Sub-microsecond 精度:同步精度可達 100 納秒以內
- 硬件时间戳記:利用硬件捕捉精確时间
- 確定性延遲:透過 Transparent Clock 修正网络延遲
1.2 本文实作目標
建立一个完整可验证的 PTP 时间同步系统,並著重介紹 AT32F403A 作为 End Slave 的实作細節,包括:
- 硬件连接与初始化(SPI、GPIO、中断配置)
- PTP Daemon 软件整合
- 时间同步验证方法
- 常见问题与除错技巧
1.3 系统拓扑(Topology)概覽
本文使用以下固定拓扑(Topology)進行实作:
| 层次 | 設備 | 角色 | 协议 |
|---|---|---|---|
| 时间源 | Raspberry Pi 3 + DM9058 | Grandmaster (GM) | PTPv2 One-Step, UDP/IPv4 |
| 网络中繼 | Microchip KSZ9477 | E2E Transparent Clock (TC) | 硬件 PTP,CF 自動修正 |
| 同步目標 | AT32F403A + DM9058 | End Slave (ES) | PTPv2 One-Step, UDP/IPv4 |
文章重點分配:
- 上篇(本文):AT32F403A + DM9058 Bring-up 与环境建置(如何跑起來)
- 下篇:系统整合与测试(如何量测、如何除错)
2. 系统架构
2.1 整體系统拓扑图(System Topology)
以下 Mermaid 图展示完整的 PTP 时间同步拓扑(Topology),包含 Sync 与 Delay 消息的双向流向。
图说:
- 綠色:Grandmaster(时间源)
- 金色:Transparent Clock(网络中繼,自動修正延遲)
- 藍色:End Slave(本文实作重點)
- 實線箭頭:Sync 消息流向(Forward Path)
- 虛線箭頭:Delay 消息流向(Reverse Path)
- CF:Correction Field(修正欄位)
- S1 / S2(符號对照):
- S1:
Sync在透明时钟(TC)内部的駐留时间(Sync Residence Time)。 - S2:
Delay_Req在透明时钟(TC)内部的駐留时间(Delay Residence Time)。
- S1:
- S1 的計算:
Sync封包進入 TC 的入埠时间戳(Ingress) 与離開 TC 的出埠时间戳(Egress) 之差,即 S1 = Egress - Ingress。TC 会把 S1 累加到该Sync的CorrectionField(Forward path 修正)。 - S2 的計算:
Delay_Req封包進入 TC 的入埠时间戳(Ingress) 与離開 TC 的出埠时间戳(Egress) 之差,即 S2 = Egress - Ingress。TC 会把 S2 累加到该封包的CorrectionField(Reverse path 修正),讓后續計算能把「交換器内部造成的額外延遲」扣除掉,避免把它誤當成線路傳播延遲。 - 注意:此處 TC 的 Ingress/Egress 时间戳与后面四步交換公式中的 t1, t2, t3, t4 是不同的量测點。四步交換的 t1~t4 是指 Master 与 Slave 之間的端點时间戳,而 S1/S2 是 TC 内部的駐留时间。
2.1.1 多个 End Slave 的完整拓扑(Multiple End Slaves Topology)
以下 Mermaid 图展示完整的 PTP 时间同步拓扑(Topology),包含一个 Grandmaster、一个 Transparent Clock,以及兩个 End Slave 的架构。
图说:
- 綠色区域(时间源层):Grandmaster 作为唯一的时间源,向所有 End Slave 提供標準时间
- 金色区域(网络中繼层):Transparent Clock 作为多端口交換机,同時处理兩个 End Slave 的 PTP 消息
- 藍色区域(同步目標层):兩个 End Slave 設備,每个都獨立与 GM 進行时间同步
- 實線箭頭:Sync 消息流向(Forward Path),从 GM 透過 TC 分發到各个 ES
- 虛線箭頭:Delay_Req 与 Delay_Resp 消息流向(Reverse Path),每个 ES 獨立進行延遲測量
- CF 修正说明:
- S1_1, S1_2:各 ES 的 Sync 消息在 TC 內的駐留时间(可能不同,取決于 TC 内部路由)
- S2_1, S2_2:各 ES 的 Delay_Req 消息在 TC 內的駐留时间
- RT_1, RT_2:各 ES 的 Delay_Resp 消息在 TC 內的駐留时间(Residence Time)
多 Slave 拓扑(Topology)特點:
- 獨立同步:每个 End Slave 獨立計算自己的 Offset 与 Mean Path Delay
- TC 多端口处理:KSZ9477 作为多端口交換机,可同時处理多个 ES 的 PTP 消息
- CF 獨立修正:每个 ES 的消息在 TC 內的駐留时间可能不同,TC 会为每个消息獨立修正 CF
- 擴展性:理論上可支援多个 ES(实际數量受 TC 端口數与网络頻寬限制)
2.2 PTP One-Step 消息時序
PTP One-Step 模式的关键是时间戳記直接嵌入 Sync 消息,因此本项目不使用 Two-Step 消息。
四步时间交換:
- Sync(GM → TC → ES):Master 發送 Sync,t1 时间戳記嵌入消息中
- Delay_Req(ES → TC → GM):Slave 發送延遲請求,記錄發送时间 t3
- Delay_Resp(GM → TC → ES):Master 回應,包含接收 Delay_Req 的时间 t4
Slave 計算 Offset:
Offset = (t2 - t1 - CF_sync) - Mean_Path_Delay
Mean_Path_Delay = [(t2-t1-CF_sync) + (t4-t3-CF_delay)] / 2
2.3 E2E TC Correction Field (CF) 修正机制
E2E Transparent Clock 的核心功能是**累加网络駐留时间(Residence Time)**到 Correction Field。
CF 修正流程:
消息進入 TC → 記錄 Ingress 时间 → 处理与轉發 → 記錄 Egress 时间
→ 計算 Residence Time (RT = Egress - Ingress)
→ 更新 CF (CF_new = CF_old + RT) → 轉發修正后的消息
修正范例:
| 消息 | 進入 TC 時 CF | TC Residence | 離開 TC 時 CF |
|---|---|---|---|
| Sync (GM→ES) | 0 ns | 350 ns | 350 ns |
| Delay_Req (ES→GM) | 0 ns | 380 ns | 380 ns |
| Delay_Resp (GM→ES) | 0 ns | 340 ns | 340 ns |
重要:Slave 在計算 Offset 時必須考慮所有 CF 修正值,才能獲得準確的时间偏移量。
3. 硬件配置
3.1 Grandmaster: Raspberry Pi 3 + DM9058(簡要)
角色:提供標準时间源(Master Clock)
硬件配置:
- 主控:Raspberry Pi 3
- 网络接口:DM9058 10/100Mbps Ethernet(透過 SPI 连接)
- 软件:Linux PTP daemon (
ptp4l)
设定重點:
# RPi3 上的 ptp4l 配置
sudo ptp4l -i eth0 -m -S -l 6 -f master_config.cfg
master_config.cfg:
[global]
clockClass 0
priority1 128
slaveOnly 0
twoStepFlag 0 # One-Step 模式
network_transport UDPv4
time_stamping hardware # 硬件时间戳記
delay_mechanism E2E # End-to-End 延遲机制
3.2 Transparent Clock: Microchip KSZ9477(簡要)
角色:E2E TC,自動修正网络延遲
特性:
- 硬件 PTP 支援:無需软件处理,硬件自動更新 CF
- 端口配置:
- Port 1 连接 RPi3(Grandmaster)
- Port 2 连接 AT32F403A(End Slave)
配置方式:
透過交換机管理接口啟用 PTP E2E TC 模式,具體步骤依廠商文件而定。
3.3 End Slave: AT32F403A + DM9058(⭐ 本文重點)
3.3.1 AT32F403A 微控制器
核心規格:
- 处理器:ARM Cortex-M4F @ 200MHz
- Flash:1MB
- RAM:224KB (96KB SRAM + 128KB extension)
- 关键特性:
- 高精度定時器(用于 PTP 时钟)
- 多通道 SPI(与 DM9058 通讯)
- 豐富的 GPIO(控制与中断)
3.3.2 DM9058 网络控制器
核心規格:
- 网络接口:10/100Mbps Ethernet
- 连接方式:SPI 模式(与 AT32F403A 通讯)
- PTP 支援:硬件时间戳記能力(关键功能)
为什麼选择 DM9058?
- 硬件时间戳記:能精確捕捉封包收發时间
- SPI 接口:適合嵌入式系统整合
- 成本效益:相較于內建 Ethernet 的高階 MCU
3.3.3 AT32F403A ↔ DM9058 硬件连接
接脚连接表(⭐ 实际项目配置):
| AT32F403A Pin | 功能 | DM9058 Pin | 说明 |
|---|---|---|---|
| PA5 | SPI1_SCK | SCK | SPI 时钟(25 MHz,可配置) |
| PA6 | SPI1_MISO | MISO | 主机輸入(Master In Slave Out) |
| PA7 | SPI1_MOSI | MOSI | 主机输出(Master Out Slave In) |
| PA15 | SPI1_CS | CS | 片選(GPIO 控制,低電位有效) |
| PC7 | GPIO EXINT7 | INT | 外部中断 7(下降沿触发) |
| GND | Ground | GND | 共地 |
| 3.3V | Power | VCC | 電源供應 |
硬件架构示意图:

图说明:
- 藍色区域:AT32F403A 微控制器内部模块
- CPU Core:32-bit RISC 处理器
- Memory:1MB Flash + 224KB RAM
- SPI1 Master(黃色):25 MHz SPI 接口,连接 DM9058
- GPIO Control Pins:中断控制(PC7)
- UART:除错输出
- 米色区域:DM9051 网络晶片功能模块
- SPI Slave:接收 AT32F403A 指令
- Interrupt Ctrl:封包事件通知
- Timestamp Engine(紅色):硬件 PTP 时间戳記
- MAC/PHY Layer:网络协议处理
- RJ45:实体网络接口
- 綠色区域:网络连接
- Ethernet Cable 连接到 KSZ9477 Transparent Clock
- 连接关系:
- SPI 双向通讯(MOSI/MISO/SCK/CS)
- INT 中断信号(PC7,下降沿触发)
4. 软件架构
4.1 AT32F403A PTP Daemon 软件分层
本项目採用分层架构設計,从應用层到硬件层清晰分離,各层透過定義良好的接口進行通讯。
图说:
- 綠色(應用层):系统初始化与主控邏輯
- 藍色(PTP 协议层):IEEE 1588 协议实作核心
- 橙色(网络层):lwIP TCP/IP 協議棧整合
- 粉色(驱动层):DM9058 硬件驱动与 PTP 功能
- 紫色(HAL 层):AT32F403A 硬件抽象
- 灰色(硬件层):实体硬件元件
4.2 关键模块概略说明
本章節僅提供概略导读:先告訴你「每一层主要看哪些档案」,以及遇到问题時该从哪裡往下追。
| 层次 | 代表模块/档案 | 主要责任 |
|---|---|---|
| 應用层 | utilities/sc0101_ptp_daemon/src/main.c | 系统初始化、主循环排程、PTP daemon 啟停(等待网络就緒后初始化) |
| PTP 协议层(ptpd) | middlewares/3rd_party/ptpd-2.0.0/src/ptpd.cprotocol.cdep/servo.cbmc.c | 协议状态机、PTP 消息处理、Clock Servo 校時(PI)、BMC 選主 |
| 网络层(lwIP 整合) | middlewares/3rd_party/ptpd-2.0.0/src/dep/net.cutilities/dm9058_u2510_if/ethif.c | UDP 319/320 收發、把硬件时间戳透過 pbuf 傳遞到协议层 |
| 驱动层(DM9058) | utilities/dm9058_edriver_v1.6.1a/core/dm9058_beta.c.../dm9058_ptp.cutilities/dm9058_u2510_if/.../devif_ptp.c | DM9058 初始化、PTP 时钟(get/set/adjfreq)、TX/RX 硬件时间戳擷取与封包關聯 |
| HAL/硬件层 | utilities/dm9058_edriver_v1.6.1a/hal/*libraries/drivers/* | SPI/DMA、EXINT 中断、时钟/定時器等底层硬件抽象 |
主循环的概念:
- 先把网络封包(尤其 PTP Event 封包)盡快收進來,再跑 PTP daemon 的状态机与周期处理。
- 因此你会看到
lwip_rx_loop_handler()、ptp_daemon_state_machine()、lwip_periodic_handle()这類呼叫在主循环中反覆出現。
除错建議(从上往下追):
- 抓不到 PTP 封包:先看
ethif.c/devif_ptp.c(是否收得到、是否判定为 PTP) - 收得到但协议沒反應:看
dep/net.c(UDP 319/320 是否 bind、是否把 pbuf 丟給 ptpd) - 有進 ptpd 但时间不準:看
dep/servo.c与dm9058_ptp.c(时间戳是否正確、校時接口是否生效)
4.3 关键接口与资料流
4.3.1 系统时间接口(PTP Servo ↔ DM9058 PTP)
servo.c dm9058_ptp.c
──────── ────────────
getTime() ──────────────> dm9058_ptptime_gettime()
setTime() ──────────────> dm9058_ptptime_settime()
updateTime() ──────────────> dm9058_ptptime_updateoffset()
adjFreq() ──────────────> v51_ptp_time_adj_freq()
4.3.2 封包与时间戳的最小理解
- RX(接收):DM9058 收到封包並產生硬件时间戳 → 驱动把时间戳寫入
pbuf->time_sec/nsec→dep/net.c把它交給 ptpd 协议处理(handle*())。 - TX(發送):ptpd 組好 PTP Event 封包(Sync/Delay_Req)→ 驱动送出並讀回 TX 时间戳 → 必要時把时间戳回填/關聯到该封包。
想追完整 RX/TX 呼叫鏈時,再回頭看
devif_ptp.c(封包識別/时间戳關聯)与dm9058_ptp.c(PTP clock + timestamp)。
4.4 项目目录结构
at32f403a_dm9051a_ptp_daemon_trace/
├── project/ # 范例工程(BSP/board 支援檔)
├── utilities/ # 應用程序 + DM9058 驱动(主要工作區)
│ ├── sc0101_ptp_daemon/ # PTP 主程序(main / 网络啟動流程)
│ │ └── mdk_v5/ # Keil MDK 项目檔(建置入口:*.uvprojx)
│ ├── dm9058_edriver_v1.6.1a/ # DM9058 驱动(含 PTP clock + timestamp)
│ └── dm9058_u2510_if/ # lwIP netif 与 PTP 封包關聯
├── middlewares/ # lwIP + ptpd(协议核心)
│ ├── lwip_2.1.2/
│ └── 3rd_party/ptpd-2.0.0/
├── libraries/ # AT32 官方 HAL/SDK
└── docs/ # 文件与图表
快速定位(建議只記这幾个):
- PTP 主程序入口:
utilities/sc0101_ptp_daemon/src/main.c - PTP 协议核心(ptpd):
middlewares/3rd_party/ptpd-2.0.0/src/ - DM9058 PTP(时钟+时间戳):
utilities/dm9058_edriver_v1.6.1a/dm9058_edriver_extend/dm9058_ptp.c - lwIP netif 与 PTP 封包關聯:
utilities/dm9058_u2510_if/ethif.c、utilities/dm9058_u2510_if/dm9058_edriver_extend/devif_ptp.c
5. AT32F403A 环境建置
⭐ 本章節为文章重點,提供完整的环境建置流程与程序码范例。
5.1 开发环境准备
5.1.1 必要工具
1. IDE 与编译器
- Keil MDK-ARM v5.x(推薦)或
2. 調試与烧录工具
- AT-Link-EZ CMSIS-DAP(推薦)或 J-Link
3. 软件套件
- AT32F403A Firmware Library(从官方下載)
5.1.2 硬件准备
清單:
- AT32F403A 开发板
- DM9058 SPI 模块
- 杜邦線(连接 SPI 与中断腳位)
- Ethernet 网络線(连接到 KSZ9477 TC)
- UART 轉 USB 模块(用于除错输出)
- AT-Link-EZ 除错器(CMSIS-DAP)
5.2 硬件连接步骤
步骤 1:SPI 接線
| 从 AT32F403A | 到 DM9058 | 注意事項 |
|---|---|---|
| PA5 | SCK | 时钟線,需短且直 |
| PA6 | MISO | 主机輸入 |
| PA7 | MOSI | 主机输出 |
| PA15 | CS | 片選,低電位有效 |
步骤 2:中断接線
| 从 AT32F403A | 到 DM9058 | 说明 |
|---|---|---|
| PC7 | INT | 下降沿触发,需上拉 |
步骤 3:電源与地線
| 从 AT32F403A | 到 DM9058 |
|---|---|
| 3.3V | VCC |
| GND | GND |
⚠️ 重要:確保所有连接牢固,特別是 SPI 时钟線和地線。不良连接会導致 SPI 通讯錯誤!
5.3 韌體编译与烧录
5.3.1 使用 Keil MDK 编译
步骤 1:開啟项目
開啟档案:utilities/sc0101_ptp_daemon/mdk_v5/ptp_daemon_f403a.uvprojx
步骤 2:配置 Target
- 確認 Device:
AT32F403ACGT7 - Debug: 选择
CMSIS-DAP Debugger - JTAG/SW Adapter:
AT-Link-EZ CMSIS-DAP - Port:
SW,Max Clock:1MHz
步骤 3:编译
選單 → Project → Build Target (F7)
步骤 4:烧录
選單 → Flash → Download (F8)
5.4 AT32F403A 初始化配置
本项目的初始化分为四个主要部分:系统时钟、SPI 通讯、外部中断、DM9058 驱动。以下以文字说明配置要點,完整程序码請参考 GitHub 项目。
5.4.1 系统时钟配置(200MHz)
配置档案:utilities/sc0101_ptp_daemon/src/at32f403a_407_clock.c
时钟来源与 PLL 配置:
- 外部振盪器(HSE):8 MHz
- PLL 倍頻:× 50
- PLL 分頻:÷ 2
- 系统时钟(SYSCLK):200 MHz
匯流排时钟分配:
| 匯流排 | 分頻器 | 頻率 | 用途 |
|---|---|---|---|
| AHB | ÷1 | 200 MHz | CPU 核心 |
| APB1 | ÷2 | 100 MHz | 低速周邊 |
| APB2 | ÷2 | 100 MHz | 高速周邊(SPI1) |
时钟樹:
HSE (8MHz) → PLL (*50÷2) → SYSCLK (200MHz)
↓
┌───────────────────┼───────────────────┐
↓ ↓ ↓
AHB (÷1, 200MHz) APB1 (÷2, 100MHz) APB2 (÷2, 100MHz)
↓ ↓ ↓
Core 低速周邊 SPI1 (25MHz)
关键配置函式:
crm_pll_config(CRM_PLL_SOURCE_HEXT_DIV, CRM_PLL_MULT_50, CRM_PLL_OUTPUT_RANGE_GT72MHZ)- 配置 PLL 倍頻 ×50crm_ahb_div_set(CRM_AHB_DIV_1)- 设定 AHB 分頻器 ÷1crm_apb1_div_set(CRM_APB1_DIV_2)- 设定 APB1 分頻器 ÷2crm_apb2_div_set(CRM_APB2_DIV_2)- 设定 APB2 分頻器 ÷2(影響 SPI 时钟)
5.4.2 SPI1 配置(25 MHz)
配置档案:utilities/dm9058_edriver_v1.6.1a/hal/SPI1/at32f403a_spi1_dma.c
SPI 参数配置:
| 参数 | 设定值 | 说明 |
|---|---|---|
| 模式 | Master | AT32F403A 为主机 |
| 时钟速度 | 25 MHz | APB2 (100MHz) ÷ 4 |
| 數據寬度 | 8-bit | 單字節傳輸 |
| 时钟極性(CPOL) | Low (0) | 空閒時时钟为低電平 |
| 时钟相位(CPHA) | 1 Edge (0) | 第一个邊沿採樣 |
| CS 控制 | 软件模式 | GPIO PA15 控制 |
| 傳輸方向 | 全雙工 | 同時收發 |
GPIO 配置:
- PA5:SPI1_SCK(複用功能)
- PA6:SPI1_MISO(復用功能)
- PA7:SPI1_MOSI(複用功能)
- PA15:CS 片選(GPIO 输出,需釋放 JTAG 功能)
特殊配置:
// AT32F403A 需釋放 PA15 的 JTAG 功能
gpio_pin_remap_config(SWJTAG_GMUX_010, TRUE);
SPI 通讯流程:
- CS 拉低(選中 DM9058)
- 發送命令字節(讀/寫 + 暫存器位址)
- 發送/接收數據字節
- CS 拉高(結束通讯)
5.4.3 外部中断配置(EXINT7, PC7)
配置档案:at32f403a_int7.c
中断参数配置:
| 参数 | 设定值 | 说明 |
|---|---|---|
| GPIO 腳位 | PC7 | 连接 DM9058 INT 信号 |
| 中断線 | EXINT_LINE_7 | 外部中断線 7 |
| 触发方式 | 下降沿 | DM9058 INT 为低電位有效 |
| GPIO 模式 | 輸入 + 上拉 | 空閒時保持高電平 |
| 中断向量 | EXINT9_5_IRQn | EXINT5-9 共用 |
| 優先级組 | NVIC_PRIORITY_GROUP_4 | 4 位 preemption priority |
中断处理流程:
- 檢查 EXINT7 旗標
- 设定
dm9058_interrupt_event = 1(通知主循环) - 清除中断旗標
- 返回
中断事件:
- 封包接收完成
- 封包發送完成
- PHY 链接状态變化
5.4.4 DM9058 初始化流程
配置档案:dm9058_beta.c
初始化步骤:
-
晶片 ID 验证
- 讀取暫存器
DM9058_PIDL - 預期值:0x58(DM9058)
- 完整 ID:0x9058
- 讀取暫存器
-
MAC 位址配置
- 寫入 6 bytes 到 PAR 暫存器(0x10-0x15)
- 范例 MAC:00:60:6E:E2:7C:BB
-
PTP 功能啟用(依晶片版本而定)
- 硬件时间戳記功能
- 参考 DM9058 Datasheet
初始化成功標誌:
[DRIVER INT mode] DM9058 found: 9058
PTP Transport: UDP over IPv4
LWIP: Network interface added successfully
LWIP: Getting MAC address from DM9058...
reg mac 00 60 6e e2 87 6b
LWIP: Network interface MAC address updated
LWIP: Setting default network interface...
💡 技巧:完整的初始化程序码(含錯誤处理、DMA 配置等)約 500 行,建議直接参考项目原始码。本節僅列出关键配置参数,幫助理解整體架构。
5.5 PTP Daemon 配置与啟動
5.5.1 PTP 配置参数
PTP 协议参数來自 PTPd 的常數与 ptpClock->defaultDS,于 PTPd 初始化時由 initData() 寫入。
实际配置来源:
| 参数概念 | 实际位置 | 说明 |
|---|---|---|
| One-Step / Two-Step | constants.h → DEFAULT_TWO_STEP_FLAG | FALSE = One-Step(时间戳直接嵌入 Sync) |
| 僅 Slave 模式 | constants.h → SLAVE_ONLY | TRUE = 僅从时钟,不參与 BMC 競選 Master |
| 延遲机制 | constants.h → DEFAULT_DELAY_MECHANISM | E2E |
| Sync 間隔 | constants.h → DEFAULT_SYNC_INTERVAL | 0 → 2^0 = 1 秒 |
| twoStepFlag 寫入 | bmc.c → initData() | ptpClock->defaultDS.twoStepFlag = DEFAULT_TWO_STEP_FLAG; |
| DefaultDS 结构 | datatypes.h → DefaultDS | 含 twoStepFlag、slaveOnly、domainNumber 等 |
constants.h 摘錄(middlewares/3rd_party/ptpd-2.0.0/src/constants.h):
#define DEFAULT_TWO_STEP_FLAG FALSE /* One-Step:僅 SYNC,时间戳在 Sync 內 */
#define SLAVE_ONLY TRUE /* 僅 Slave 模式 */
#define DEFAULT_DELAY_MECHANISM E2E
#define DEFAULT_SYNC_INTERVAL 0 /* 2^0 = 1 秒 */
bmc.c 摘錄(initData() 內):
ptpClock->defaultDS.twoStepFlag = DEFAULT_TWO_STEP_FLAG;
5.5.2 主程序流程
main.c 主要流程(参考 utilities/sc0101_ptp_daemon/src/main.c):
int main(void)
{
/* 1. 系统初始化 */
system_clock_config(); // 200MHz 时钟
at32_board_init();
uart_print_init(115200);
print_version_info();
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
/* 2. 网络驱动初始化 */
emac_tmr_init(); // TMR6 用于 local_time 更新
tcpip_stack_init(); // lwIP 协议棧
printf("[MAIN] Waiting for network connection...\r\n");
/* 3. 主循环 */
for (;;)
{
lwip_rx_loop_handler(); // 网络封包接收
ptp_daemon_state_machine(); // PTP 状态机(DHCP 后啟動)
lwip_periodic_handle(local_time); /* lwIP timeout handle - 包含 PTP 协议計時器 */
}
}
PTP Daemon 状态机(簡化版):
/* 状态:WAITING_NETWORK → INITIALIZING → RUNNING */
static void ptp_daemon_state_machine(void)
{
switch (ptp_daemon_state)
{
case PTP_STATE_WAITING_NETWORK:
if (network_dhcp_is_bound()) {
ptp_daemon_state = PTP_STATE_INITIALIZING;
}
break;
case PTP_STATE_INITIALIZING:
if (PTPd_Init() == 0) {
ptp_daemon_state = PTP_STATE_RUNNING;
ptp_rtc_sync_enable(true);
}
break;
case PTP_STATE_RUNNING:
ptpd_Periodic_Handle(local_time);
break;
}
}
完整代码:請参考
utilities/sc0101_ptp_daemon/src/main.c,包含錯誤处理与重試机制。
5.6 编译与烧录验证
5.6.1 编译输出
正常编译后,输出應類似:
Build target 'AT32F403A_PTP'
compiling main.c...
compiling dm9058_beta.c...
linking...
Program Size: Code=124568 RO-data=8756 RW-data=2048 ZI-data=51200
".\Objects\ptp_daemon.axf" - 0 Error(s), 0 Warning(s).
5.6.2 首次烧录验证
步骤 1:连接 UART(115200 baud, 8N1)
步骤 2:烧录韌體
步骤 3:觀察序列埠输出
========================================
AT32F403A DM9058 PTP Daemon
========================================
Version: 2.0.0
Build Date: Jan 23 2026
Build Time: 13:48:28
Git Commit: 0dda3de35c76
Git Date: Fri Jan 23 2026 13:40:33 GMT+08:00 (CST)
========================================
[INIT] Configuring TMR6 for local_time updates
LWIP: Initializing lwIP stack...
LWIP: DHCP mode - setting IP addresses to 0.0.0.0
[AT32F403a]
tcpip_stack_init
[SPI Instance]
at32f403a_spi1_dma.c
AT32F403A ETHERNET SPI1 DMA
[SPI Pins]
sck/mosi/miso/ pa5/pa7/pa6, cs/ pa15
[DRIVER init] AT32F403A INT Running...
[DRIVER init] AT32F403A INTERRUPT GPIO
[DRIVER init] int/ pc7
[hal] at32f403a_spi1 'spi' Running 25Mhz...
[core] dm9058_constants 'INT' Running...
(apb2_freq) 100Mhz, set SPI CLK 25Mhz
[DRIVER INT mode] CLK:200000000(sclk_freq) 200000000 100000000(apb2_freq) 100000000(apb1_freq)
[DRIVER INT mode] SPI CLK use apb2_freq 100Mhz, set to 25Mhz
[DRIVER INT mode] DM9058 found: 9058
PTP Transport: UDP over IPv4
****** dm9058 Rate: +0x00000000 (+0) - Clock adjusted to be faster
LWIP: Network interface added successfully
LWIP: Getting MAC address from DM9058...
reg mac 00 60 6e e2 87 6b
LWIP: Network interface MAC address updated
LWIP: Setting default network interface...
LWIP: Bringing up network interface...
LWIP: Setting link callback...
LWIP: Checking initial link status...
LWIP: Link is UP - network ready
LWIP: Network stack initialization completed
[INIT] System initialization completed
[INIT] Waiting for network connection...
DHCP: No DHCP client data available
Link: State changed from UNKNOWN to UP
如果看到以上输出,恭喜!AT32F403A + DM9058 硬件平台已准备就緒。
6. 本篇成果(平台 bring-up 成功)
6.1 硬件实体設置图
以下为本项目实际使用的硬件平台实体設置图,展示了完整的 PTP 时间同步测试环境:

硬件配置说明:
本實驗平台主要由三个核心元件組成,透過乙太网络線和信号跳線连接,構成一个完整的 PTP 时间同步验证系统:
-
Raspberry Pi 3 + DM9058(左上角)
- 作为 PTP Grandmaster (GM),提供標準时间源
- Raspberry Pi 3 开发板裝在透明塑膠外殼中
- 多條彩色跳線从 SPI 连接到 DM9058,用于控制信号、中断
- 整合 DM9058 乙太网络控制器模块
- 透過藍色乙太网络線连接到 KSZ9477 交換器
- USB 線用于供電
-
Microchip KSZ9477 乙太网络交換器(右側中央)
- 作为 E2E Transparent Clock (TC),自動修正网络延遲
- 大型綠色 PCB 評估板,標示为 “Microchip KSZ9477”
- 擁有多个乙太网络埠,连接不同的 PTP 節點
- 从 Raspberry Pi 過來的藍色乙太网络線连接到其中一个埠
- 另一條灰色乙太网络線连接到 AT32F403A 裝置
- 硬件 PTP 支援,無需软件处理即可自動更新 Correction Field (CF)
-
AT32F403A + DM9058(左下角)
- 作为 PTP End Slave (ES),本文实作重點
- 白色开发板,標示为 “AT32F403A”
- 綠色 PCB 小板(帶状态 LED)插在 AT32F403A 板上为 DM9058
- 从小板引出的灰色乙太网络線连接到 Microchip KSZ9477 交換器
- 多條彩色跳線 SPI 连接到中繼小板DM9058,用于控制信号、中断
- USB 線用于供電、程序烧录或序列埠通信
系统拓扑(Topology)说明:
- Microchip KSZ9477 充當网络骨幹,连接 Raspberry Pi 和 AT32F403A 这兩个 PTP 節點
- Raspberry Pi 3 + DM9058 扮演 PTP 主时钟 (Master),提供標準时间
- AT32F403A + DM9058 扮演从时钟 (Slave),同步到 Master 的时间
- 彩色跳線连接可能用于提供額外的同步信号(如 PPS, Pulse Per Second),或用于監控关键状态,以精確測量 PTP 的同步性能和延遲
此設置旨在验证 AT32F403A 和 Raspberry Pi 搭配 DM9058 乙太网络模块,在通過 Microchip KSZ9477 交換机连接的网络环境下,实现 PTP 精確时间同步的功能及效能。
结语
上篇的目標,是把「AT32F403A + DM9058 + lwIP + PTP daemon」这條鏈路先跑起來、再跑穩:
- 硬件连接、SPI/中断、驱动初始化
- 网络层先就緒(link/DHCP 或靜態 IP),再啟動 PTP
- 你能在 UART 上清楚看到:初始化成功、状态机前進,以及周期性输出 offset / mean path delay
到这一步,已經完成工程現場最困難的部份:把平台 bring-up 變成可運作的流程。
中篇与下篇预告
中篇预告
在中篇中,我們將深入探討:
-
PTP 系统运行成果展示:
- 网络层初始化成功验证
- PTP daemon 状态机轉換过程
- 周期性 Offset 与 Mean Path Delay 输出分析
-
时间同步精度验证:
- 如何量测 PTP 同步精度
- Offset 收敛过程分析
- Clock Servo 控制迴路调校
-
常见问题与除错技巧:
- 网络连线问题排查
- PTP 封包收發除错
- 时间戳記準確性验证
-
系统整合测试:
- 多个 End Slave 同時运行的验证
- Transparent Clock CF 修正机制验证
- 長时间稳定性测试
中篇將幫助您:
- 理解 PTP 系统的运行机制
- 掌握时间同步精度的量测方法
- 學会系统除错与優化技巧
下篇预告
在下篇中,我們將深入探討:
-
系统整合与测试:
- 完整的测试前置 Checklist
- 系统啟動順序与验证流程
- Wireshark 抓包技巧与必要欄位
-
兩點抓包验证 TC CorrectionField(⭐ 下篇核心):
- 端點兩點抓包方案(GM 端 + ES 端)
- 封包配對与 ΔCF 計算
- CorrectionField 單位轉換与統計分析
-
工程实作導向的验证方法:
- 可重現、可量化、可除错的测试流程
- 完整的测试結果報告模板
- 常见问题排查 SOP
下篇將幫助您:
- 使用兩點抓包證明 TC 的 CorrectionField 累加机制
- 形成工程現場可直接照做的测试 SOP
- 掌握故障排除手冊与验证方法
下篇定位:工程实作導向(可重現、可量化、可除错),使用「兩點抓包」證明
correctionField在路徑中被累加。
专有名词对照表(Terminology)
| 中文 | 英文 | 縮寫 | 说明 |
|---|---|---|---|
| 拓扑 | Topology | - | 网络設備的连接结构 |
| 精確时间协议 | Precision Time Protocol | PTP | IEEE 1588 標準 |
| 透明时钟 | Transparent Clock | TC | 修正网络延遲的中間設備 |
| 修正欄位 | Correction Field | CF | PTP 消息中累加延遲的欄位 |
| 駐留时间 | Residence Time | - | 消息在 TC 内部的停留时间 |
| 主时钟 | Grandmaster | GM | 提供时间源的 PTP Master |
| 从时钟 | Slave Clock | - | 同步到 Master 的設備 |
| 时间戳記 | Timestamp | - | 精確的时间記錄 |
| 偏移量 | Offset | - | Slave 与 Master 的时间差 |
| 單步模式 | One-Step | - | 时间戳記直接嵌入 Sync 消息 |
| 端對端 | End-to-End | E2E | 延遲測量机制 |
参考资料
- Artery Technology 原始码套件(移植来源):
SC0101_AT32F407_437_PTP_Daemon_V2.0.0.zip(本项目以其 PTP daemon 整合架构为基础,移植到 AT32F403A 平台) - IEEE 1588-2008: IEEE Standard for a Precision Clock Synchronization Protocol for Networked Measurement and Control Systems
- AT32F403A Datasheet: Artery Technology AT32F403A/407 Series MCU Datasheet
- DM9058 Datasheet: Davicom DM9058 10/100Mbps Ethernet Controller
- KSZ9477 User Guide: Microchip KSZ9477 7-Port Gigabit Ethernet Switch with PTP
- LinuxPTP Documentation: http://linuxptp.sourceforge.net/
- lwIP Documentation: https://www.nongnu.org/lwip/
附录:原始码链接
- 程序码来源:Artery Technology
SC0101_AT32F407_437_PTP_Daemon_V2.0.0.zip(移植基础) - DM9058 驱动:
dm9058_edriver_v1.6.1a
前一篇: AT32F403A + DM9058 实现高精度 PTP 时间同步:从硬件到软件的完整实作指南
下一篇: AT32F403A + DM9058 实现高精度 PTP 时间同步(中篇):成果展示与验证
2636

被折叠的 条评论
为什么被折叠?



