jim800121chen 46514d77d7 docs(local-tool): M9 — Kneron Dongle FW 偵測 + 升降版(A+B、翻案 R5-Q9)
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>
2026-05-25 07:40:56 +08:00

426 lines
22 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.

# M9-6 強驗證結果(本機 macOS、35 分鐘)
> 對應 `50-m9-6-sdk-validation.md` 驗證 A-2 與 C-1
> 補充 `55-m9-6-weak-validation-result.md` 留下的 unknown
> 執行日期2026-05-25
> 執行者Backend Agent
> 平台macOS單機驗證、無 KL630/KL730 實機 dongle
---
## 環境
- **OS**macOSDarwin
- **Python**`Python 3.14.3`system / venv-less
- **本機已找到的 wheel**
- macOS`vendor/wheels/darwin/KneronPLUS-2.0.0-py3-none-any.whl`
- Linux`vendor/wheels/linux/KneronPLUS-2.0.0-py3-none-any.whl`
- Windows`vendor/wheels/windows/KneronPLUS-3.1.2-py3-none-any.whl`
- **驗證方式**:解壓 wheel 到 `/tmp/kp-<platform>-<version>/`、直接 `PYTHONPATH=... python3` import 或 `grep` source code
- **限制**:沒有實機 KL630/KL730 dongle、無法跑 `scan_devices()` / `connect_devices()` 驗證 USB 連線層行為
- **驗證範圍**A-2KL630/KL730 enum 在三個版本 wheel 內的存在性)+ C-1.tar 內容檢查)+ 順手延伸到 firmware API 表面對齊
---
## 驗證 A-2 結果KL630/KL730 enum
### A-2.1 macOS 2.0.0 wheel — `import kp` 實測
**指令**
```bash
mkdir -p /tmp/kp-darwin-2.0.0 && \
python3 -m pip install --target=/tmp/kp-darwin-2.0.0 \
/Users/jimchen/visionA/local-tool/vendor/wheels/darwin/KneronPLUS-2.0.0-py3-none-any.whl --quiet
PYTHONPATH=/tmp/kp-darwin-2.0.0 python3 -c "import kp; ..."
```
**完整輸出**(節錄關鍵段、過濾 IntEnum 內建屬性):
```
=== kp module loaded ===
kp.__version__: N/A
kp file: /tmp/kp-darwin-2.0.0/kp/__init__.py
=== ProductId enum (all) ===
KP_DEVICE_KL520 = 256 (type: ProductId)
KP_DEVICE_KL720 = 1824 (type: ProductId)
KP_DEVICE_KL720_LEGACY = 512 (type: ProductId)
```
**KPEnum.py source 直接證實**
```python
class ProductId(IntEnum):
KP_DEVICE_KL520 = 0x100
KP_DEVICE_KL720 = 0x720
KP_DEVICE_KL720_LEGACY = 0x200
```
**結論**
-`KP_DEVICE_KL630` **不存在**
-`KP_DEVICE_KL730` **不存在**
-`KP_DEVICE_KL520` / `KP_DEVICE_KL720` / `KP_DEVICE_KL720_LEGACY` 存在
### A-2.2 Linux 2.0.0 wheel — source grep檔案結構與 macOS 一致、跳過 import
```bash
$ grep -n "KP_DEVICE_KL" /tmp/kp-linux-2.0.0/kp/KPEnum.py
14: KP_DEVICE_KL520 : int, default=0x100
16: KP_DEVICE_KL720 : int, default=0x720
18: KP_DEVICE_KL720_LEGACY : int, default=0x200
21: KP_DEVICE_KL520 = 0x100
22: KP_DEVICE_KL720 = 0x720
23: KP_DEVICE_KL720_LEGACY = 0x200
```
**結論**:與 macOS 2.0.0 完全一致——只有 3 個 enum、無 KL630/KL730。
### A-2.3 Windows 3.1.2 wheel — source grepwheel 內 .dll 在 macOS 無法 import、但 source 可讀)
```bash
$ grep -n "KP_DEVICE_KL\|KL630\|KL730\|KL830" /tmp/kp-windows-3.1.2/kp/KPEnum.py
20: KP_DEVICE_KL530 : int, default=0x530
22: KP_DEVICE_KL830 : int, default=0x832
24: KP_DEVICE_KL730 : int, default=0x732
26: KP_DEVICE_KL630 : int, default=0x630
28: KP_DEVICE_KL540 : int, default=0x540
31: KP_DEVICE_KL520 = 0x100
32: KP_DEVICE_KL720 = 0x720
33: KP_DEVICE_KL720_LEGACY = 0x200
34: KP_DEVICE_KL530 = 0x530
35: KP_DEVICE_KL830 = 0x832
36: KP_DEVICE_KL730 = 0x732
37: KP_DEVICE_KL630 = 0x630
38: KP_DEVICE_KL540 = 0x540
```
**結論**3.1.2 完整支援 KL520 / KL530 / KL540 / KL630 / **KL730 (0x732)** / KL830 / KL720 / KL720_LEGACY。
### A-2 整體結論
| Wheel | KL520 | KL720 | KL720_LEGACY | KL630 | KL730 | KL530/KL540/KL830 |
|-------|:-:|:-:|:-:|:-:|:-:|:-:|
| **macOS 2.0.0** | ✅ 0x100 | ✅ 0x720 | ✅ 0x200 | ❌ | ❌ | ❌ |
| **Linux 2.0.0** | ✅ 0x100 | ✅ 0x720 | ✅ 0x200 | ❌ | ❌ | ❌ |
| **Windows 3.1.2** | ✅ 0x100 | ✅ 0x720 | ✅ 0x200 | ✅ 0x630 | ✅ **0x732** | ✅ |
### A-2 影響
**1. KL730 product_id 修正(重要新事實)**
- 弱驗證 §「Unknown 對照表 B-1」與 `40-b-phase` §2.1 都假設 KL730 product_id = `0x0730`
- **實測 SDK enumKL730 = `0x732`**(不是 0x730
- KL630 = `0x630`(與弱驗證假設一致)
- 對 driver `_KNOWN_PRODUCTS` map 影響KL730 entry 要改 `0x732`、舊 `0x0730` 假設是錯的
**2. wheel 升級決策(高優先)**
- macOS + Linux 在 2.0.0 都**沒有** KL630/KL730 enum、`import kp; kp.ProductId.KP_DEVICE_KL630` 直接 `AttributeError`
- → A 階段若要做 KL630/KL730 任何事(即使只是 scan/connect、macOS/Linux **必須升 wheel 到 3.1.2**
- → A 階段若維持「只支援 KL520+KL720 不升 wheel」可保持 2.0.0、但 PRD AC-FW-3.5KL630/KL730必須延後到 B 階段
- 弱驗證的「強驗證必跑 → 確認 2.0.0 enum」這個 unknown **本次已解****沒有、必須升 wheel**
**3. PRD AC-FW-3.5 結論進一步收緊**
- 弱驗證建議「AC-FW-3.5 延後到 B 階段」**保持有效**、強驗證確認此判斷正確
- 新增理由「macOS/Linux 2.0.0 wheel 連 enum 都沒有、A 階段做不到」(不只是「沒 reference 實作」)
---
## 驗證 C-1 結果:.tar 內容
### C-1.1 KL630/kp_firmware.tar
```bash
$ ls -la /tmp/web_academy_prototype/local_service_win/firmware/KL630/
-rw-r--r-- 1 jimchen wheel 11 May 24 12:57 VERSION
-rw-r--r-- 1 jimchen wheel 6041600 May 24 12:57 kp_firmware.tar (~5.8 MB)
-rw-r--r-- 1 jimchen wheel 542720 May 24 12:57 kp_loader.tar (~530 KB)
$ cat /tmp/web_academy_prototype/local_service_win/firmware/KL630/VERSION
SDK-v2.5.7
```
**`tar -tvf KL630/kp_firmware.tar`**(節錄):
```
drwxrwxr-x kp_firmware/
-rw-rw-r-- kp_firmware/VERSION (10 bytes)
drwxrwxr-x kp_firmware/bin/
-rw-r--r-- kp_firmware/bin/gt.conf (350 bytes)
-rwxrwxr-x kp_firmware/bin/kp_firmware (22,736 bytes、ELF binary)
-rw-r--r-- kp_firmware/bin/gt (192,228 bytes)
drwxrwxr-x kp_firmware/lib/
-rw-r--r-- kp_firmware/lib/libvmf.so.3.16.0.0 (2,668,076 bytes)
-rw-r--r-- kp_firmware/lib/libvmf_vdec.so.1.0.0.1 (624,048 bytes)
-rw-r--r-- kp_firmware/lib/libfreetype.so.6.13.0 (520,144 bytes)
-rw-r--r-- kp_firmware/lib/libusb-1.0.so.0.3.0 (367,068 bytes)
-rw-r--r-- kp_firmware/lib/libkplus.so.2.1.1.0 (185,488 bytes)
-rw-r--r-- kp_firmware/lib/libusbgx.so.2.0.0 (152,276 bytes)
-rw-r--r-- kp_firmware/lib/librtspsrvr.so.9.2.0.3 (147,764 bytes)
-rw-r--r-- kp_firmware/lib/libconfig.so.9.2.0 (119,836 bytes)
-rw-r--r-- kp_firmware/lib/libvmf_nn.so.2.1.1.1 (201,408 bytes)
-rw-r--r-- kp_firmware/lib/libvmf_nnm.so.1.3.0.0 (114,280 bytes)
... 共 ~80 個檔案、含大量 .so / .a / symlinks
```
**`tar -tvf KL630/kp_loader.tar`**
```
drwxrwxr-x kp_loader/
-rw-r--r-- kp_loader/VERSION
drwxrwxr-x kp_loader/bin/
-rw-r--r-- kp_loader/bin/gt.conf
-rw-r--r-- kp_loader/bin/gt
-rwxrwxr-x kp_loader/bin/kp_loader (20,852 bytes、ELF binary)
drwxrwxr-x kp_loader/lib/
-rw-r--r-- kp_loader/lib/libusbgx.so.2.0.0
-rw-r--r-- kp_loader/lib/libkutils.so.1.0.0.0
-rw-r--r-- kp_loader/lib/libconfig.so.9.2.0
-rw-r--r-- kp_loader/lib/libaio.so.1.0.2
... 共 ~15 個檔案、純粹是精簡 runtime 環境
```
### C-1.2 KL730/kp_firmware.tar
```bash
$ ls -la /tmp/web_academy_prototype/local_service_win/firmware/KL730/
-rw-r--r-- VERSION (11 bytes)
-rw-r--r-- kp_firmware.tar (33,710,080 bytes ≈ 32 MB)
-rw-r--r-- kp_loader.tar (20,295,680 bytes ≈ 19 MB)
$ cat KL730/VERSION
SDK-v1.3.0
```
**`tar -tvf KL730/kp_firmware.tar`**(節錄):
```
drwxrwxr-x kp_firmware/
-rw-rw-r-- kp_firmware/VERSION
drwxrwxr-x kp_firmware/bin/
-rwxrwxr-x kp_firmware/bin/kp_firmware (39,256 bytes、ELF binary)
-rw-r--r-- kp_firmware/bin/gt (224,216 bytes)
drwxrwxr-x kp_firmware/lib/
-rw-r--r-- kp_firmware/lib/lib3a.so.1.3.0.0 (13,941,696 bytes !!!)
-rw-r--r-- kp_firmware/lib/libsqlite3.so.0.8.6 (6,137,248 bytes)
-rw-r--r-- kp_firmware/lib/libvmf.so.1.3.0.0 (3,199,008 bytes)
-rw-r--r-- kp_firmware/lib/libcrypto.so.1.1 (3,036,328 bytes)
-rw-r--r-- kp_firmware/lib/libvdec.so.0.0.0.1 (1,448,128 bytes)
-rw-r--r-- kp_firmware/lib/libcva.so.0.0.0.2 (1,032,584 bytes)
-rw-r--r-- kp_firmware/lib/libfreetype.so.6.13.0 (1,047,856 bytes)
-rw-r--r-- kp_firmware/lib/libvmf_nnm.so.1.3.0.3 (825,344 bytes)
-rw-r--r-- kp_firmware/lib/libssl.so.1.1 (679,192 bytes)
... 含 RTSP / SSL / SQLite / Video Codec / 3A / Thermal / Free type 等
```
**`tar -tvf KL730/kp_loader.tar`**
```
drwxrwxr-x kp_loader/
-rwxrwxr-x kp_loader/bin/kp_loader (34,848 bytes、ELF)
drwxrwxr-x kp_loader/lib/
-rw-rw-r-- kp_loader/lib/lib3a.so.1.3.0.0 (13,941,696 bytes) -- 同上、為何 loader 也帶 13 MB 的 ISP lib
-rw-rw-r-- kp_loader/lib/libcva.so.0.0.0.2 (1,032,584 bytes)
... 約 20 個 .so 檔案、含 ISP / video / freetype / thermal
```
### C-1 結論(重大發現)
**1. .tar 內容**不是**前兩輪研究假設的 `fw_scpu.bin` + `fw_ncpu.bin`**
| 假設(弱驗證 §「Unknown 對照表 C-1」 | 實測 |
|---------------------------------------|------|
| .tar 內含 `fw_scpu.bin` + `fw_ncpu.bin` | ❌ 完全沒有 .bin |
| 可能有 manifest.json / metadata | ❌ 只有純 `VERSION` 字串檔10 bytes、無 manifest |
| 解壓後拿 .bin 路徑餵 SDK | ❌ 沒 .bin 可拿 |
**2. .tar 實際內容是「Linux user-space root filesystem」**
- 一個 ELF binary`kp_firmware``kp_loader`、ARM 架構推測)
- 一堆 shared libraries`.so` + symlinks
- 一個 `gt`(推測是 gateway / debug tool
- 一個 `gt.conf` 配置檔
**3. 對 KL630/KL730 firmware 模型的影響(推論、待 B 階段實機 confirm**
KL520/KL720 模型(既有 visionA-local 認知):
- chip 上跑 **bare-metal / RTOS** firmware
- firmware = 兩個獨立 .binSCPU + NCPU寫 flash 或 RAM-load
- SDK API`load_firmware_from_file(dg, scpu.bin, ncpu.bin)` / `_update_kdp2_firmware_from_files(dg, scpu, ncpu)`
KL630/KL730 模型(從 .tar 內容推論):
- chip 上跑 **完整 Linux**embedded distro
- firmware = root filesystemELF binary + .so libraries + config
- SDK API 應該是**完全不同的機制**——大概率走 USB Mass Storage / NFS boot / file transfer protocol、把整個 rootfs 推上去
- **KneronPLUS 3.1.2 wheel 沒有對應的 .tar firmware update Python API**grep 確認、見下節「附帶發現 1」
**4. 對策略 Y vs Z 的影響**
弱驗證結論:「策略 Z.tar 直接餵 SDK不可行、必走策略 Ybuild time 解壓拿 .bin
**強驗證更新**
- 策略 Z 不可行 ✅ 仍正確
- **策略 Y 不可行 ❌**(沒 .bin 可拿、解壓後是 Linux rootfs、不是兩個 .bin
- → 必須有**策略 X新方案**
- **X.1**:把整個 `kp_firmware.tar` 當不透明 blob 處理、找新 SDK API可能在 3.1.2 wheel 內有 KL630/KL730 專用、或在更新 wheel 版本)
- **X.2**:把 .tar 內某個檔案(`kp_firmware` ELF當「主 firmware」、可能對應 SDK 內部 KDP3 / KDP4 流程
- **X.3**:完全跳過 SDK API、用 USB Mass Storage 自己寫 rootfs最後手段
- **這個發現直接推翻 `41-tar-firmware-handling.md` 的策略 Y 設計、`_resolve_firmware_paths``extracted/fw_scpu.bin` 路徑**——該路徑根本不存在
**5. KL720 KDP2 vs KL630/KL730 模型差異**
- KL720 KDP2仍是 SCPU+NCPU 兩個 .bin、寫 flash 一次後 product_id 從 0x0200 → 0x0720
- KL630/KL730是「載入 Linux rootfs」、與 KL720 KDP2 模型完全不同代
---
## 附帶發現(順手讀 wheel source 得到)
### 附帶 1KneronPLUS 3.1.2 Python 層**沒有** `update_kdp_firmware_from_files`(弱驗證需要修正)
**弱驗證「發現 2」結論**:「`update_kdp_firmware_from_files` API 在 KneronPLUS 3.1.2 存在且 warrenchen 已使用」
**強驗證更正**
`grep -n "update_kdp" /tmp/kp-windows-3.1.2/kp/KPCore.py`
```
584: def _update_kdp2_firmware(...)
625: def _update_kdp2_firmware_from_file(...)
661: def _update_kdp2_usb_loader(...)
696: def _update_kdp2_usb_loader_from_file(...)
```
`grep -n "kp_update_kdp" /tmp/kp-windows-3.1.2/kp/KPWrapper.py`
```
55: self.__init_kp_update_kdp2_firmware()
56: self.__init_kp_update_kdp2_firmware_from_files()
57: self.__init_kp_update_kdp2_usb_loader()
58: self.__init_kp_update_kdp2_usb_loader_from_file()
```
**事實**
- Python wrapper 層只有 `_update_kdp2_*`**單底線 prefix、表示 advance / non-public** API
- **沒有** `update_kdp_firmware_from_files`(即弱驗證 §「發現 2」描述的 KDP1 → KDP2 升版 API
- warrenchen 用的 `lib.kp_update_kdp_firmware_from_files` 是**直接 ctypes binding 到 .so/.dll 的 C symbol**、繞過 Python wrapper
- 該 C symbol **可能**存在於 SDK .so/.dll 內、但 Python 層**沒對外 export**——意味我們要嘛走 ctypes、要嘛找替代方案
**對 PRD AC-FW-3.1KL720 KDP1 → KDP2 flash 升版)影響**
- 既有 visionA-local 用 `kp.core.load_firmware_from_file`RAM-based— ✅ Python wrapper 都有、跨版本相容
- 若要走 warrenchen 模式做 **flash-based** 升版:必須用 ctypes 直接打 `lib.kp_update_kdp_firmware_from_files`、Python wrapper 沒這個函式
- 這個事實在 TDD 設計 KL720 flash-based 升版時要明示「走 ctypes、不走 Python wrapper」
### 附帶 2`load_firmware_from_file` 簽名跨版本一致
`load_firmware_from_file(device_group, scpu_fw_path, ncpu_fw_path)` 在 2.0.0 與 3.1.2 都是兩個 `str` path 參數、簽名相容、無 .tar 支援、與弱驗證結論一致。
### 附帶 3KneronPLUS 3.1.2 也**沒有任何 .tar 介面 API**
grep 全 wheel
```bash
$ grep -rn "load_firmware_from_tar\|kp_update_kdp.*tar\|tar_path\|from_tar" /tmp/kp-windows-3.1.2/kp/
(no result)
```
完全沒有 .tar 相關 Python API。意味
- KL630/KL730 的 `kp_firmware.tar` 在 KneronPLUS 3.1.2 Python 層**沒有對應 API**
- 推測:要嘛 .tar 是給 SDK 內部的 `legacy_plus121_runner` 之類 helper script 用、要嘛要更新版 wheel、要嘛要走 ctypes
- 這個發現解釋了**為什麼 warrenchen 完全沒有 KL630/KL730 endpoint**——SDK Python 層沒給可用 API
---
## 對 PRD / TDD 的影響
### 立即可修(強驗證結果確認、不需更多實機)
| 文件 | 章節 | 修改內容 |
|------|------|---------|
| `04-architecture/v2/firmware-management.md` | KL730 product_id | 從 `0x0730` 改為 `0x732`SDK enum 實測值) |
| `04-architecture/v2/firmware-management.md` | `_resolve_firmware_paths` | **整段重寫**——.tar 不是兩個 .bin、是 Linux rootfs、沒法走「解壓拿 .bin」路徑 |
| `04-architecture/v2/firmware-management.md` | .tar 處理策略 | 標策略 Y **同樣不可行**、留 placeholder「KL630/KL730 firmware 處理需 M9-9 強驗證才能定案」 |
| `04-architecture/v2/firmware-management.md` | KneronPLUS wheel 升級 | macOS/Linux 2.0.0 確認**無** KL630/KL730 enum、A 階段做 KL630/KL730 必先升 wheel |
| `04-architecture/v2/firmware-management.md` | KL720 KDP1→KDP2 flash 升版 | 標「需走 ctypes 直接打 `lib.kp_update_kdp_firmware_from_files`、Python wrapper 無對應」 |
| `04-architecture/research-kl520-fw-management/41-tar-firmware-handling.md` | §1.3 / §4.4 | **整段重寫**——.tar 是 Linux rootfs、策略 Y 不可行、需新策略 XB 階段定) |
| `04-architecture/research-kl520-fw-management/40-b-phase-kl630-kl730-extension.md` | §2.1 | KL730 product_id 改 `0x732` |
| `04-architecture/research-kl520-fw-management/40-b-phase-kl630-kl730-extension.md` | §3.2 表格 | 填入「A-2 強驗證結果」columnmacOS/Linux 2.0.0 無 enum |
| `04-architecture/research-kl520-fw-management/40-b-phase-kl630-kl730-extension.md` | §5.2 推測「flash-based」 | 改為「embedded Linux rootfs 模型、與 KL520/KL720 不同代」 |
| `04-architecture/research-kl520-fw-management/50-m9-6-sdk-validation.md` | §8.1 A-1/A-2 | 填本檔結果 |
| `04-architecture/research-kl520-fw-management/50-m9-6-sdk-validation.md` | §8.3 C-1 | 填本檔結果 |
| `04-architecture/research-kl520-fw-management/55-m9-6-weak-validation-result.md` | 「結論 2」與「發現 2」 | 標註「update_kdp_firmware_from_files Python wrapper 不存在、僅 C symbol、走 ctypes」 |
| `04-architecture/research-kl520-fw-management/55-m9-6-weak-validation-result.md` | 「結論 4 / 5」 | 標註「策略 Y 同樣不可行、.tar 是 Linux rootfs、需新策略 X」 |
| `02-prd/features/feature-firmware-management.md` | AC-FW-3.5 | 強化「延後到 B 階段」決定、附本檔事實macOS/Linux 2.0.0 enum 不存在、.tar 模型完全不同代)|
### 仍需強驗證的剩餘項目M9-9 起跑前必跑)
| # | 項目 | 阻塞 |
|---|------|------|
| **B-1**(更新) | KL730 product_id = `0x732` 假設用實機 confirmSDK enum 寫 0x732、但實機回什麼仍要驗| M9-9 啟動 |
| **B-2** | KL630/KL730 是否每次 connect 都要 load firmwareembedded Linux 模型下可能完全不需要 load | M9-9 |
| **B-3** | KL630/KL730 firmware 字串可能值 | M9-9 |
| **A-3 / A-4** | 找 KL630/KL730 firmware update 對應的 SDK API可能在 KP 3.1.2+ 有 KDP3 / KDP4 / Linux loader 之類專用、或要更新 wheel| M9-10 啟動 |
| **A-5** | `_update_kdp2_firmware_from_file` 是否對 KL630/KL730 適用、或要走完全不同 API | M9-10 |
| **A-6** | wheel 2.0.0 → 3.1.2 升級對 KL520+KL720 regression | M9-13 |
### A 階段是否阻塞?
**結論****不阻塞 A 階段**A 階段範圍 = KL520+KL720
- A 階段 wheel 維持 macOS/Linux 2.0.0、Windows 3.1.2 三平台不一致現狀
- KL520+KL720 在所有平台都有對應 enum、A 階段所需 APIload_firmware_from_file跨版本相容
- 弱驗證的「KL520+KL720 既有 bridge.py 用的 API subset 在 2.0.0 和 3.1.2 都存在」結論 ✅ 仍有效
- AC-FW-3.5KL630/KL730 升降版)確定延後到 B 階段、A 階段不開
### B 階段 milestone 影響vs 弱驗證評估)
| Milestone | 弱驗證評估 | 強驗證更新 |
|-----------|----------|----------|
| **M9-7B0 認 chip** | 低風險 | **中風險**:需處理 KL730 = 0x732不是 0x0730A 階段 driver `_KNOWN_PRODUCTS` map 維持假設可、但 B 階段必修 |
| **M9-8.tar handling** | 高:策略 Y vs Z | **更高**:策略 Y 也不可行、需 spike 找新 API、工時可能 1 → 2-3 人天 |
| **M9-9connect + inference** | 中B-1/B-2/B-3 | **高**embedded Linux 模型可能改變整個 connect 流程設計 |
| **M9-10FW 升降版擴 KL630/KL730** | 中A-5 | **可能 N/A**:若沒對應 SDK API、整段降為「不支援 KL630/KL730 升降版」、或要找替代方案(如系統廠工具) |
---
## Verification自檢
- ✅ wheel 路徑與版本不是猜——`find` 確認、`vendor/wheels/<platform>/` 結構與 `visiona-local/wheels/<platform>/` 一致、皆找到實檔
- ✅ A-2 enum 實際執行 `python3 -c "import kp; ..."`macOS+ `grep KPEnum.py`Linux/Windows、不是查 doc
- ✅ C-1 用 `tar -tvf` 實際看檔案清單與 byte size、不是看 wheel 文件
- ✅ 附帶 1update_kdp Python wrapper 不存在)用 `grep KPCore.py + KPWrapper.py` 兩處驗證、不是猜
- ✅ KL730 product_id 修正0x730 → 0x732三個來源弱驗證的 `40-b-phase` §2.1 假設、本次 wheel grep、Windows 3.1.2 KPEnum.py 註解)三方對比、明確
- ⚠️ 沒實機 KL630/KL730 dongle、B-1 / B-2 / B-3 連線層行為仍未驗(與計畫一致、本次不在範圍)
---
## 結論摘要
**A-2 強驗證**
- macOS/Linux 2.0.0 wheel **無** KL630/KL730 enum
- Windows 3.1.2 wheel **有**、且 KL730 product_id = **0x732**(非 0x0730
- → wheel 三平台不一致、A 階段做 KL520+KL720 不阻塞B 階段做 KL630/KL730 macOS/Linux 必先升 wheel
**C-1 強驗證**
- KL630/KL730 .tar 是 **Linux rootfs**ELF binary + .so + 配置)、**不是 SCPU+NCPU 兩個 .bin**
- → 弱驗證的「策略 Y解壓後拿 .bin」**不可行**、TDD §41 需重寫
- → KL630/KL730 firmware update 機制與 KL520/KL720 **是不同代設計**、需找新 SDK API
**附帶**
- KneronPLUS 3.1.2 Python wrapper **無** `update_kdp_firmware_from_files`KDP1 升版)、只有 `_update_kdp2_*` 私有 API
- KneronPLUS 3.1.2 Python wrapper **無**任何 .tar 介面 API
- → KL720 KDP1→KDP2 flash 升版若要走 warrenchen 模式必須用 ctypes不能走 Python wrapper
**對 M9-6 弱驗證 unknown 解決度**
| 弱驗證標的 unknown | 強驗證解開? |
|-------------------|-----------|
| 2.0.0 wheel 是否有 KL630/KL730 enum | ✅ 確認**沒有** |
| `update_kdp_firmware_from_files` 對 KL630/KL730 適用性 | ⚠️ 部分——Python wrapper 不存在、要嘛走 ctypes 要嘛找新 API、實機 confirm 仍需 |
| .tar 內容 | ✅ 確認**是 Linux rootfs、不是兩個 .bin** |
| B-1KL630/KL730 product_id 是 0x630 / 0x730| ⚠️ KL630=0x630 SDK enum 證實、KL730 SDK enum = 0x732修正假設、實機回什麼仍需驗 |
**B 階段啟動的新風險**:原本以為策略 Y 解、實際是「整個 firmware 模型不同代、需要 spike」、B 階段工時可能 +2-3 人天。
---
## 與其他研究檔的關係
| 連結 | 引用內容 |
|------|---------|
| `50-m9-6-sdk-validation.md` §2 A-2 + C-1 | 本檔 §「驗證 A-2 結果」+「驗證 C-1 結果」回填 |
| `50-m9-6-sdk-validation.md` §8.1 / §8.3 | 本檔結果應回填到該檔 §8.1A 類)+ §8.3C 類) |
| `55-m9-6-weak-validation-result.md` 「Unknown 對照表」A-2/C-1 | 本檔解開 |
| `55-m9-6-weak-validation-result.md` 「重大發現 5」/「Unknown A-3/A-4」 | 本檔附帶 1 修正Python wrapper 無 KDP1 update API |
| `55-m9-6-weak-validation-result.md` 「結論 4 / 5」 | 本檔 §「C-1 結論」推翻(策略 Y 不可行) |
| `40-b-phase-kl630-kl730-extension.md` §2.1 | 本檔修正 KL730 product_id = 0x732 |
| `40-b-phase-kl630-kl730-extension.md` §5.2 | 本檔修正 KL630/KL730 是 embedded Linux 模型、與 KL520/KL720 不同代 |
| `41-tar-firmware-handling.md` 全文 | 本檔 §「C-1 結論」推翻策略 Y、需重寫 |
| `02-prd/features/feature-firmware-management.md` AC-FW-3.5 | 本檔強化「延後到 B 階段」決定 |