# CLAUDE.md — Blanton TTL Script ## 專案簡介 Blanton(Project Helios)交換器平台的系統層可靠性測試自動化腳本組。 Windows 端用 **Tera Term TTL macro** 透過 COM console 驅動 DUT 的 SONiC, A / B / C 三支腳本分別跑「基線 → 壓力 soak → 收工判定」,全程存 log。 DUT 端的取數能力由一組 **bash 工具庫** 提供(CB FPGA `pcimem` → FPGA I2C/VI2C → VRM / 溫感 / LTC2980)。 完整架構見 [ARCHITECTURE.md](ARCHITECTURE.md)。 **目前狀態(2026-08-24)**:Script A 為 **V1.0.6**(A 集中記錄 A/B/C 三支的變更)。涵蓋 PCIe AER / DDR EDAC / PMON+TPM / 電壓 margin(9 顆 LTC2980)/ SWB loopback 線速流量 / 10G+1G 管理網路 ping / BMC DDR 與 USB / NVMe 健康,壓力層走平台的 `bgctl`。 switch unit 數量由 `config.ttl` 的 `SWB_UNIT0` / `SWB_UNIT1` 宣告。 最後一次發布是 **V1.0.5**;SWB 的 I2C 通道與位址已於 2026-08-19 上機驗證。 交付用 `./publish/publish.sh` 打包。 ## 技術棧 - **Host**:Tera Term 5.x TTL macro(`.ttl`),Windows - **DUT**:SONiC(Debian-based),bash + busybox/mawk,`root@sonic:~#` - **暫存器存取**:`pcimem`(mmap PCI sysfs `resource0` + BAR 相對 offset,一律 32-bit word) - **I2C/PMBus**:CB FPGA F3 I2C master(Ch0~Ch17,base 0x300 stride 0x20)、 CB F3 VI2C proxy → ICB/PDB(Ch0~Ch4,base 0x780)、CPU 原生 bus(`i2cset`/`i2cget`) - **Margin**:LTC2980(= 2 × LTC2977)over PMBus,LINEAR16 - **資料面流量**:`bcmcmd`(Broadcom drivshell)SWB loopback,VLAN 30..137 成對 `cdN`/`cdN+32`, `tx 100 length=512`;判定讀 ASIC `MIB_TPOK`/`MIB_RPOK` 做 per-pair 雙向交叉比對 - **BMC**:host 端 `bmc-manager run ""`,不需對 BMC 開 SSH(繞開其 busybox 工具鏈) - **背景工作**:平台的 `bgctl run/list/stop --all/reset`;長時間 ping 用 `systemd-run --unit=` 掛 transient unit - **管理網路**:iproute2(`ip link set` / `address replace` / `route replace ... metric`)+ `ping -I` - **判定資料源**:PCIe AER sysfs(`aer_dev_*`)、EDAC sysfs(`dimm_{ce,ue}_count`)、SONiC `show platform *` - **無編譯步驟**:TTL 與 bash 都直譯執行 ## 常用指令 ```bash # ── 部署 bash 工具庫到 DUT ────────────────────────── scp -r src/Script_ABC_Blanton/Blanton_Script admin@:~/ # ── DUT 上載入工具(Script A 也是做這六件事)───────── source ~/Blanton_Script/blanton_fpga_pcimem.sh # ← 會自己印出偵測到的 CB FPGA BDF source ~/Blanton_Script/blanton_cb_i2c.sh source ~/Blanton_Script/blanton_icb_vi2c.sh source ~/Blanton_Script/blanton_pwr_data.sh source ~/Blanton_Script/blanton_traffic_linespeed.sh source ~/Blanton_Script/LTC2980_Margin_Script/margin.sh # ── FPGA BDF:自動偵測,不用改檔;必要時手動釘 ─────── fpga_rescan # 換 DUT / 重新列舉後重測 FPGA_BDF=0000:05:00 fpga_rescan # 偵測到多顆或選錯時,指定 domain:bus:dev(不含 .fn) echo $FPGA_BDF_ACTIVE # 目前生效的 BDF # ── 煙霧測試 ──────────────────────────────────────── cb_fpga 0 0xD90 # RST_CAUSE_REG,讀得到 = BAR 通了 cb_i2c_init 11 && cb_i2c_scan 11 # Ch11 風扇控制器,應看到 0x20 vi2c_scan_all # ICB/PDB 五個通道 temp_all # CB + ICB 溫感 pwr_data # SWB VRM 全軌 margin_init Blanton_CB_CONN13 && margin_status # ── SWB loopback 流量(bcmcmd,unit 0/1)───────────── # 不帶 -u 就是預設 TL_UNITS="0 1",兩塊 switch board 都做(TTL 三支腳本即如此) blanton_traffic_linespeed ps # 對照線的 link/speed blanton_traffic_linespeed init # VLAN 30..137,cdN <-> cdN+32 blanton_traffic_linespeed clear # clear c blanton_traffic_linespeed start -tx 100 -length 512 blanton_traffic_linespeed stop # 移除 VLAN 成員(--destroy 連 VLAN 一起砍) blanton_traffic_linespeed report # per-pair TX/RX + PASS/FAIL(exit 2 = 有 FAIL/NA) blanton_traffic_linespeed run # ps → init → clear → start → report 一條龍 blanton_traffic_linespeed init -u 0 # 只做單一 unit 時才需要 -u blanton_traffic_linespeed init -n # -n dry-run:只印要下的 bcmcmd,不碰 DUT blanton_traffic_linespeed report -f # 離線重解一份存下來的 console log # 離線版報表(開發機上跑,選項更多) python3 tools/bcm_mibpair_report_V1.1.0.py -a # ── 管理網路 ping 監控(需先 chmod +x!)────────────── chmod +x ~/Blanton_Script/*.sh # 佈署後必做一次 ~/Blanton_Script/mgmt_ping_monitor.sh fg # 前景試一輪(約 30 秒),確認 IP/對端/網卡 ~/Blanton_Script/mgmt_ping_monitor.sh start # 背景,log/mgmt_ping.log(start 會先清空) ~/Blanton_Script/mgmt_ping_monitor.sh status ~/Blanton_Script/mgmt_ping_monitor.sh stop ~/Blanton_Script/mgmt_ping_monitor.sh summary # 只看每段的 RESULT 行 # ⚠️ tail 子命令是 tail -f,會卡住不返回;TTL 裡要倒 log 請用 cat # ⚠️ bmc_monitor.sh / bmc_monitor_ddr.sh 已停用(改走 bgctl + bmc-manager),檔案仍在 # ── 背景壓力(平台工具)────────────────────────────── bgctl run /usr/sbin/memtester 1G 100 bgctl list bgctl stop --all ; bgctl reset --yes # ── 各工具的 help ─────────────────────────────────── blanton_fpga_help ; blanton_cb_i2c_help ; vi2c_help temp_sensor_help ; pwr_data_help ; blanton_traffic_linespeed_help ``` **打包交付(在開發機上):** ```bash ./publish/publish.sh # 版號讀 Script A 檔頭 → publish/Script_ABC_Blanton_V1.0.3/ ./publish/publish.sh -z # 另出 zip ./publish/publish.sh -n # dry run ``` 要出新版**先改 Script A 檔頭的 `; Version :`**,publish 才會用新版號建資料夾。 **Host 端跑一輪測試:** ``` Tera Term 連 COM port (115200-8-N-1) → Control → Macro → 1_Blanton_Script_A.ttl (基線,跑完出 messagebox) → 手動跑 2_Blanton_Script_B.ttl (壓力 soak,while 1 迴圈,泡到時間到停掉) → 手動跑 3_Blanton_Script_C.ttl (kill + 收工快照 + 判定) → 檢查 Logs\Blanton_Margin_.log ``` ## 開發慣例 - **執行單位**:`src/Script_ABC_Blanton/` 整包給測試員(Tera Term 工作目錄); 其中 `Blanton_Script/` 是 scp 到 DUT `~/` 的單位 - **TTL 分層**:`config.ttl` 放設定 → 三支主腳本編排流程 → `utils/*.ttl` 是可 include 的無狀態片段 (只做 `wait prompt_sonic_root` + `sendln`,不設變數、不 logopen) - **新增取數項目** = 新增一支 `utils/show_xxx.ttl`,再在主腳本 `include`,不要往主腳本塞指令 - **bash 命名**:公開函數 `cb_i2c_* / vi2c_* / temp_* / pwr_* / margin_*`,內部 helper 一律底線開頭 (`_cbi2c_* / _vr / _ts_* / _pwr_*`) - **版本紀錄**:`.sh` 每支檔頭都有 `Version History` 區塊,改動時**在檔頭補一行** (`V1.0.2 YYYY-MM-DD <做了什麼>`),不要只改版號。 TTL 這邊 **2026-08-17 起改為集中制**:`1_Blanton_Script_A.ttl` 的 History 記錄 A/B/C 三支的 所有變更,B 與 C 的檔頭版本區塊已移除。⚠️ 這是待確認的慣例變更 —— 若要回到「每支各自記錄」,B/C 的 History 需要補回去 - **Commit**:Conventional Commits,**英文**。scope 用 `ttl` / `fpga` / `i2c` / `vi2c` / `margin` / `pwr` / `temp` / `docs` - **換行符**:由 `.gitattributes` 管理 —— `*.sh` `*.conf` `*.py` `*.txt` `*.md` 釘 **LF** (要在 SONiC 上跑/被 source),`*.ttl` 維持 **CRLF**(Tera Term 只在 Windows 跑)。 編輯 `.ttl` 時要保留 CRLF,別讓整檔變成 LF 產生假 diff - **打包**:`./publish/publish.sh`,版號**讀 Script A 檔頭**不是參數 —— 先改檔頭再打包 - **Status 表**:`docs/TTL_Script_Blanton_Status_*.xlsx` 是逐項進度的正本(OK / On-Going + Owner), 完成一項就同步更新,別讓文件跟腳本脫節 ## 注意事項 - 🔒 **NDA:本 repo 只推 `nas` + `gitea`,絕不推 GitHub。** `docs/` 內含客戶 FPGA 規格。 - 🔒 **DUT 帳密不進 git**。`1_Blanton_Script_A.ttl` 的 `sendln "YourPaSsWoRd"` 是 placeholder, 實際值放 `secret/config_secret.ttl`(gitignored)。**任何 commit 前先 grep 一次確認沒帶到真密碼。** - ⚠️ **PCIe BDF 是 per-unit 的 —— bash 端已自動化,TTL 端還沒**。 `blanton_fpga_pcimem.sh` V1.5.0(2026-08-17)起 source 時自動偵測(sysfs vendor `0x1590` → `lspci` → `FPGA_BDF_FALLBACK`),**不用再每台改檔**;印一行 `[INFO] CB FPGA BDF = ...`, 可用 `fpga_rescan` 重測、`FPGA_BDF=... fpga_rescan` 手動釘住。 **但 `utils/show_pcie_error_reg_*.ttl` 裡的 7 組 BDF 仍是寫死的**,換 DUT 還是要人工校對 —— 不校就會讀到別的裝置,或整段 `No such file or directory`。 - ⚠️ **AER 判定看差值不看絕對值**:Script A 抓基線、Script C 抓結果,相減才是本輪錯誤。 **Endpoint 與上游 Root Port 兩邊都要讀**,錯誤可能只記在 RP。 - ⚠️ **ICB/PDB 一律走 VI2C(`blanton_icb_vi2c.sh`),不要走 VSPI**:VSPI ~18 ms/reg 會讓 I2C byte 相間隔拉到 ~50 ms,踩中 SMBus 25–35 ms timeout,裝置直接 NACK。實測全掃 9.4 s vs 34.0 s。 - ⚠️ **I2C 讀一律 Repeated START**(不是 STOP + START),否則 PMBus/SMBus 裝置(VRM、EFUSE)不理。 - ⚠️ **`margin_save` / `STORE_USER_ALL` 會永久寫 NVM**,斷電保留 → **測試流程中絕不執行**, 以免覆蓋客戶出廠 config。`margin.sh` 的 auto-enable(`ON_OFF_CONFIG=0x1a`)只改 RAM,斷電復原。 - ⚠️ **改電壓會弄壞 DUT**:套 profile 前確認該軌 OV/UV limit,且 servo DAC 注入電阻有 populate (本板部分 margin 電阻標 PROTO,沒 populate 的軌電壓不會動,不是腳本壞掉)。 - ⚠️ **`ARB_LOST` ≠ 有裝置**:`vi2c_scan` 只看 `RX_ACK`,仲裁失敗會被誤報成裝置存在。 `blanton_pwr_data.sh` 已加 retry + plausibility window,**寧可印 `NA` 也不要印看起來像數據的錯值**。 - ⚠️ **A → B → C 必須同一個 Tera Term session**:B 的背景 job 與 C 的 `kill $(jobs -p)` 綁在同一個 shell;log 也只有 A 會 `logopen`,B/C 是續寫。中途關掉 window 就得手動收程序、log 也斷了。 - ⚠️ **MP29816 的 Vout 解析度不是固定值**,由 `MFR_VOUT_SCALE_LOOP(0x29)` bit[12:10] 決定, `blanton_pwr_data.sh` 執行期從晶片讀;xlsx 上寫的 `/5mV` 與 MP2985B 的 `+49` offset **都是錯的**。 - ⚠️ **`bcmcmd` 就算失敗也 exit 0**(`VLAN: ERROR: Entry exists` / `Failed to execute the diagnostic command` 都照樣回 0),所以 `blanton_traffic_linespeed.sh` 是**比對輸出**而非看 exit code。另外 `bcmcmd` 一律要 `` - ⚠️ **TTL 的 `timeout` 是全域的**:`timeout = N` 之後**每一個** `wait` 都被限制在 N 秒。逾時的 `wait` 直接返回而沒吃到 prompt,下一個指令就在前一個還沒跑完時送出,之後整輪錯開一拍。**設了一定要 配一個 `timeout = 0` 還原**(`wait_init.ttl` 60→0;Script B 的 cdc_ncm 探測 15→0 在 `:skip_ping`) - ⚠️ **兩張管理網卡同網段會 ARP flux**:`mgmt_ping_monitor.sh` 讓 eth0/eth1 同時 up,同一個 /24 下 對端 ARP 可能由任一張卡回應,回包落在沒送封包的那張。`ARP_STRICT=1` 擋掉;判讀時看 `RESULT` 行的 `nic_tx`/`nic_rx`(該卡自己的 packet delta)—— **ping 成功但 `nic_tx` 接近 0 = 封包從另一張卡出去的** - ⚠️ **`ip -s link` 的欄位順序是 `bytes packets errors ...`**,要 packet 數取的是**第 2 欄**不是第 1 欄 - ⚠️ **`mgmt_ping_monitor.sh` / `bmc_monitor*.sh` 需要 exec bit**,且**不是改用 `bash x.sh start` 就能繞過** —— `do_start` 內部是 `setsid "$SCRIPT_PATH" __daemon`,直接執行該路徑。git 記錄是 `100644`, Windows → 隨身碟 → DUT 也帶不動權限位元,所以佈署後要 `chmod +x ~/Blanton_Script/bmc_monitor*.sh`。 沒做的話 start 會 Permission denied、後面的 `cat` 撲空,而且**不會報錯**,只會得到一份全空的 log - ⚠️ **這幾支 monitor 的 `tail` 子命令是 `tail -n 50 -f`,永遠不返回**。TTL 裡絕對不要呼叫它 (Script C 曾因此卡死,`18ce7a1` 改成直接 `cat log/*.log`) - ⚠️ **背景 monitor 的 `start` 只等 1 秒就返回**,不是跑完一輪。Script A 要做一輪基線的話, `start` 和 `stop` 中間必須 `pause`(目前是 45 秒,一輪約 30 秒)—— 少了它 log 只會有 START banner - ⚠️ **`show_dmesg.ttl` 結尾會 `dmesg -C` 清空 kernel ring buffer**。這是刻意的(讓 Script C 只看到 soak 期間新產生的訊息),但代表事後在 DUT 上 `dmesg` 撈不到舊訊息 —— 內容只存在 master log 裡 - ⚠️ **DUT 的 awk 對 `%d` 會夾到 INT32**(2147483647)。線速流量的計數器是 ~10¹² 量級, 所以 awk 裡輸出大數一律用 `%.0f`(double 域,精確到 2⁵³)。`blanton_traffic_linespeed.sh` V0.4.1 已修;寫新的 awk 報表時要記得同一件事 ## 資料夾說明 - `src/Script_ABC_Blanton/` — 可執行內容(Tera Term 工作目錄;內含要 scp 到 DUT 的 `Blanton_Script/`) - `docs/` — 客戶 FPGA 規格、AER/EDAC 檢查依據、逐項 Status 表(最新為 `*_20260817.xlsx`) - `tools/` — Host / 離線端:`bcm_mibpair_report_V1.1.0.py`(drivshell log → per-pair 報表)、 `traffic_loopback_*.txt`(bcmcmd 原始指令表,`blanton_traffic_linespeed.sh` 是其 bash 版, **改 loopback 線路時兩邊要同步**) - `publish/` — `publish.sh`(打包工具,**進 git**)+ `Script_ABC_Blanton_/` 產出(**gitignored**) - `secret/` — 🚫 gitignored(除 `README.md` 與 `*.example`):DUT 帳密、per-unit BDF 覆寫、COM 設定 - `For_AI/` — 🚫 gitignored:AI 協作素材(波形截圖、草稿筆記)