Files
Blanton_TTL_Script/ARCHITECTURE.md
T
etwenandClaude Opus 5 24c704c667 docs(arch): Add ARCHITECTURE.md and CLAUDE.md, init repo
Bring the Blanton Tera Term TTL test suite under version control and
document how the pieces fit together.

- ARCHITECTURE.md: A/B/C script roles, host-to-DUT-to-FPGA data path,
  config/settings/profile data models, PCIe AER + EDAC topology table,
  10 key constraints, and 6 development phases derived from the
  Status_20260814 spreadsheet's On-Going items
- CLAUDE.md: stack, smoke-test commands, conventions, and the hardware
  footguns (per-unit BDF, VSPI vs VI2C timing, repeated START,
  STORE_USER_ALL, ARB_LOST false positives)
- secret/: gitignored credential store with README + .example template,
  so the DUT login stops living in 1_Blanton_Script_A.ttl
- .gitignore: secret/*, For_AI/, *.log, publish/, *.DSN

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
2026-08-17 08:52:11 +08:00

549 lines
33 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ARCHITECTURE — Blanton TTL Script
## Overview
**Blanton_TTL_Script** 是 BlantonProject Helios)交換器平台的**系統層可靠性測試自動化腳本組**。
測試工程師在 Windows 端用 **Tera Term (TTL macro)** 透過 COM port 連上 DUT 的 SONiC console
由 A / B / C 三支腳本依序驅動一整輪 stress + margin + error-counter 測試,全程自動存 log。
三支腳本的分工就是一輪測試的三個階段:
| Script | 階段 | 做什麼 |
|--------|------|--------|
| `1_Blanton_Script_A.ttl` | **Pre-test / Baseline** | 登入、對時、載入 shell 工具、清 PCIe AER、抓 PCIe tree / margin / PMON / dmesg 基線 |
| `2_Blanton_Script_B.ttl` | **Stress / Soak** | 開 CPU / DDR / SSD / USB / PCIe / I2C 壓力程序,之後進無限迴圈每輪抓 fan / temp / margin |
| `3_Blanton_Script_C.ttl` | **Post-test / Verdict** | 殺掉壓力程序、再抓一次 PMON / dmesg / PCIe AER,比對 stress log 判定 |
DUT 端的實際取數能力則來自一組 **bash 工具庫**`Blanton_Script/`),這一層才是真正碰硬體的地方:
CB FPGA 的 PCIe BAR`pcimem`)→ FPGA 內建 I2C / VI2C master → 板上 VRM、溫度感測器、
LTC2980 margin 控制器。TTL 只負責「按順序 `sendln` 並把畫面收進 log」,硬體語意全在 bash 這層。
**使用者**:硬體 / 系統驗證工程師(ETWen、KC、Alan)。
**核心價值**:把一輪要跑數小時、跨 PCIe / DDR / I2C / 電源多個子系統的 reliability run
壓縮成「開 Tera Term → 跑 A → 跑 B 泡著 → 跑 C 收工」三個動作,且每一筆數據都有 log 可回溯。
---
## Tech Stack
| Layer | Technology |
|-------|-----------|
| 測試控制端(Host | Tera Term 5.x **TTL macro**`.ttl`),Windows |
| Host ↔ DUT 通道 | RS-232 / USB-Serial COM portSONiC console |
| DUT OS | SONiCDebian-based network OS),bash + busybox/mawk |
| DUT 端工具語言 | Bash Shell Script |
| 暫存器存取後端 | `pcimem`mmap PCI sysfs `resource0` + BAR 相對 offset |
| I2C / PMBus 路徑 | CB FPGA F3 OpenCores I2C master、CB FPGA F3 VI2C proxy、CPU 原生 bus`i2cset`/`i2cget` |
| 電源 margin | LTC2980= 2 × LTC2977over PMBusLINEAR16 編碼 |
| 錯誤計數來源 | Linux PCIe AER sysfs`aer_dev_*`)、EDAC sysfs`dimm_ce/ue_count` |
| 平台監控 | SONiC `show platform *`pmon container |
| 壓力測試 | `mlucas-avx2`AMD CPU)、`~/hammer/tools/stress_*.py`DDR / SSD / USB / PCIe / I2C |
| 版本控制 | GitNAS + Gitea 私有 remote**不推 GitHub,含客戶 NDA 資料** |
> ⚠️ **無編譯步驟。** TTL 與 bash 都是直譯執行,「build」等同「把 `src/Script_ABC_Blanton/` 複製到
> Tera Term 工作目錄,並把 `Blanton_Script/` scp 到 DUT 的 `~/`」。
---
## Architecture Diagram
```
┌──────────────────────────────────────────────────────────────┐
│ Windows Host — Tera Term 5.x │
│ │
│ 1_Blanton_Script_A.ttl ──┐ │
│ 2_Blanton_Script_B.ttl ──┼─→ include "config.ttl" │
│ 3_Blanton_Script_C.ttl ──┘ (prompt / EN_* 旗標) │
│ │ │
│ └─→ include "utils/*.ttl" (可重用取數片段) │
│ │
│ logopen → Logs/Blanton_Margin_<ts>.log (整段 console 存檔) │
└───────────────────────┬──────────────────────────────────────┘
│ COM portsendln "<cmd>" / wait "<prompt>"
┌──────────────────────────────────────────────────────────────┐
│ DUT — SONiC console (root@sonic:~#) │
│ │
│ ~/Blanton_Script/ (source 進 shell 後成為一組函數) │
│ ├ blanton_fpga_pcimem.sh cb_fpga / pmc_fpga / swb0_fpga │
│ ├ blanton_cb_i2c.sh cb_i2c_* / cb_pmbus_* │
│ ├ blanton_icb_vi2c.sh vi2c_* (ICB/PDB proxy) │
│ ├ blanton_temp_sensor.sh temp_cb / temp_icb / temp_all │
│ ├ blanton_pwr_data.sh pwr_data / pwr_data_pdb │
│ └ LTC2980_Margin_Script/ margin_init / margin_status ... │
│ │
│ ~/hammer/tools/ 壓力程序(mlucas-avx2, stress_*.py
│ SONiC CLI show platform fan/temperature/... │
│ Linux sysfs aer_dev_* / edac mc0/rank* │
└───────────────────────┬──────────────────────────────────────┘
│ pcimem /sys/bus/pci/devices/0000:03:00.<fn>/resource0
┌──────────────────────────────────────────────────────────────┐
│ CB FPGA (PCIe EP4 個 Function) │
│ F0 local regsRST_CAUSE_REG 0xD90 / SWB 0xD94,0xD98 │
│ F3 I2C master Ch0..Ch17 (base 0x300, stride 0x20) │
│ F3 VI2C→ICB Ch0..Ch4 (base 0x780, stride 0x20) │
│ F2 VSPI 橋接 PMC/ICB/SWB(慢,~18ms/reg,本專案不走) │
└───────────────────────┬──────────────────────────────────────┘
│ I2C / PMBus
TCA9546/9543 mux · MP29816/MP2985B VRM · TMP75/TMP432 溫感
MAX31790 風扇 · LTC2980 margin (CONN13~16 × CB/SWB0/SWB1)
PDBHotswap / Power brick / EFUSE(走 VI2C ch3/ch4
```
---
## Project Structure
```
Blanton_TTL_Script/
├── CLAUDE.md # 專案記憶 & 給 Claude 的指令
├── ARCHITECTURE.md # 本架構文件
├── .gitignore # secret/ + For_AI/ + logs 規則
├── docs/ # 規格與狀態文件(客戶提供 / 專案產出)
│ ├── Blantons_FPGA_Registers.md # FPGA 暫存器規格(markdown 正本,查 offset 用)
│ ├── Blantons_FPGA_Registers_draft.docx # 同上,客戶原始 docx
│ ├── Blantons_FPGA_Registers_Map_draft.xlsx
│ ├── Blantons_PCIe_AER_and_DDR_EDAC_checks.pdf # AER / EDAC 檢查點依據
│ └── TTL_Script_Blanton_Status_20260814.xlsx # ⭐ 三支腳本逐項 StatusOK / On-Going + Owner
├── tools/ # Host 端輔助腳本(log 解析、報表產生)
├── secret/ # 🚫 gitignored — DUT 密碼、per-unit BDF、COM 設定
│ ├── README.md # ✅ committed — 用途索引
│ ├── config_secret.ttl.example # ✅ committed — 帳密範本(__CHANGE_ME__
│ └── config_secret.ttl # 🚫 實際帳密,由 config.ttl include
├── For_AI/ # 🚫 gitignored — AI 協作素材(波形截圖、草稿)
├── publish/ # 可交付的打包輸出(Blanton_Script_ABC_v<ver>_<date>/ + zip
└── src/
└── Script_ABC_Blanton/ # ← Tera Term 的工作目錄(整包給測試員)
├── config.ttl # 全域設定:testcase 名、EN_Margin / EN_log、三個 prompt 字串
├── 1_Blanton_Script_A.ttl # Pre-test:登入 → 對時 → source 工具 → 清 AER → 抓基線
├── 2_Blanton_Script_B.ttl # Stress:開壓力程序 → while 1 每輪抓 fan/temp/margin
├── 3_Blanton_Script_C.ttl # Post-testkill → 再抓一次 → 比對 stress log
├── utils/ # 可 include 的取數片段(TTL,無狀態、只 wait+sendln
│ ├── pcie_bus.ttl # lspci -tvvv / -vv
│ ├── setup_pmon.ttl # show platform summary/fan/temperature/psu/voltage/current/ssd
│ ├── show_dmesg.ttl # date + dmesg grep error/fail/warning
│ ├── show_margin_status.ttl # source margin_status_all.sh(掃 9 顆 LTC2980
│ ├── kill_all_process.ttl # kill $(jobs -p)
│ ├── show_pcie_error_reg.ttl # 舊的合併版(已被下列 per-device 版取代)
│ ├── show_pcie_error_reg_TH6_SWB0.ttl # EP 01:00.0 + RP 00:01.1
│ ├── show_pcie_error_reg_TH6_SWB1.ttl # EP 02:00.0 + RP 00:01.2
│ ├── show_pcie_error_reg_FPGA.ttl # RP 00:01.5(共用上游)
│ ├── show_pcie_error_reg_BMC.ttl # EP 03:00.0 + RP 00:01.4
│ ├── show_pcie_error_reg_I210.ttl # EP 07:00.0 + RP 00:02.4
│ ├── show_pcie_error_reg_SSD.ttl # EP 06:00.0 + RP 00:02.1
│ └── show_pcie_error_reg_DDR.ttl # EDAC mc0 rank0~3 CE/UE
├── logs/ # Tera Term logopen 輸出(*.log gitignored
└── Blanton_Script/ # ← scp 到 DUT ~/ 的單位(bash 工具庫)
├── blanton_fpga_pcimem.sh # pcimem 後端:cb_fpga/pmc_fpga/icb_fpga/swb0_fpga/swb1_fpga
├── blanton_cb_i2c.sh # CB FPGA F3 I2C masterCh0~Ch17+ PMBus helper
├── blanton_icb_vi2c.sh # CB F3 VI2C proxy → ICB/PDBCh0~Ch4
├── blanton_temp_sensor.sh # TMP75 / TMP432 讀溫(CB Ch10 mux + ICB VI2C Ch2
├── blanton_pwr_data.sh # SWB VRM + PDB brick 的 Vin/Vout/Iout/Temp 表
└── LTC2980_Margin_Script/ # 電壓 margin 子專案(另有獨立 repo
├── margin.sh # margin_init/status/set/apply_profile/save
├── settings/*.conf # 一個 .conf = 一顆 LTC2980CB + SWB0/1 × CONN13~16
├── profiles/*.conf # 16-ch 批次組合(comboA/B、high3/5、low3/5、normal、off
├── script/*_all.sh # 跨 9 顆 LTC2980 的批次 status / apply / save
└── logs/ # margin 操作 log
```
---
## Data Models
本專案沒有資料庫,「資料模型」是**設定檔格式**與**暫存器 / sysfs 語意**。
### 1. `config.ttl` — 全域測試參數(TTL 變數)
```ini
strTestcase = "Margin" ; 測項名,進 log 檔名
project_name = "Blanton" ; 專案名,進 log 檔名
EN_Margin = 1 ; 1=跑 margin 掃描, 0=跳過
EN_log = 1 ; 1=logopen 存檔, 0=不存
prompt_login = "sonic login:"
prompt_sonic = "admin@sonic:~$"
prompt_sonic_root = "root@sonic:~#"
```
Log 檔名規則:`<mdir>\Logs\<project_name>_<strTestcase>_<YYYYmmdd-HHMMSS>.log`
### 2. `settings/<board>.conf` — 一顆 LTC298016 channel
| 欄位 | 型別 | 說明 |
|------|------|------|
| `TRANSPORT` | string | `""`/`"i2c"` = CPU 原生 bus`i2cset`);`"swb"` = 走 CB FPGA F3 I2C |
| `CB_I2C_CH` | int | `TRANSPORT="swb"` 時的 FPGA I2C 通道(6/7/8/9 |
| `CHIPS[]` | string[2] | `"bus:addr"`index 0 → CH0~7、index 1 → CH8~15 |
| `CHIP_PRE_CMD[]` / `CHIP_POST_CMD[]` | string[1] | mux 切換等前後置指令,`;` 分隔多筆 |
| `CH<n>_VNOM` | string | 標稱電壓(`"-"` = 未使用 / NC |
| `CH<n>_NET` | string | 電路 net name(對照 schematic |
Channel 定址:`ch / 8``CHIPS[]` index`ch % 8` → LTC2977 PMBus PAGE0x00~0x07)。
### 3. `profiles/*.conf` — 16-ch 批次 margin 組合
```bash
PROFILE_CHANNELS=( "0:high:8" "1:low:8" ... ) # "channel:operation:change_percent"
```
| operation | PMBus `OPERATION`(0x01) | 說明 |
|-----------|------------------------|------|
| `high` | `0xA8` | Margin high |
| `low` | `0x98` | Margin low |
| `nominal` | `0x80` | 回標稱值(跟隨 VOUT_COMMAND |
| `off` | `0x00` | 關閉輸出 |
### 4. FPGA / I2C 暫存器語意(工具庫依賴)
| 區塊 | 位置 | 關鍵欄位 |
|------|------|----------|
| CB F0 local | `cb_fpga 0 0xD90` | `RST_CAUSE_REG``0xD94`/`0xD98` = SWB0/SWB1 |
| CB F3 I2C(每 ch 0x20 stridebase 0x300 | `+00/04` PRSCL, `+08` CTRL(b7 MOD_EN), `+0C` TX/RX, `+10` CMD/STAT, `+14` MUX_SEL, `+18` RST, `+1C` SEM |
| CB F3 VI2Cbase 0x780ICB/PDB | 同上,但 **`+1C` 無 SEM** |
| I2C CMD | `STA=0x80 STO=0x40 RD=0x20 WR=0x10 NACK=0x08 IACK=0x01` |
| I2C STAT | `RX_ACK=0x80(1=NACK) BUSY=0x40 ARB_LOST=0x20 TIP=0x02 INT=0x01` |
| Prescale @75MHz | `0x88` = 100 kHz、`0x24` = 400 kHz |
### 5. 錯誤計數 sysfs(判定依據)
| 類別 | 路徑 | 判定 |
|------|------|------|
| PCIe AEREP + 上游 RP 都要看) | `/sys/bus/pci/devices/<BDF>/aer_dev_{correctable,nonfatal,fatal}` | test 前後差值 > 0 即 failcorrectable 需依 spec 設門檻) |
| DDR EDAC | `/sys/devices/system/edac/mc/mc0/rank<0-3>/dimm_{ce,ue}_count` | UE > 0 直接 failCE 依門檻 |
**Blanton PCIe 拓樸對照**`show_pcie_error_reg_*.ttl` 的來源):
| 裝置 | Endpoint BDF | Upstream Root Port |
|------|--------------|--------------------|
| TH6 SWB0 | `0000:01:00.0` | `0000:00:01.1` |
| TH6 SWB1 | `0000:02:00.0` | `0000:00:01.2` |
| CB FPGA | F0~F3 @ `0000:03:00.x` | `0000:00:01.5` |
| BMC | `0000:03:00.0` | `0000:00:01.4` |
| I210 1G NIC | `0000:07:00.0` | `0000:00:02.4` |
| NVMe SSD | `0000:06:00.0` | `0000:00:02.1` |
> ⚠️ **BDF 是 per-unit 的**。`blanton_fpga_pcimem.sh` 的 `FUNCT0..3_RES` 已經改過三次
> 04:00.x → 03:00.x → 05:00.x → 03:00.x)。換 DUT 一定要先 `lspci -Dnn | grep -i fpga` 重新確認,
> 同理 `show_pcie_error_reg_*.ttl` 裡的 BDF 也要跟著校。
---
## Key Features
| 模組 | 進入點 | 功能 |
|------|--------|------|
| **Script APre-test** | `1_Blanton_Script_A.ttl` | root 登入 → `mkdir ./logs``date -s` 對時 → source 五個 bash 工具 → 清/讀 7 組 PCIe AER → `lspci -tvvv/-vv` → margin 全掃 → PMON 七項 → dmesg 三 grep → `messagebox` 提示接 Script B |
| **Script BStress** | `2_Blanton_Script_B.ttl` | `mlucas-avx2 -cpu 0:15` + 5 份 `stress_mem.py` + `stress_hhmd/ssd/pcie/usb.py` 全部背景執行 → `jobs` 確認 → `while 1` 每輪 `show platform fan` / `temperature` / margin |
| **Script CPost-test** | `3_Blanton_Script_C.ttl` | `kill $(jobs -p)` → PMON + dmesg 再抓一次 → 7 組 AER 再抓一次 → `cat` mlucas / stress_ssd log → 完成 messagebox |
| **FPGA 暫存器存取** | `cb_fpga <fn> <addr> [data]` | pcimem 打 `resource0` + BAR 相對 offset32-bit word`pmc/icb/swb0/swb1_fpga` 走 VSPI 窗口 |
| **CB I2C / PMBus** | `cb_i2c_init/scan/read/write``cb_pmbus_read/write/linear16` | FPGA F3 OpenCores master**讀用 Repeated START**SMBus/PMBus 裝置必需) |
| **ICB / PDB 存取** | `vi2c_init/scan/read/write``vi2c_scan_all` | CB F3 VI2C proxy~3.3 ms/reg,取代 VSPI 的 ~18 ms/reg(後者會踩 SMBus 2535 ms timeout |
| **溫度** | `temp_cb` / `temp_icb` / `temp_all` | TMP7512-bit 左靠齊 ×0.0625)、TMP432(含 RANGE bit 的 64 偏移、remote1/2 |
| **電源資料** | `pwr_data` / `pwr_data_pdb` / `pwr_pdb_id` | SWB VRM 全軌 Vin/Vout/Iout/Temp 對齊表;MP29816 解析度**執行期從 `MFR_VOUT_SCALE_LOOP` 讀**,不寫死 |
| **電壓 Margin** | `margin_init/status/set/apply_profile/save` + `*_all.sh` | 9 顆 LTC2980CB CONN13、SWB0/1 CONN13~16)批次 high/low margin 與狀態掃描 |
---
## Data Flow
### 一輪完整測試(端到端)
```
[測試員] 開 Tera Term,連 COM<n>Control → Macro → 1_Blanton_Script_A.ttl
Script A ── logopen Logs/Blanton_Margin_<ts>.log ──┐ (之後所有畫面都進這個檔)
│ │
├─ 登入 admin → sudo -i → root@sonic:~# │
├─ date -s "<host 時間>" ← 讓 DUT 時戳可對照 │
├─ source 5 個 bash 工具(函數進 shell
├─ AER 基線:7 組 EP+RP 的 correctable/nonfatal/fatal
├─ lspci -tvvv / -vv ← 拓樸 + link speed/width
├─ margin_status_all ← 9 顆 LTC2980 × 16ch 的 Vout 與偏差%
├─ show platform × 7 ← fan/temp/psu/voltage/current/ssdhealth
└─ dmesg | grep error/fail/warning
[messagebox "Start Script B"] ← 人工確認後手動跑 B
Script B ── 同一個 log 檔續寫(logwrite 分隔線)
├─ 背景程序:mlucas-avx2(CPU) ×1, stress_mem ×5,
│ stress_hhmd(I2C/LSB/PCIe), stress_ssd, stress_pcie, stress_usb
├─ jobs ← 確認全部起來了
└─ while 1: fan → temperature → margin_status_all soak 期間持續取樣)
[測試員 Ctrl-C / 停止 macro,接著跑 C]
Script C
├─ kill $(jobs -p) ← 收掉所有背景壓力
├─ show platform × 7 + dmesg ← 收工快照
├─ AER 再抓一次 ← 與 Script A 基線相減 = 本輪新增錯誤
└─ cat mlucas_amm_log / log.stress_ssd ← 壓力程式自身的 pass/fail
[messagebox "GOOD JOB! Test Case DONE"] → 人工檢查 log
```
### 硬體讀值路徑(以「讀一顆 SWB VRM 的 Vout」為例)
```
pwr_data
└→ cb_pmbus_read <ch> <slave7> 0x8B 2 (blanton_cb_i2c.sh)
└→ _cbi2c_xfer_readSTA+WR(slave|W) → WR(reg) → Sr + STA+WR(slave|R)
→ RD(ACK) → RD(NACK)+STO ← Repeated START
└→ cb_fpga 3 <0x300 + ch*0x20 + reg> (blanton_fpga_pcimem.sh)
└→ pcimem /sys/bus/pci/devices/0000:03:00.3/resource0 <off> w [data]
└→ CB FPGA BAR0 → F3 I2C master → SCL/SDA → MP29816/MP2985B
└→ 解碼:MP2985B = 1 mV/LSBMP29816 = 由 MFR_VOUT_SCALE_LOOP(0x29) bit[12:10] 決定
Vin 一律 31.25 mV/LSB(÷32
```
---
## Key Constraints & Business Rules
1. **A → B → C 必須依序跑,且 B 之後才能跑 C。** Script B 的背景 job 只存在於那個 shell session
Script C 的 `kill $(jobs -p)` 依賴同一個 session;中途斷線就得手動收程序。
2. **A / B / C 共用同一個 log 檔**:只有 Script A `logopen`B / C 用 `logwrite` 續寫分隔線。
跑 B/C 前若關掉了 Tera Termlog 就斷了。
3. **PCIe AER 的判定是「差值」不是「絕對值」**Script A 抓基線、Script C 抓結果,
兩者相減才是本輪產生的錯誤。EP 與上游 Root Port **兩邊都要看**(錯誤可能只記在 RP)。
4. **BDF 是 per-unit 的**,換 DUT 必須重新確認並改 `blanton_fpga_pcimem.sh``FUNCT0..3_RES`
`utils/show_pcie_error_reg_*.ttl`(見 Data Models §5 註)。
5. **ICB / PDB 一律走 VI2C,不走 VSPI**VSPI ~18 ms/reg 會讓 I2C byte 相之間拉到 ~50 ms
踩中 SMBus 2535 ms timeout,裝置會 NACK register pointer。實測全 5 通道掃描 9.4 s vs 34.0 s。
6. **I2C 讀一律用 Repeated START**(不是 STOP + START):PMBus / SMBus 裝置(VRM、EFUSE
只吃 Sr;只有純暫存器裝置兩種都行。
7. **`margin_save``STORE_USER_ALL`)會永久寫進 NVM**,斷電保留。測試流程中**絕不執行**,
以免覆蓋客戶出廠 config。`margin.sh` 的 auto-enable 只改 RAM`ON_OFF_CONFIG`),斷電復原。
8. **操作硬體電壓有損壞 DUT 的風險**:套 profile 前先確認該軌 OV/UV limit 與 servo DAC 注入電阻
有 populate(本板部分 margin 電阻標 PROTO,沒 populate 的軌電壓不會動)。
9. **`ARB_LOST` 不等於裝置存在**`vi2c_scan` 只看 `RX_ACK`,仲裁失敗會被誤報成「有裝置」。
`blanton_pwr_data.sh` 因此加了 ARB_LOST-aware retry 與 plausibility window
`0xFFFF` 或超出範圍一律回 `NA`)——**寧可 NA 也不要印出一個看起來像數據的錯值**。
10. **DUT 密碼不得進 git**`1_Blanton_Script_A.ttl` 目前的 `sendln "YourPaSsWoRd"` 是 placeholder
實際帳密必須放 `secret/config_secret.ttl`gitignored)並由 `config.ttl` include。
11. **客戶 NDA**`docs/` 內含客戶 FPGA 規格與 schematic 衍生資訊,**本 repo 只推 NAS + Gitea
絕不推 GitHub**。
---
## Security Considerations
| 項目 | 做法 |
|------|------|
| **DUT console 帳密** | 集中在 `secret/config_secret.ttl`gitignored),`config.ttl``include` 載入。repo 內只留 `secret/config_secret.ttl.example`,敏感欄位一律 `__CHANGE_ME__` |
| **`secret/` 資料夾** | 本機 / 現場敏感資料集中地:DUT 帳密、per-unit BDF 覆寫、COM port 設定、客戶提供的未公開附件。`.gitignore``secret/*` + `!secret/README.md` + `!secret/*.example` + `!secret/.gitkeep`**除 README 與 `.example` 外全部忽略** |
| **客戶機密文件** | `docs/` 內 FPGA 規格(docx/xlsx/md)屬客戶 NDA 範圍;schematic 原始檔(`*.DSN`)一律 gitignore,不進 repo |
| **Remote 限制** | 只推私有 remote`nas``git.et-wen.com:51222`+ `gitea``etgit.et-wen.com`)。**不設 GitHub `origin`** |
| **測試 log** | `logs/*.log` 含 DUT 序號、MAC、韌體版本等可識別資訊 → gitignore,只保留目錄結構(`.gitkeep` |
| **破壞性硬體指令** | `margin_save` / `STORE_USER_ALL` 為永久 NVM 寫入,工具預設不呼叫;批次腳本 `margin_save_all.sh` 在 README 與腳本頂端都有警語 |
| **root 權限** | 全流程在 `root@sonic:~#` 下執行(pcimem / i2c 需要);腳本不留任何 `chmod 777` 或放寬權限的動作 |
| **For_AI/** | AI 協作素材(截圖、草稿筆記)整個資料夾 gitignore,避免不小心把客戶圖面帶進 repo |
---
## Build & Setup Steps
無編譯。從零到能跑一輪測試:
```bash
# ── 0. 取得專案(開發機 / 測試 NB)────────────────────────────
git clone ssh://ETHouseNAS@git.et-wen.com:51222/volume1/git/Blanton_TTL_Script.git
cd Blanton_TTL_Script
# ── 1. 準備帳密(不進 git)──────────────────────────────────
cp secret/config_secret.ttl.example secret/config_secret.ttl
# 編輯 secret/config_secret.ttl,填入實際 DUT 帳密(取代 __CHANGE_ME__
# ── 2. DUT 端:部署 bash 工具庫 ─────────────────────────────
scp -r src/Script_ABC_Blanton/Blanton_Script admin@<DUT_IP>:~/
ssh admin@<DUT_IP> 'sudo -i'
# (現場無網路時改用 USB 隨身碟複製到 ~/Blanton_Script
# ── 3. DUT 端:確認 FPGA BDF(每台不同!)────────────────────
lspci -Dnn | grep -i fpga # 例:0000:03:00.0
ls -d /sys/bus/pci/devices/0000:*:00.3
# 若不是 0000:03:00.x,改 ~/Blanton_Script/blanton_fpga_pcimem.sh 的 FUNCT0..3_RES
# 以及 src/Script_ABC_Blanton/utils/show_pcie_error_reg_*.ttl 內的 BDF
# ── 4. DUT 端:煙霧測試(跑 Script A 之前先手動確認)──────────
source ~/Blanton_Script/blanton_fpga_pcimem.sh
cb_fpga 0 0xD90 # RST_CAUSE_REG,讀得到值 = BAR 通了
source ~/Blanton_Script/blanton_cb_i2c.sh
cb_i2c_init 11 && cb_i2c_scan 11 # Ch11 風扇控制器,應看到 0x20
source ~/Blanton_Script/LTC2980_Margin_Script/margin.sh
margin_init Blanton_CB_CONN13 && margin_status
```
**HostWindows)端:**
```
1. 安裝 Tera Term 5.x
2. 把 src\Script_ABC_Blanton\ 整包複製到本機(路徑不要有空白與非 ASCII)
3. 在該資料夾下建立 Logs\ 目錄(Script A 的 logopen 需要)
4. Tera Term 連上 DUT COM port(預設 115200-8-N-1
5. Control → Macro → 選 1_Blanton_Script_A.ttl
6. A 跑完出現 messagebox → 手動跑 2_Blanton_Script_B.ttlsoak
7. Soak 時間到 → 停止 B 的 macro → 跑 3_Blanton_Script_C.ttl
8. 檢查 Logs\Blanton_Margin_<ts>.log
```
> 註:本專案非 .NET / Blazor / EC2 架構,`aws-ec2-deploy` 與 `vbox-run-deploy` 兩份部署指南不適用,已跳過。
---
## Development Phases
現況基準:`docs/TTL_Script_Blanton_Status_20260814.xlsx` 已逐項標記 OK / On-Going
以下 Phase 直接把該表的 On-Going 項目排進來,並補上工程化(版控、密碼外移、打包)的缺口。
### Phase 1 — 版控化 + 密碼外移(工作量:S)
**目標:** 專案進 git(NAS + Gitea),帳密不再躺在腳本裡,任何人 clone 下來照文件就能跑。
**包含:**
- [ ] `git init` + `.gitignore``secret/*``For_AI/``logs/*.log``~$*``*.DSN`
- [ ]`secret/README.md` + `secret/config_secret.ttl.example``__CHANGE_ME__` placeholder
- [ ] `config.ttl` 改為 `include "..\..\secret\config_secret.ttl"`(或現場放同層),
`1_Blanton_Script_A.ttl``sendln "YourPaSsWoRd"` 換成 `sendln dut_password`
- [ ] `src/Script_ABC_Blanton/logs/.gitkeep`,既有 `Blanton_Margin_20260814-164122.log` 移出 repo
- [ ] `CLAUDE.md` + `ARCHITECTURE.md` 進 repopush `nas` + `gitea`**不推 GitHub**
**驗收條件:** 在另一台機器 `git clone` → 填 `secret/config_secret.ttl` → Script A 能完整登入並產生 log
`git log -p` 中搜不到任何實際密碼。
---
### Phase 2 — Script A 補完:Check History + Margin 驗收(工作量:M
**目標:** Script A 的基線資料補齊到「開機原因 + 全部電壓軌」都有紀錄,Status 表的兩個 On-Going 轉 OK。
**包含:**
- [ ] 新增 `utils/show_reset_cause.ttl``cb_fpga 0 0xD90`RST_CAUSE_REG)、
`cb_fpga 0 0xD94`SWB0)、`cb_fpga 0 0xD98`(SWB1),並在註解貼上 bit 定義
(來源 `docs/Blantons_FPGA_Registers.md` §5 RST_CAUSE_REG
- [ ] Script A 的 `; ========== Check History ==========` 區塊改 include 上面這支
- [ ] `utils/show_margin_status.ttl`:清掉已註解的 per-conf 舊寫法,只留
`margin_status_all.sh`;確認 9 顆 LTC2980 都能掃到(含 SWB 的 `TRANSPORT="swb"` 路徑)
- [ ] 新增 `utils/show_pwr_data.ttl``pwr_data` + `pwr_data_pdb`)與
`utils/show_temp_sensor.ttl``temp_all`),把 `blanton_pwr_data.sh` /
`blanton_temp_sensor.sh` 真正接進流程(目前 Script A 只 source 沒用)
- [ ] Script A 開頭加 BDF 自檢:`lspci -Dnn | grep -i fpga`log 裡看得到本台的實際 BDF
**驗收條件:** 跑一次 Script Alog 內同時含 reset cause 三個暫存器值、9 顆 LTC2980 × 16ch 的
margin status、全部 VRM 軌的 Vin/Vout/Iout/Temp、CB + ICB 溫感讀值,且無 `ERR` / `NA` 以外的異常。
---
### Phase 3 — Script B 壓力層穩固化(工作量:M)
**目標:** 壓力程序起得來、起不來看得出來,soak 迴圈有時戳、可控週期。
**包含:**
- [ ] 部署 `~/hammer/tools/` 前置檢查:新增 `utils/check_hammer_tools.ttl`
`ls -l ~/hammer/tools/` + `ls ~/hammer/tools/amd/mlucas-avx2`),缺檔就別往下跑
- [ ] 壓力程序 log 加時戳,避免多輪覆蓋:
`mlucas_amm_log``~/logs/mlucas_amm_log_$(date +%Y%m%d-%H%M%S).log`Status 表 ScriptB #2 的既定寫法)
- [ ] `jobs` 之後加驗證:期望 10 個背景 job1 mlucas + 5 mem + hhmd/ssd/pcie/usb),
數量不符時 `messagebox` 提示
- [ ] soak 迴圈改為「每輪先 `date`、跑完 `pause <間隔>`」,
`EN_LoopInterval`(預設 600 秒 = 10 min)放進 `config.ttl`,兌現 Status 表的「Get data every 10mins」
- [ ] soak 每輪補 `show platform psustatus` / `voltage` / `current`(目前只有 fan + temperature
- [ ]`; ========== CLEAR EVENT ==========`Status 表 ScriptB #1Owner: Alan
**驗收條件:** Script B 啟動後 `jobs` 顯示 10 個 job;連續跑 3 輪,log 內三段各自帶正確時戳且間隔 ≈10 min;
故意把 `~/hammer` 改名,Script B 會在前置檢查就停下並提示。
---
### Phase 4 — Traffic 與 SONiC 介面資料(工作量:M)
**目標:** 補齊 Status 表中 Owner=Alan 的三個 traffic 項目,讓測試涵蓋交換晶片的資料面。
**包含:**
- [ ] `utils/traffic_setup.ttl`Blanton/SONiC 版的 port 起始設定與 counter 清零
(對照 Carlsbad 的 `clear int stat global`,改用 SONiC `sonic-clear counters`
- [ ] `utils/show_traffic_counters.ttl``show interface counters`
`show interface counters errors``show interface status`
- [ ] `utils/show_interface_detail.ttl``show interface transceiver eeprom/dom`
`show interface link-training`(對照 Carlsbad `sho int transceiver detail`
- [ ] `utils/show_tech.ttl``show techsupport`Script C 收工快照,Status 表 ScriptC #4
- [ ] Script A 的 TRAFFIC-SETUP-STAGE 與 Script C 的 CHECK Traffic counters 接上這些片段
- [ ] `config.ttl``EN_Traffic` 旗標,未接線的站點可整段跳過
**驗收條件:** `EN_Traffic=1` 時,Script A log 有清零後的 counter 基線、Script C log 有結束時的
counter 與 error-counter,兩者可直接相減;`EN_Traffic=0` 時整段不執行且不報錯。
---
### Phase 5 — Log 解析與自動判定(工作量:L)
**目標:** 不用人眼掃幾 MB 的 console log,跑完自動吐一張 PASS/FAIL 摘要。
**包含:**
- [ ] `tools/parse_blanton_log.py`:吃 `Logs/*.log`,切出 ScriptA / ScriptB / ScriptC 三段
(靠 `logwrite``#####` 分隔線)
- [ ] AER / EDAC 差值計算:抽出 A 與 C 兩次的 `aer_dev_*``dimm_{ce,ue}_count`,輸出增量表,
UE > 0 或 fatal/nonfatal > 0 直接標 FAIL
- [ ] Margin 表解析:把 9 顆 × 16ch 的 Vout / 偏差% 收成 CSV,標出超出 ±(profile 設定值 + 容差) 的軌
- [ ] 溫度 / 風扇 / 電源趨勢:soak 期間逐輪取樣 → CSV(可直接畫圖)
- [ ] Stress 判定:`mlucas_amm_log``log.stress_ssd` 的錯誤關鍵字掃描
- [ ] 產出 `Logs/<run>_summary.md`:一頁 PASS/FAIL + 每個子系統一行結論
**驗收條件:** 拿一份既有 log(如 `Blanton_Margin_20260814-164122.log`)跑解析器,
產出 summary 與 CSV;人工植入一筆假的 `dimm_ue_count=1` 後,summary 正確翻成 FAIL。
---
### Phase 6 — 打包、Runbook 與交付(工作量:S)
**目標:** 產出可直接交給現場測試員(或客戶)的一包,含操作手冊,不需要看原始碼。
**包含:**
- [ ] `tools/publish.sh`:把 `src/Script_ABC_Blanton/` + 空 `Logs/` + `secret/*.example`
打包成 `publish/Blanton_Script_ABC_v<ver>_<YYYYMMDD>/` 與同名 zip(比照
既有的 `Blanton_Script_ABC_v1.0_20251229` 命名)
- [ ] `README.md`(現場用):Tera Term 設定、A→B→C 操作順序、常見錯誤(BDF 不符、
margin 掃不到、hammer 工具缺檔)與對應處理
- [ ] `CHANGELOG.md`:延續三支腳本頂端的 Version History,集中成一份
- [ ] 三支腳本的 header 版號與 `CHANGELOG.md` 對齊,`config.ttl``script_version` 並寫進 log 開頭
- [ ] `docs/TTL_Script_Blanton_Status_*.xlsx` 更新為全 OK,或把剩餘項目移進 Future Extensions
- [ ] 打 git tag `v1.1.0`push `nas` + `gitea`
**驗收條件:** 從 zip 解壓到一台乾淨的測試 NB,照 README 操作,不看原始碼就能完成一輪 A→B→C
並產出 summary`publish/` 內容與 git tag 一致。
---
## Future Extensions
- **Script B 的 eye measurement**Status 表 ScriptB「Take one round of eye measurement on uplink ports」
目前是空區塊,待 TH6 SDK 的 eye scan 指令確認後補上。
- **PDB 電源轉換值驗證**`blanton_pwr_data.sh` 的 PDB 段落在第一台 DUT(COM39)因 ch4 仲裁問題無法驗證,
COM36 才拿到部分結果;`READ_VIN` 已知不是真的輸入電壓(跟隨 `READ_VOUT`)。待拿到 brick 的
`MFR_ID`/`MFR_MODEL` 後對照 datasheet 定案。
- **`show_pcie_error_reg.ttl` 淘汰**:舊的合併版已被 7 支 per-device 版取代,確認無人引用後刪除。
- **BDF 自動偵測**:把 `blanton_fpga_pcimem.sh` 註解中的 auto-detect 片段轉正,
`lspci -Dnn | grep -i fpga` 動態填 `FUNCT0..3_RES`,讓換 DUT 不用改檔。
- **SSH / 網路模式**:目前全走 COM console。若 DUT 管理網路可用,可改用 `plink`/`ssh` 執行同一組
bash 工具,速度與可靠度都比 serial 好,TTL 只保留開機階段。
- **多 DUT 併行**:多台 DUT 同時 soak 時,Tera Term 每台開一個 macro window
可考慮改成 Python`pyserial`)統一排程與集中收 log。
- **與 `LTC2980_Margin_Script` 獨立 repo 的同步機制**:目前 `Blanton_Script/LTC2980_Margin_Script/`
是該 repo 的複本(少了 `ARCHITECTURE.md`/`CLAUDE.md`/`Reference/`,多了兩支 `blanton_*` 後端)。
待評估改用 git submodule 或明確的 vendored 同步腳本。