L 級新功能、PRD/Design/TDD/ADR 三方協作 + 互審 + M9-6 SDK 雙驗證、總計 ~9000 行文件。
範圍:
- A 階段(MVP、5 人天):KL520 + KL720 自動升級 KDP1 → KDP2
- B 階段(10.5 人天):手動降版面向一般使用者 + KL630 / KL730 擴展
- 合計 15.5 人天、安裝包 +7MB(保守 bundle 策略)
關鍵決策:
- 翻案 R5-Q9(progress.md 第二輪使用者決策「韌體燒錄 flash → B 砍掉」)
- 跨平台用 KneronPLUS Python C API、不用 DFUT.exe
- 多版本目錄結構選 C metadata(firmware/<chip>/{version}/ + CURRENT_VERSION)
- Kneron firmware redistribution 授權與 R5-B4 預置模型同性質、發佈前評估
文件產出:
- PRD v2.2(PRD-v2.md 495 行 + features/feature-firmware-management.md 599 行)
- Design v2.2(firmware-management.md 948 行 + control-panel.md §6a graceful shutdown)
- TDD v2.2(v2/firmware-management.md 823 行 + ADR-001 218 行)
- 8 份 research(含 M9-6 弱驗證 + 強驗證、~3200 行)
- 3 份三方互審報告(PM/Design/Architect cross-review)
M9-6 強驗證重大發現(影響 B 階段):
- KL730 product_id 實際是 0x732(不是 0x0730)
- KL630/KL730 firmware 是 embedded Linux rootfs(不是 .bin、不同代設計)
- KneronPLUS Python 沒 update_kdp_firmware_from_files 公開 API、warrenchen 走 ctypes
- 不影響 A 階段、B 階段 M9-8 需 spike
下一步:派 backend M9-1 起跑(bridge.py handle_firmware_upgrade)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
219 lines
13 KiB
Markdown
219 lines
13 KiB
Markdown
# ADR-001: Kneron Dongle FW 偵測 + 升降版(翻案 R5-Q9)
|
||
|
||
## Status
|
||
|
||
**Accepted** — 使用者於 2026-05-24 拍板方案 A + B 一次做完、L 級正規流程。
|
||
|
||
**2026-05-25 update**:M9-6 弱驗證執行(見 `research-kl520-fw-management/55-m9-6-weak-validation-result.md`)後追加兩個新事實:
|
||
1. **visionA-local KneronPLUS wheel 三平台版本不一致**:macOS/Linux = 2.0.0、Windows = 3.1.2。對 A 階段(KL520/KL720 升級)不阻塞(既有 API 在兩個版本都存在);對 B 階段(KL630/KL730)影響重大、B 階段啟動前必須統一升級到 3.1.2+ 並跑三平台 KL520/KL720 回歸(M9-13)。詳見 TDD `v2/firmware-management.md` §1.3。
|
||
2. **PRD AC-FW-3.5(KL630/KL730 升降版)延後至 B 階段 M9-10**:弱驗證確認 warrenchen 沒做 KL630/KL730 升降版(reference 實作為零)、且需要實機才能驗 `update_kdp_firmware_from_files` 對 KL630/KL730 是否適用。A 階段 scope 縮限為 KL520+KL720 自動升級。Decision §1 表格的 A 階段範圍不變(本來就只列 KL520+KL720)、Consequences §5 風險敘述強化。
|
||
|
||
## Context
|
||
|
||
### 痛點背景
|
||
|
||
visionA-local 自 2026-04 上線以來、累積以下與 Kneron Dongle FW 相關的痛點:
|
||
|
||
1. **拿到舊 dongle 完全不能用**:使用者拿到的 KL520 dongle 若是 KDP1 legacy(pid=0x0200)、插上 visionA-local 後 connect 流程在 `kp.core.load_firmware_from_file` 階段失敗、無法 inference。
|
||
2. **KL520 firmware 殘留導致 Error 15 SEND_DATA_TOO_LARGE**(2026-04-21 已修、但 root cause 在 FW 層):commit `ddf0eb8` 為了解 Windows 60s HTTP timeout 加「KL520 首次 connect 跳過 reset」優化、後來發現 KL520 若 session 間 firmware 殘留(`fw=KDP2 Comp/U`)、直接 load_model + inference 100% 炸 Error 15。已 revert、但這暴露既有 FW 偵測 + reset 邏輯的脆弱性。
|
||
3. **KL630 / KL730 偵測不到**:scan 階段顯示得到名字、但 `handle_connect` fall-through 到 KL520 路徑、用錯誤的 firmware 檔載入 → 連不上。新世代 dongle 完全不可用。
|
||
4. **舊 model 與新 FW 相容性**:進階使用者反映「我的舊 NEF model 在升版 FW 後跑不出結果」、缺乏降版機制。
|
||
|
||
### R5-Q9 砍 flash 的歷史決策
|
||
|
||
`progress.md` 重要決策紀錄 §「第二輪使用者決策 Q9」:
|
||
|
||
> 韌體燒錄 flash → B 砍掉
|
||
|
||
(行號為動態值、本 ADR 不寫具體 L 行號避免日後 progress.md 增刪後失準;以「第二輪使用者決策 Q9」描述位置為準)
|
||
|
||
當時砍的理由(推測、原 progress.md 沒留下細節):
|
||
1. visionA-local 是「local 推論工具」、不是「dongle 管理工具」、燒 flash 不屬核心使用旅程
|
||
2. 燒 flash 有 brick 風險、不想對使用者開放
|
||
3. 早期 MVP 範圍縮小、把非必要功能延後
|
||
4. 既有「load_firmware 到 RAM」夠用(KL520 USB Boot 每次都重 load、KL720 已預燒 KDP2)
|
||
|
||
### 為何現在要翻案
|
||
|
||
1. **痛點 #1 是真實場景**:使用者已陸續遇到舊 KDP1 dongle 完全不能用(Q9 原始假設「既有 load_firmware 到 RAM 夠用」不成立)
|
||
2. **同事 warrenchen 雲端版已驗證可做、且安全**:`/tmp/web_academy_prototype/local_service_win/` 有完整實作可參考
|
||
3. **範圍可切割**:Q9 砍的是「使用者按按鈕燒任意 model 到 device flash」、本期是「升級到 Kneron 官方 KDP2 標準版本」、避開大部分 brick 與責任風險
|
||
4. **跨平台技術可行**:KneronPLUS Python API(`kp.core.update_kdp_firmware_from_files`)+ `libkplus.{dll,so,dylib}` 三平台都已在既有 wheel 內、無需引入 Windows-only DFUT.exe
|
||
|
||
### 技術現況盤點
|
||
|
||
visionA-local 既有 code 已有 70% 的 FW 偵測 + RAM-load 邏輯:
|
||
- `kneron_bridge.py:handle_connect()` 已會偵測 Loader mode、從 `firmware/<chip>/fw_scpu.bin + fw_ncpu.bin` load firmware 到 RAM
|
||
- `kneron_bridge.py:handle_connect()` 已處理 KL720 KDP legacy → 強制 load KDP2 firmware 到 RAM
|
||
- `DeviceInfo.FirmwareVer` 已在 driver interface、bridge 連線時也回傳 `firmware` 欄位
|
||
- bundled firmware 已存在 `server/scripts/firmware/{KL520,KL720}/`(合計 ~360KB)
|
||
|
||
缺的是「持久化升降版」:
|
||
- 既有的 `load_firmware_from_file` 是 RAM-load(裝置重新上電就消失)
|
||
- 真正的 FW 升降版需要呼叫 `kp_update_kdp_firmware_from_files`(會寫 flash)
|
||
|
||
## Decision
|
||
|
||
採以下五項決策:
|
||
|
||
### 1. 採方案 A + B、不分階段交付
|
||
|
||
| 階段 | 範圍 | 工時 |
|
||
|-----|------|------|
|
||
| A | KL520 + KL720 自動升級 KDP1 → KDP2、安裝包 +0KB | 5 人天 |
|
||
| B | + KL630 + KL730 driver 擴展 + 手動降版(面向一般使用者)+ 多版本管理、安裝包 +7MB | 10.5 人天 |
|
||
| **合計** | — | **15.5 人天** |
|
||
|
||
不採「先做 A、之後再評估 B」的分階段策略——使用者明確要求一次做完。
|
||
|
||
### 2. 翻案 R5-Q9,範圍切割如下
|
||
|
||
| 「燒 flash」場景 | 本期決策 |
|
||
|-----------------|---------|
|
||
| 使用者按按鈕燒任意 model(NEF)到 device flash | **繼續砍**(R5-Q9 原始決策維持)|
|
||
| 升級到 Kneron 官方 KDP2 標準版本 | **本期做**(範圍切割後翻案)|
|
||
| 手動降版到 bundled 舊版(含 KDP1)| **本期做**(B2 階段、面向一般使用者)|
|
||
| 使用者燒入自編 firmware binary | **不做**(brick 風險過高、責任風險過高)|
|
||
|
||
切割後翻案的核心邏輯:Q9 擔憂的 brick 風險來自「使用者燒任意 binary」、而非「升級到官方標準版本」。本期只暴露「升級到 Kneron 官方 KDP2」+ 「降版到 bundled 已知舊版」、binary 來源已嚴格限制。
|
||
|
||
### 3. 跨平台用 KneronPLUS Python C API
|
||
|
||
| 替代方案 | 否決原因 |
|
||
|---------|---------|
|
||
| DFUT.exe(warrenchen 雲端版用)| Windows-only、~30MB Qt5 binary、跨平台不通 |
|
||
| ctypes 包 KneronPLUS C API | 既有 Python wheel 已包好、不需重做 |
|
||
| 自寫 USB 協議實作 | 範圍過大、需逆向工程 Kneron protocol、Kneron 不認可 |
|
||
|
||
採 KneronPLUS Python API(`kp.core.update_kdp_firmware_from_files`)路徑:
|
||
- 三平台都有 wheel(既有 bundle 已含、增加成本 ~0KB)
|
||
- 對應 C 函式經 SDK 驗證、不踩 brick 風險
|
||
- 與既有 `kp.core.load_firmware_from_file` 路徑共用、bridge.py 改動可控
|
||
|
||
### 4. 多版本目錄結構採選項 C — CURRENT_VERSION metadata
|
||
|
||
```
|
||
firmware/<chip>/
|
||
├── CURRENT_VERSION ← 單行檔:"v2.2.0"
|
||
├── v2.2.0/{...} + VERSION
|
||
├── v2.1.0/{...} + VERSION
|
||
└── kdp1/{...} + VERSION
|
||
```
|
||
|
||
| 替代方案 | 否決原因 |
|
||
|---------|---------|
|
||
| 選項 A — symbolic link(`current/` 指向版本目錄)| Windows symlink 需 admin、`tar` 處理跨 OS 不一致 |
|
||
| 選項 B — 實體副本(`current/` 是 `v2.2.0/` 的 file copy)| 每 chip 多佔一份(合計 +7-8MB 額外)、跨平台簡單但浪費空間 |
|
||
| 選項 C — `CURRENT_VERSION` 單行檔 + 版本目錄並列 | **選此**:架構乾淨、空間最省、跨平台無 symlink 風險、bridge.py 多一次 file read(trivial 成本)|
|
||
|
||
### 5. 保守 bundle 策略 +7MB
|
||
|
||
| Chip | bundled 版本 | 估算 |
|
||
|------|------------|------|
|
||
| KL520 | current + kdp1 + v2.1.0 | ~290KB |
|
||
| KL720 | current + v2.1.0(如有)| ~500KB |
|
||
| KL630 | current + 1 個舊版(如有)+ extracted | ~9MB |
|
||
| KL730 | current + extracted | ~8MB |
|
||
|
||
合計 ~18MB(極大值)。實際採保守策略 = 不一定每個 chip 都 bundle 舊版(KL630/KL730 舊版可能 SDK release 取不到)、估算 +7MB。
|
||
|
||
macOS dmg 從 163MB → ~170MB(+4-5%)、使用者「+5MB 接受」決策對齊。
|
||
|
||
## Consequences
|
||
|
||
### 正面影響
|
||
|
||
1. **解決真實痛點**:拿到舊 KDP1 dongle 完全不能用的情境消除(A 階段)、新世代 dongle KL630/KL730 變可用(B 階段)、進階使用者可手動切版本(B2 階段)
|
||
2. **架構乾淨**:新 `firmware/` 模組與既有 `flash/` 分離、職責清楚、未來擴 KL830 / KL530 有明確 hook 點
|
||
3. **跨平台一致**:三平台同走 KneronPLUS Python API、無 Windows-only 依賴、維護成本均勻
|
||
4. **回溯可追**:本 ADR + 研究檔(research-kl520-fw-management/)+ TDD v2/firmware-management.md 留下完整決策痕跡、未來新人接手不會問「為何 Q9 砍了又做」
|
||
|
||
### 負面影響(接受的取捨)
|
||
|
||
1. **+7MB 安裝包**(B 階段、A 階段 +0KB):macOS dmg 從 163MB → ~170MB、使用者已接受
|
||
2. **Brick 風險未完全消除**:KL720 升級會寫 flash、升級中拔 USB 仍有 brick 可能(緩解:UI 警告、不打包 DFUT 但提供內部 SOP)
|
||
3. **法律 / 簽章授權待釐清**:Kneron firmware redistribution(含 KDP1 / 舊版)需發佈前評估、與 R5-B4 同性質、不阻塞開發但是 PRD P0 懸念
|
||
4. **15.5 人天工時**:比原估 11-12 多 ~30%、主因 B2 階段「面向一般使用者」UX safety net + 多版本管理 + M9-6 SDK 驗證
|
||
5. **B 階段對 KL630/KL730 SDK 行為仍有未知**:M9-6 驗證後可能需要升級 KneronPLUS wheel、有 KL520/KL720 regression 風險
|
||
6. **CURRENT_VERSION 機制需要 A → B2 migration**:A 階段 firmware 檔扁平放、B2 階段才搬進版本目錄、需小心不破壞 A 階段已 commit 路徑
|
||
|
||
### 風險
|
||
|
||
完整風險清單見 `v2/firmware-management.md` §10(R-FW-1 ~ R-FW-12、R-TAR-1 ~ R-TAR-4 合計 16 條)。最關鍵:
|
||
|
||
| # | 風險 | 等級 |
|
||
|---|------|------|
|
||
| R-FW-8 | KneronPLUS SDK 對 KL630/KL730 API 不可預測 | 高 |
|
||
| R-FW-11 | 一般使用者誤觸降版 brick 風險 | 高 |
|
||
| R-FW-1 | 升級中拔除 device(KL720 寫 flash 階段)| 中 |
|
||
|
||
## Alternatives Considered
|
||
|
||
### 替代方案 1:不做 FW 管理
|
||
|
||
| 維度 | 評估 |
|
||
|------|------|
|
||
| 工時 | 0 |
|
||
| 痛點解決 | 不解 |
|
||
| 否決原因 | 痛點 #1(KDP1 dongle 不能用)是真實且高頻場景、使用者明確要求做 |
|
||
|
||
### 替代方案 2:用 DFUT.exe(warrenchen 雲端版方案)
|
||
|
||
| 維度 | 評估 |
|
||
|------|------|
|
||
| 工時 | 較少(直接呼叫 .exe)|
|
||
| 跨平台 | **Windows-only**、macOS / Linux 完全不通 |
|
||
| 安裝包衝擊 | +30MB Qt5 binary |
|
||
| 否決原因 | visionA-local 是三平台 desktop app、Windows-only 工具不接受 |
|
||
|
||
### 替代方案 3:只做內部 dev mode 降版(非面向一般使用者)
|
||
|
||
| 維度 | 評估 |
|
||
|------|------|
|
||
| 工時 | 少(不用做 UX safety net、~12 人天)|
|
||
| 痛點解決 | 痛點 #4(舊 model 相容性)不解、仍需技術支援介入 |
|
||
| 否決原因 | 使用者明確決策(2026-05-24):手動降版面向一般使用者、不只 dev mode |
|
||
|
||
### 替代方案 4:多版本目錄結構選 symlink / 副本
|
||
|
||
| 維度 | 選 A symlink | 選 B 副本 | 選 C metadata(本期選此)|
|
||
|------|-------------|----------|---------------------|
|
||
| 跨平台 | Windows symlink 需 admin、Windows zip/tar 處理 symlink 不一致 | 完美跨平台 | 完美跨平台 |
|
||
| 空間 | 最省 | 每 chip 多一份(+7-8MB)| 最省(只多一個單行檔)|
|
||
| 複雜度 | 高(symlink fall-back 邏輯)| 低 | 低(讀 metadata 一行)|
|
||
|
||
### 替代方案 5:等 A 階段驗證後再評估 B
|
||
|
||
| 維度 | 評估 |
|
||
|------|------|
|
||
| 工時 | A 階段 5 人天先交付 |
|
||
| 風險 | A → B 整合時的 .tar handling / chip 判斷 / multi-version migration 必須重整 A 階段已 commit 程式碼 |
|
||
| 否決原因 | 使用者明確要求一次做完、且 ADR / TDD 一次定稿能避免 A 階段做出不利 B 階段擴展的設計 |
|
||
|
||
## Related
|
||
|
||
| 編號 | 關聯 |
|
||
|------|------|
|
||
| R5-Q9 | 第二輪「韌體燒錄 flash → B 砍掉」、本 ADR 翻案 |
|
||
| R5-B4 | 「Kneron 預置模型 re-distribution 授權」未解決問題、firmware redistribution 同性質、發佈前統一處理 |
|
||
| R5-E | 60s 啟動 hard timeout、FW 升降版不在啟動 pipeline、無關 |
|
||
| 2026-04-21 commit | KL520 reset bug fix、本 ADR 必須維持「升級成功後 needsReset=true」確保不踩 Error 15 |
|
||
| watchServer Error state | `v2/server-lifecycle.md`、FW 升降版失敗不觸發 server Error state |
|
||
| TDD `v2/firmware-management.md` | 本 ADR 對應的 TDD 章節、含完整 API / 流程 / 工時 / 風險 |
|
||
| PRD `02-prd/features/feature-firmware-management.md` v2.2 | 對應 user story(US-FW-1 ~ US-FW-3)與成功指標 |
|
||
| research-kl520-fw-management/ | 本 ADR 的研究依據(含 warrenchen 實作分析、SDK API 落差、.tar handling、降版 UX 需求、M9-6 弱驗證結果)|
|
||
|
||
## Compliance
|
||
|
||
- [x] Architect 與 PM Agent 確認本 ADR 影響業務指標(FW 升級流程是 PRD v2.2 新功能)
|
||
- [x] 成本影響已評估:開發 15.5 人天 + 基礎設施 +7MB 安裝包 + 維運 0(無 OTA 通道、無監控 SaaS 需求)
|
||
- [ ] 與 Kneron 取得 firmware redistribution 授權(發佈前必須完成、不阻塞開發)
|
||
- [ ] Design Agent 確認 UX 多層 safety net 落地(二次確認 modal + DOWNGRADE 輸入 + persistent banner)
|
||
|
||
## 變更記錄
|
||
|
||
| 日期 | 版本 | 變更 | 作者 |
|
||
|------|------|------|------|
|
||
| 2026-05-24 | 1.0 | 初版產出、Status: Accepted | Architect Agent |
|
||
| 2026-05-25 | 1.1 | 三方互審後修:(1) Status 區塊加 2026-05-25 update 反映 M9-6 弱驗證新事實(wheel 三平台版本不一致 + AC-FW-3.5 延後 B 階段);(2) Context R5-Q9 行號改為描述式引用(不寫具體 L 行號);(3) Related 表補 PRD v2.2 條目;(4) 不改 Decision/Alternatives/Compliance 主體(決策邏輯沒變、仍 Accepted) | Architect Agent |
|