fix(local-tool): KL520 首次 connect 跳過不必要的 device reset

使用者 Windows 上 connect KL520 耗時 60+ 秒且前端收到 504 timeout。

根因分析(從 log 逐行推斷):
  1. server 啟動後首次 connect → needsReset=true → restartBridge()
  2. reset 送出 → KL520 reboot → 退回 KDP2 Loader 模式(USB Boot 裝置,
     reset = firmware 從 RAM 清掉)
  3. USB 重新枚舉 8 秒 → 新 bridge process → 嘗試 reconnect
  4. Loader 模式的 connect_devices_without_check 不穩定 → attempt 1 fail
     (16 秒 timeout) → attempt 2 成功 (4 秒)
  5. 載 firmware fw_scpu.bin → 31 秒
  6. firmware loaded → 再次 reboot → 5 秒後 reconnect
  7. 總時:8 + 16 + 4 + 31 + 5 = 64 秒 > 前端 60 秒 HTTP timeout → 504

但 KL520 是 USB Boot 裝置,每次斷電 firmware + model 就會清掉,connect
時本來就是 clean state。server 啟動後主動 reset 是多餘的——它把完整
firmware 砍掉再重載一次,浪費 60 秒且 Loader 模式 connect 不穩定。

這個 reset 邏輯最初是為 KL720 設計的:KL720 是 flash-based 裝置,
firmware 和 model 保留在 flash,reset 清 stale model 才有意義。

修法:needsReset 條件加上 chipType == "KL720"。KL520 跳過 reset,
直接使用已有的 firmware。如果 KL520 真的有殘留 model 要清(理論上
不會因為它是 RAM-based),下次 load_model 前的 restartBridge 會處理。

修復後 KL520 connect 預期時間:2-5 秒(一次 connect + set_timeout)。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
jim800121chen 2026-04-16 22:49:01 +08:00
parent abbe9d4c0b
commit ddf0eb8147

View File

@ -289,14 +289,27 @@ func (d *KneronDriver) Connect() error {
d.mu.Unlock()
// First connect after server start: reset device to clear stale models.
if needsReset {
d.driverLog("INFO", "[kneron] first connect after server start — resetting device to clear stale model...")
//
// KL520 跳過 resetKL520 是 USB Boot 裝置reset 會退回 Loader 模式
// firmware 從 RAM 清掉),然後需要重新載 firmware~30 秒)+ USB
// 重新枚舉(~8 秒)。這讓原本 2 秒的 connect 變成 60+ 秒,而且
// Loader 模式的 connect_devices_without_check 不穩定(常需重試)。
//
// KL520 每次 connect 本來就是 clean stateRAM-based firmware斷電
// 即清),不需要主動 reset 清 stale model。如果真的有殘留 model
// 下次 load_model 前的 restartBridge 會處理。
//
// KL720 是 flash-based 裝置firmware 和 model 會保留在 flashreset
// 清 stale model 才有意義。
if needsReset && d.chipType == "KL720" {
d.driverLog("INFO", "[kneron] first connect after server start — resetting KL720 to clear stale model...")
if err := d.restartBridge(); err != nil {
d.driverLog("WARN", "[kneron] reset on connect failed (non-fatal): %v", err)
// Non-fatal: device is still connected, just might have stale model
} else {
d.driverLog("INFO", "[kneron] device reset complete — clean state ready")
}
} else if needsReset {
d.driverLog("INFO", "[kneron] %s: skipping reset on first connect (USB Boot device, clean state by default)", d.chipType)
}
return nil