From 3f02435414a175f8e8245a6048026ea07862ebf9 Mon Sep 17 00:00:00 2001 From: jim800121chen Date: Sat, 28 Feb 2026 04:52:22 +0800 Subject: [PATCH] docs: add F18 KL520 hardware integration specs to PRD + TDD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PRD v2.5: - Add F18: Kneron KL520 hardware communication integration - USB Boot mode with auto firmware loading - JSON-RPC bridge architecture (Go → Python → SDK → USB) - Tiny YOLO v3 inference verified (~25ms latency) - COCO 80-class detection with NMS post-processing TDD v1.4: - Update 5.2: Replace placeholder driver with actual implementation - KL720Driver with JSON-RPC over stdin/stdout - Python bridge command protocol table - KL520 USB Boot connection flow - Add 8.5.13: KL520 technical mapping with architecture diagram, inference pipeline code, YOLO post-processing specs, Apple Silicon compatibility notes, and verified detection results - Update 11.5: Add firmware files, kp module, and scripts directory structure - Update directory structure to match actual driver files Co-Authored-By: Claude Opus 4.6 --- docs/PRD-Integrated.md | 21 ++++- docs/TDD.md | 189 ++++++++++++++++++++++++++++++++--------- 2 files changed, 169 insertions(+), 41 deletions(-) diff --git a/docs/PRD-Integrated.md b/docs/PRD-Integrated.md index de291ec..5672c03 100644 --- a/docs/PRD-Integrated.md +++ b/docs/PRD-Integrated.md @@ -8,8 +8,8 @@ |------|------| | 文件名稱 | 邊緣 AI 開發平台 PRD | | 產品名稱 | (暫未定名,以下稱「本平台」) | -| 版本 | v2.3 | -| 日期 | 2026-02-24 | +| 版本 | v2.5 | +| 日期 | 2026-02-28 | | 狀態 | 更新中 | --- @@ -1224,6 +1224,23 @@ Kneron Dongle Arduino 開發板 非 Kneron 晶片 | **解除安裝** | macOS: .app 內含解除安裝選項、Windows: 控制台「新增或移除程式」標準流程 | | **狀態** | 規劃中,待 CLI 安裝穩定後實作 | +#### F18 — Kneron KL520 硬體通訊整合 + +| 項目 | 規格 | +|------|------| +| **概述** | KL520 USB Dongle 的完整通訊管線已驗證,涵蓋 USB 偵測、韌體載入、模型載入、即時推論與結果後處理 | +| **支援裝置** | Kneron KL520 (VID 0x3231, PID 0x0100),USB 2.0 High-Speed | +| **USB Boot 模式** | KL520 無板載 Flash 韌體,每次連線時 host 自動上傳 fw_scpu.bin + fw_ncpu.bin | +| **SDK** | Kneron PLUS SDK v3.1.2,從 C 原始碼編譯為 macOS dylib(Apple Silicon 透過 Rosetta 2 執行) | +| **通訊架構** | Go Server → JSON-RPC (stdin/stdout) → Python Bridge (`kneron_bridge.py`) → Kneron PLUS SDK (kp) → USB → KL520 | +| **支援模型** | Kneron NEF 格式,已驗證 Tiny YOLO v3 (model_id=19, 輸入 224×224, COCO 80 類) | +| **推論延遲** | ~25ms(KL520 NPU 硬體推論,不含圖片前處理與網路傳輸) | +| **後處理** | YOLO v3 雙尺度偵測 (7×7 + 14×14)、Sigmoid 解碼、信心門檻過濾 (≥0.25)、NMS (IoU 0.45) | +| **輸出格式** | 統一 `InferenceResult` JSON:taskType、latencyMs、detections[{label, confidence, bbox{x,y,width,height}}] | +| **Python Bridge 指令** | `scan`(裝置掃描)、`connect`(連線+自動韌體載入)、`load_model`(NEF 模型載入)、`inference`(base64 圖片推論)、`disconnect` | +| **圖片前處理** | OpenCV 解碼 → BGR565 轉換 → KP_IMAGE_FORMAT_RGB565,支援 JPEG/PNG/BMP | +| **驗證結果** | 街道場景圖片偵測到 8 個物件(person ×2、car ×5、bicycle ×1),結果正確 | + --- ## B5. 功能路線圖(Post-MVP) diff --git a/docs/TDD.md b/docs/TDD.md index ea7c7c6..a2773e9 100644 --- a/docs/TDD.md +++ b/docs/TDD.md @@ -7,9 +7,9 @@ | 項目 | 內容 | |------|------| | 文件名稱 | 邊緣 AI 開發平台 TDD | -| 對應 PRD | PRD-Integrated.md v2.2 | -| 版本 | v1.2 | -| 日期 | 2026-02-24 | +| 對應 PRD | PRD-Integrated.md v2.5 | +| 版本 | v1.4 | +| 日期 | 2026-02-28 | | 狀態 | 更新中 | --- @@ -496,9 +496,8 @@ server/ │ ├── driver/ # 裝置驅動層 │ │ ├── interface.go # DeviceDriver 介面定義 │ │ ├── kneron/ -│ │ │ ├── kl720_driver.go # KL720 Dongle 驅動 (MVP) -│ │ │ ├── kl730_driver.go # KL730 / KNEO Pi 驅動 (Phase 1) -│ │ │ └── kneron_sdk.go # Kneron PLUS SDK 封裝 +│ │ │ ├── kl720_driver.go # Kneron Driver (KL520/KL720, JSON-RPC → Python bridge) +│ │ │ └── detector.go # USB 裝置偵測 (透過 Python bridge scan) │ │ └── mock/ │ │ └── mock_driver.go # 模擬驅動 (開發/測試用) │ │ @@ -1201,48 +1200,65 @@ type BBox struct { } ``` -### 5.2 Kneron KL720 Driver 實作策略 +### 5.2 Kneron Driver 實作策略(已實作) + +Go Driver 透過 Python subprocess(`kneron_bridge.py`)與 Kneron PLUS SDK 通訊,採用 JSON-RPC over stdin/stdout 模式。 + +``` +Go Server ──stdin/stdout──► kneron_bridge.py ──ctypes──► libkplus.dylib ──USB──► KL520 + JSON-RPC kp module BULK EP +``` ```go // internal/driver/kneron/kl720_driver.go type KL720Driver struct { - info DeviceInfo - sdk *KneronSDK // Kneron PLUS SDK 封裝 - connected bool - inferring bool - mu sync.Mutex + info driver.DeviceInfo + connected bool + inferring bool + modelLoaded string + mu sync.Mutex + scriptPath string // kneron_bridge.py 路徑 + pythonCmd *exec.Cmd // Python 子進程 + stdin io.WriteCloser // JSON 指令輸入 + stdout *bufio.Scanner // JSON 回應輸出 + pythonReady bool } -// USB 裝置識別 -var KL720USBFilter = USBFilter{ - VendorID: 0x3231, // Kneron VID (需確認實際值) - ProductID: 0x0200, // KL720 PID (需確認實際值) -} +// USB 裝置識別(已確認實際值) +const KneronVendorID uint16 = 0x3231 +// KL520 PID = 0x0100, KL720 PID = 0x0200 -func (d *KL720Driver) Connect() error { - d.mu.Lock() - defer d.mu.Unlock() +// Python venv 自動偵測:scripts/venv/bin/python3 → 系統 python3 +func (d *KL720Driver) resolvePython() string { ... } - // 1. 透過 Kneron PLUS SDK 初始化裝置 - // 2. 取得裝置資訊 (kp_get_system_info) - // 3. 設定連線狀態 - return d.sdk.Connect(d.info.Port) -} +// 啟動 Python bridge,設定 DYLD_LIBRARY_PATH,等待 {"status":"ready"} +func (d *KL720Driver) startPython() error { ... } -func (d *KL720Driver) Flash(modelPath string, progressCh chan<- FlashProgress) error { - // 1. 驗證 NEF 檔案 - // 2. 進入 bootloader / DFU 模式 - // 3. 透過 kp_load_model_from_file() 上傳 NEF - // 4. 回報進度 - // 5. 驗證 CRC - // 6. 重啟裝置 -} +// JSON-RPC 通訊:Marshal → stdin → stdout → Unmarshal +func (d *KL720Driver) sendCommand(cmd map[string]interface{}) (map[string]interface{}, error) { ... } +``` -func (d *KL720Driver) ReadInference() (*InferenceResult, error) { - // 透過 Kneron PLUS SDK 讀取推論結果 - // 解析 Kneron 格式 → 統一 InferenceResult -} +**Python Bridge 指令協定:** + +| 指令 | 參數 | 回應 | 說明 | +|------|------|------|------| +| `scan` | — | `{devices: [{port, firmware, kn_number, product_id}]}` | USB 裝置掃描 | +| `connect` | `port`, `index` | `{status, firmware, kn_number}` | 連線 + 自動韌體載入 | +| `load_model` | `path` | `{status, model_id, target_chip}` | NEF 模型載入 | +| `inference` | `image_base64` | `{taskType, latencyMs, detections[...]}` | 圖片推論 | +| `disconnect` | — | `{status}` | 斷線 | + +**KL520 連線流程(USB Boot 模式):** + +``` +connect_devices(port_id) + → set_timeout(10000ms) + → 偵測 firmware 狀態 + → if "Loader": load_firmware_from_file(scpu, ncpu) + → sleep(5s) 等待 reboot + → 重新 scan + connect + → 回傳 firmware 版本 ``` ### 5.3 Driver 註冊流程 @@ -1642,7 +1658,87 @@ Server 啟動 → deps.PrintStartupReport(logger) | macOS Apple Silicon | tar.gz | `edge-ai-platform_v0.1.0_darwin_arm64.tar.gz` | | Windows x64 | zip | `edge-ai-platform_v0.1.0_windows_amd64.zip` | -每個 archive 含:`edge-ai-server` binary + `data/models.json` + `scripts/kneron_bridge.py` + `scripts/requirements.txt` +每個 archive 含:`edge-ai-server` binary + `data/models.json` + `scripts/kneron_bridge.py` + `scripts/requirements.txt` + `scripts/firmware/KL520/` + +#### 8.5.13 Kneron KL520 硬體通訊整合(F18) + +| 前端元件 | 後端模組 | 腳本/資源 | +|---------|---------|----------| +| 既有 inference panel | `internal/driver/kneron/kl720_driver.go` | `scripts/kneron_bridge.py` | +| 既有 device panel | `internal/driver/kneron/detector.go` | `scripts/firmware/KL520/fw_scpu.bin` | +| — | `internal/driver/interface.go` | `scripts/firmware/KL520/fw_ncpu.bin` | + +**通訊架構:** + +``` +┌──────────┐ JSON-RPC ┌──────────────────┐ ctypes ┌──────────────┐ USB BULK ┌───────┐ +│ Go Server│──stdin/out──►│ kneron_bridge.py │──────────►│libkplus.dylib│──────────►│ KL520 │ +│ (Gin) │◄────────────│ (Python 3.9) │◄──────────│(Kneron PLUS) │◄──────────│ (NPU) │ +└──────────┘ └──────────────────┘ └──────────────┘ └───────┘ +``` + +**kneron_bridge.py 推論流程:** + +```python +# 1. 接收 base64 圖片 +img_bytes = base64.b64decode(image_base64) + +# 2. OpenCV 解碼 + 色彩空間轉換 +img = cv2.imdecode(np.frombuffer(img_bytes, np.uint8), cv2.IMREAD_COLOR) +img_bgr565 = cv2.cvtColor(img, cv2.COLOR_BGR2BGR565) + +# 3. 建立推論描述符 +inf_config = kp.GenericImageInferenceDescriptor( + model_id=model_id, + input_node_image_list=[kp.GenericInputNodeImage( + image=img_bgr565, + image_format=kp.ImageFormat.KP_IMAGE_FORMAT_RGB565, + )] +) + +# 4. 送出推論 + 接收結果 +kp.inference.generic_image_inference_send(device_group, inf_config) +result = kp.inference.generic_image_inference_receive(device_group) + +# 5. YOLO v3 後處理:decode → sigmoid → NMS → detections[] +``` + +**YOLO v3 後處理細節:** + +| 項目 | 規格 | +|------|------| +| 偵測頭 | 雙尺度:7×7(大物件)+ 14×14(小物件) | +| Anchor boxes | 7×7: (81,82), (135,169), (344,319);14×14: (10,14), (23,27), (37,58) | +| 輸出通道 | 255 = 3 anchors × (5 + 80 classes) | +| 信心門檻 | ≥ 0.25 | +| NMS IoU 門檻 | 0.45 | +| 類別 | COCO 80 類(person, bicycle, car, ... toothbrush) | + +**macOS Apple Silicon 相容性:** + +``` +Kneron PLUS SDK (C source) ──編譯──► libkplus.dylib (x86_64) + ↓ +Python 3.9 (x86_64 via Rosetta 2) ──ctypes.cdll.LoadLibrary──► libkplus.dylib + ↓ +pendian.h 修正:#if defined(__APPLE__) #include +CMakeLists.txt 修正:移除 -Werror,改用 -Wno-unused-but-set-variable +``` + +**驗證結果(bike_cars_street_224x224.bmp):** + +| 物件 | 信心值 | BBox (x, y, w, h) | +|------|--------|-------------------| +| car | 0.998 | (0.66, 0.38, 0.20, 0.37) | +| car | 0.971 | (0.53, 0.34, 0.43, 0.43) | +| person | 0.965 | (0.26, 0.34, 0.10, 0.44) | +| person | 0.754 | (0.18, 0.34, 0.26, 0.43) | +| car | 0.499 | (0.42, 0.41, 0.12, 0.07) | +| bicycle | 0.465 | (0.26, 0.50, 0.12, 0.37) | +| car | 0.368 | (0.16, 0.37, 0.05, 0.05) | +| car | 0.294 | (0.45, 0.43, 0.06, 0.09) | + +推論延遲:~25ms(NPU 硬體推論) --- @@ -1870,9 +1966,24 @@ clean: **安裝內容:** 1. Edge AI Server binary + data 檔案 -2. Python venv(`$INSTALL_DIR/venv`)+ pyusb +2. Python venv(`$INSTALL_DIR/venv`)+ pyusb + numpy + opencv-python-headless 3. libusb 系統驅動(macOS: Homebrew / Linux: apt / Windows: Zadig 提示) 4. `/usr/local/bin/edge-ai-server` symlink(macOS)或 PATH 設定(Windows) +5. KL520 韌體檔案:`scripts/firmware/KL520/fw_scpu.bin`, `fw_ncpu.bin` +6. Kneron PLUS SDK:`kp` Python module + `libkplus.dylib`(macOS)/ `libkplus.so`(Linux) + +**scripts 目錄結構:** +``` +scripts/ +├── kneron_bridge.py # Go↔Kneron JSON-RPC bridge +├── requirements.txt # numpy, opencv-python-headless, pyusb +├── firmware/ +│ └── KL520/ +│ ├── fw_scpu.bin # SCPU 韌體 (52KB) +│ └── fw_ncpu.bin # NCPU 韌體 (40KB) +└── venv/ # Python venv(安裝時建立) + └── lib/.../site-packages/kp/ # Kneron PLUS SDK module +``` **解除安裝:** - macOS: `rm -rf ~/.edge-ai-platform && sudo rm -f /usr/local/bin/edge-ai-server`