摘要:眼見為憑!用示波器般的精度見證 PTP 的物理脈動
上一回,我們解鎖了 One-Step 模式,看著 Wireshark 裡的封包像上了發條一樣精准,是不是覺得還是有點“虛”?畢竟那些都是網線裡的資料。
今天,我們要玩點硬的! (Getting Physical)
我們將直接調用Davicom(聯傑)的 DM9058 GPIO 介面,讓這顆晶片把它的“心跳”直接輸出成電子信號。我們會配置一台 Pi 5 做為信號產生器 (Generator),每秒準時打出一個脈衝;另一台 Pi 5 做為捕捉器 (Capture),去抓這個脈衝到底准不准。
這不僅僅是測試,這是對 PTP 物理極限的一次 “探底”行動!
一、 戰地配置 (The Rig)
我們要搭建一個最簡單、但也最殘酷的測試環境:**直球對決**。
Output (發送端): Pi 5 + DM9058。任務:利用 `perout` 功能,在每個“正秒”瞬間,從 GPIO 引腳射出一道信號。
Input (接收端):Pi 5 + DM9058。任務:利用 `extts` (External Timestamp) 功能,一旦偵測到信號,立即記錄當下的納秒級時間。
連接:一條跳線 (Jumper Wire)。連接 Output 的發送腳與 Input 的接收腳。
連線示意圖:
DM9058 透過 Ethernet 對接跑 PTP4L 同步。
左側 (GPIO 1) 負責開火,右側 (GPIO 2) 負責中彈紀錄。

二、 改裝武器 (Modding the Code)
官方的測試程式 `perout.c` 雖然好用,但我們需要它更“聽話”一點。原本的程式是隨機時間開始輸出,我們要把它改成 “絕對正秒”輸出,這樣我們才能驗證它到底准不准。
目標檔案:`dm9058_linux_driver/test/perout.c`
修改大法:
發射次數修改 , 10 -> 10000,
#define DURATION 10000 // Duration to observe the perout behavior
我們要強制設零納秒 (`nsec = 0`),讓它精確地在 `.000000000` 發射!
// ... 前略 ...
// 設定從現在起 2 秒後開始
struct timespec ts;
clockid_t clkid = get_clockid(fd);
// ... 省略中間 boilerplate ...
if (clock_gettime(clkid, &ts)) {
perror("clock_gettime");
return -1;
}
perout.index = 1;
perout.start.sec = ts.tv_sec + 2; // 兩秒後開跑
// [重點修改] 強制歸零!我們要的是絕對正秒!
perout.start.nsec = 0;
perout.period.sec = 1; // 每秒打一次
perout.period.nsec = 0;
// ... 後略 ...
改完之後,在 `test/` 目錄下執行 `make`,編譯出我們專屬的測試工具。
dm9058_linux_driver/test$ make
gcc -Wall -Wextra -g -o perout perout.c ... # 編譯成功!
另外一台 Pi, 接收信號時, 印出 timestamp , 修改接收次數:
目標檔案:`dm9058_linux_driver/test/extts.c`
int main(int argc, char *argv[])
{
struct ptp_extts_event event;
int n_events = 7200; // 設定要讀取的事件數量
...
}
這裡我們該 7200 次, 所以估計打 2 個小時
[!NOTE] 重要
測試完成後, Ctrl-C 跳出, 跑 `sudo ./stop` 停止 GPIO 輸出.
三、 開火!(Fire in the Hole)
一切就緒,見證奇跡的時刻到了。
1. Input 端 (接收者) 先跑起來等待:
它會像個狙擊手一樣,靜靜等待 GPIO 信號的到來。
2. Output 端 (發送者) 執行改裝版 `perout`:
`./perout` 下去,它就會開始規律地在每一秒的整點發送信號。
我們預期透過 PTP 同步的兩台機器,能夠達成完美的 1.000000000 秒 間隔。任何一點偏差,就是我們常說的 Jitter (抖動)。
四、 真相解密:納秒級的動態平衡 (The Truth)
我們用這個 setup 跑了兩組極端測試,結果令人頭皮發麻。
1. 馬拉松測試 (2小時 Log 分析)
- 樣本數: 7200 (約 2 小時)
--- 統計結果 (Statistics) ---
樣本數 (Count): 7199
平均值 (Mean): 0.999990179 s
標準差 (Std Dev): 0.000000094 s (94 ns) <-- 看這個!
最小值 (Min): 0.999989986 s
最大值 (Max): 0.999990225 s
2. 閃電戰測試 (1分鐘 Log 分析)
- 交換 GPIO 輸出/輸入方向
- 樣本數: 60 (約 1 分鐘)
--- 統計結果 (Statistics) ---
樣本數 (Count): 59
平均值 (Mean): 1.000000141 s
標準差 (Std Dev): 0.000000117 s (117 ns) <-- 還有這個!
深入解讀:為什麼不是完美的“1秒”?
這就是最有趣的地方!細心的你可能發現了:
* 測試一平均值:`0.999990179 s` (快了約 9.8 微秒)
* 測試二平均值:`1.000000141 s` (慢了約 141 納秒)
“這是不是代表不准?”
錯!這恰恰證明了它“活著”!
這就是 1588 PTP 伺服回路 (Servo Loop) 正在工作的聲音。
兩台 Pi 5 上的石英震盪器 (Crystal Oscillator) 受到溫度、電壓的細微影響,頻率無時無刻不在漂移。PTP 就像一個神級賽車手,不斷地微調方向盤:
- 發現 Slave 變慢了?加速追趕!(週期變短)
- 發現 Slave 跑快了?減速等待!(週期變長)
標準差 (Std Dev) 僅約 100 納秒,意味著這個“微調”的過程極其平滑且精確。系統不是死板地固定在某個錯誤值,而是動態地、有機地鎖定在完美的時間軸上。
五、 總結:工業級的浪漫
透過 Davicom(聯傑)的 DM9058,我們把 Raspberry Pi 4/5 從一個“玩具”變成了一台工業級精密儀器。
當你看到示波器(或 log)上那 100 ns 等級的抖動資料時,你看到的不再是冰冷的電子信號,而是兩顆晶片跨越網線,在納秒尺度上進行的一場完美協奏曲。
這,就是我們追求的 One-Step 終極同步。
Tag: PTP, IEEE 1588v2, DM9058, RaspberryPi5, PPS
第一篇:玩家篇 樹莓派 Pi 5 核心效能結合 DM9058 1588 擴展 (一):高速 SPI 介面應用教學
上一篇:玩家篇 樹莓派 Pi 5 核心效能結合 DM9058 1588 擴展 (二):解鎖 One-Step 納秒級同步













