Files
pikasTech-HWLAB/docs/reference/device-pod.md
T
2026-05-28 10:18:36 +08:00

222 lines
16 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.
# Device Pod 设备目标能力模型
本文是 HWLAB `device-pod` 的长期参考口径。`device-pod` 是一个逻辑实验台抽象,用于把一个可开发、可编译、可下载、可复位、可观测 I/O 的设备目标封装成统一能力单元。进入 server 阶段后,该能力单元可以由单副本 k8s Pod 承载,并对外提供统一 REST/job API;对外稳定身份由 Service/Deployment 承载,不依赖实际 Pod name。
`device-pod` 不等同于裸物理设备,也不是泛化远程 shell。它是以下四个要素的运行时组合:
```text
device-pod
= deviceTarget
+ debugInterface
+ projectWorkspace
+ ioInterface
```
## 设计抽象
`device-pod` 可以理解成云端可拥有和调度的一张嵌入式实验台。云端拥有的是 `device-pod` 这个逻辑能力单元,不是直接拥有某一块裸板、某一根探针或某一台用户 PC。只要 profile 能把 `deviceTarget``debugInterface``projectWorkspace``ioInterface` 四要素绑定清楚,code agent 就可以围绕同一个 `devicePodId` 完成源码修改、构建、下载、复位、状态读取和 I/O 观察,从而覆盖嵌入式开发的完整闭环。
四要素的物理落点可以不同,也可以复用同一个硬件实体的不同能力:
- `deviceTarget` 是被调试和被验证的目标设备。
- `debugInterface` 提供下载、烧录、复位、debug probe 状态和芯片识别等调试能力。
- `projectWorkspace` 承载源码、工程、Keil/GCC 等工具链和编译产物。
- `ioInterface` 提供 AI、AO、DI、DO、UART、截图、日志和其他实时或近实时观测/控制能力。
`device-pod` 因此是逻辑打包关系,而不是一对一物理设备关系。一个 DAPLink/MKLink 类探针可以同时拆出 `debugInterface` 的 SWD/CMSIS-DAP 能力和 `ioInterface` 的 UART 能力;同一个 `device-pod` 也可以把该探针与调试 box、USB 摄像头、串口工具或厂商上位机组合起来,共同形成对同一个 `deviceTarget` 的完整访问能力。
## 平台化服务模式
`device-pod` 把设备目标和访问能力封装成统一逻辑单元后,HWLAB 可以在同一技术模型上承载多种交付模式。不同模式的差异主要在于 `deviceTarget`、probe、workspace、云平台和运维责任分别由谁提供,但对 code agent 和用户界面暴露的仍应是稳定的 `devicePodId`、能力边界、锁、job、trace 和 evidence。
- **Device Pod 租赁**HWLAB 运营常用开发板、调试探针、I/O 工具和 workspace 的设备机房,用户无需自备硬件即可在云端基于真实原型开发;软件验证后可以自行找硬件工程师,或委托平台侧硬件工程师继续绘制 PCB。
- **用户 PCB 托管**:用户已经完成 PCB 或样机,委托 HWLAB 托管该 `deviceTarget`,平台提供或代管 probe、I/O 工具、workspace 和 `device-pod` 运行面,用户通过云端继续开发、测试和迭代。
- **用户自有设备接入**:用户保留自己的 `deviceTarget`、debug probe 和 I/O probe,只接入 HWLAB 云;平台把这些资源通过 profile/gateway/device-host-cli 抽象为 `device-pod`,供用户自己远程开发。
- **委托开发与运维**:在用户自有设备接入的基础上,用户可以授权平台内其他开发者、维护人员或自动化 code agent 围绕同一个 `device-pod` 进行软件开发、调试、故障复现、在线维护和验收。
- **私有 HWLAB 云部署**:用户公司内部部署自有 HWLAB 云和自有设备池,平台提供安装、升级、运维和最佳实践支持;设备、数据和权限留在用户私有环境内,`device-pod` 模型保持一致。
这些模式都不能绕过 `device-pod` 的安全边界:profile 仍不得携带长期 secretmutating operation 仍需 approval、reason、锁和 evidence;平台不得把缓存、dry-run、前端状态或本地模拟误报为真实 DEV-LIVE 设备证据。
## 实施计划
长期模型以本文为准;分阶段实现计划单独维护,避免把一次性开发步骤写进长期参考:
- [Device Pod CLI MVP 计划](../plan/device-pod-cli-mvp.md):先做 code agent 可调用的独立 CLI,通过 profile、gateway 和用户 PC 侧 `device-host-cli` 跑通 workspace、debug-probe 和 io-probe 的最小闭环。
- [Device Pod Server MVP 计划](../plan/device-pod-server-mvp.md):在 CLI 跑通后再实现真正的 `device-pod-server`,提供与 CLI 对应的 RESTful API、后台监控缓存和前端最小可视化。
## Profile 注册与同步
MVP 不使用刚性的中心 profile 注册表。`device-pod` profile 的灵活源头是 HWLAB code agent workspace 下的 `.device-pod/` 目录,推荐按 `devicePodId` 存放 profile 文件,例如 `.device-pod/device-pod-71-freq.json`
`device-pod-cli` 每次执行都从当前 code agent workspace 的 `.device-pod/` 读取 profile,并在输出中保留 `profilePath``profileHash`。进入 `device-pod-server` 阶段后,CLI 或 code agent 仍以 `.device-pod/` 为 profile source-of-truth;每次连接 server 前自动上传或刷新 profileserver 只把 active profile 当作运行时缓存,不把它变成长期配置真相。
profile 必须只描述 target、debugInterface、projectWorkspace、ioInterface、gateway route、host CLI 能力和受控路径边界;不得放入 Git key、云端 token、kubeconfig、数据库 URL 或其他长期 secret。profile 校验失败时应返回 `profile-invalid``profile-missing` blocker,而不是回退到默认设备或任意 shell。
## Selector 路径纪律
`device-pod-cli` selector 是稳定 API 语法,不是自然语言路径猜测器。`workspace``debug-probe``io-probe` selector 后的路径必须由调用方拼对,尤其是 I/O probe 必须把路径写成一个 shell token,例如 `device-pod-71-freq:io-probe:/uart/1 read`
不要迁就透传路径拼错、`/` 两侧空格或 argv 被模型拆开的写法。`io-probe:/uart / 1 read``io-probe:/uart/ 1 read` 这类输入应在 runner 侧直接返回 `invalid-request` 并给出正确写法 hint,不应被自动归一化成 `uart/1`,更不应继续透传到 gateway 或 Windows `device-host-cli`。这样可以把“命令写错”和“硬件/串口不可达”明确区分,避免下游工具为模型 spacing drift 背锅。
## HWLAB coder 预装合同
HWLAB coder / code agent runner 镜像必须通过正式 CI/CD 预装 device-pod 最小闭环所需的三类入口:
- **cmd 透传入口**`/app/tools/tran.mjs` 是 runner 内的稳定合同入口,负责通过已注册 gateway session 对 Windows PC 执行 `cmd`、PowerShell、upload 和 download,并承担 UTF-8、cwd、stdout/stderr、quoting 和文件传输边界。`/app/tools/hwlab-gateway-tran.mjs` 是同一能力的兼容实现入口,不是第二套 transport;若兼容入口存在但 `/app/tools/tran.mjs` 缺失,CI/CD 预装判定不通过,必须补齐 `tran.mjs` 短名,而不是让 device-pod 逻辑适配多个临时入口。
- **device-pod-cli 入口**runner 内必须预装 `device-pod-cli` skill,稳定入口为 `/app/skills/device-pod-cli/scripts/device-pod-cli.mjs`,其实现指向 `/app/tools/device-pod-cli.mjs`。code agent 应通过该 CLI 读取 workspace 下 `.device-pod/<devicePodId>.json`,再走 cloud-api/gateway/device-host-cli 调用设备能力。
- **device-host-cli 资产**runner 内必须随 `device-pod-cli` skill 打包 Windows 侧自包含 host CLI 资产,稳定路径为 `/app/skills/device-pod-cli/assets/device-host-cli.mjs`。新 Windows 硬件 PC 接入时,不运行独立安装器;code agent 使用预装 cmd 透传入口把该资产发送到目标 workspace 的 `tools\device-host-cli.mjs`,再通过同一 cmd 透传入口执行 `node tools\device-host-cli.mjs health` 验证。
`/app/skills` 是 HWLAB coder 镜像内 code agent skill 的唯一 canonical 位置。`device-pod-cli` 不再同步到 `/root/.agents/skills``/home/ubuntu/.agents/skills` 或 workspace 下的 skill 副本;这些副本会造成 discovery 口径、wrapper 相对路径和 CI/CD 预装内容不同步。默认 prompt、`HWLAB_CODE_AGENT_SKILLS_DIRS`、skill discovery 和验收都必须指向 `/app/skills`。如果某个运行时只能读取 home 目录,应先修复 runner 的 skill discovery 或环境变量,而不是复制第二份 skill。
`device-host-cli` 不是一次性预装脚本,而是 HWLAB 内部 code agent 可继续热开发的 host 侧工具。DeepSeek、Codex runner 或其他 HWLAB 内部 code agent 在真实硬件闭环中遇到 Keil、debug probe、串口、文件工作区或硬件启动路径不顺手时,优先在目标 Windows workspace 的 `tools\device-host-cli.mjs` 上新增或修复具名设备能力,并通过 `device-pod-cli -> cloud-api -> gateway -> device-host-cli` 的真实链路热验证;验证通过后再把同一实现回填到 `/app/skills/device-pod-cli/assets/device-host-cli.mjs` 对应的 HWLAB repo 资产,进入下一次 CI/CD 预装。不得因为 host CLI 暂时不顺手而把 `device-pod-cli` 退化为泛化 cmd/shell 入口。
目标 Windows workspace 的最小布局为:
```text
<windows-workspace>\tools\device-host-cli.mjs
<windows-workspace>\.device-pod\<devicePodId>.json
```
完成上述布局后,profile 中的 `hostCli` 应指向 `node tools\device-host-cli.mjs``device-pod-cli` 才能稳定执行 workspace、debug-probe 和 io-probe 操作。`device-host-cli` 必须自包含,不能在运行时依赖 Windows 侧 skill 目录;Keil、serial-monitor、mklink、文件编辑等 skill 只允许作为实现参考。
CI/CD 判定口径是:构建产物中同时存在 `/app/tools/tran.mjs``/app/tools/hwlab-gateway-tran.mjs``/app/tools/device-pod-cli.mjs``/app/skills/device-pod-cli/SKILL.md``/app/skills/device-pod-cli/scripts/device-pod-cli.mjs``/app/skills/device-pod-cli/assets/device-host-cli.mjs``node /app/tools/tran.mjs --help` 能展示 cmd/ps/upload/download 透传帮助,`HWLAB_CODE_AGENT_SKILLS_DIRS=/app/skills`,且 code agent skill discovery 从 `/app/skills` 发现 `device-pod-cli`。只有这些入口都在 runner 中可见,才能称为 HWLAB coder 已具备 device-pod 最小预装能力。
## 四要素
### `deviceTarget`
`deviceTarget` 是被测设备目标本身,可以是一个 MCU 最小系统板、完整业务板卡、仪器模块或其他可被 HWLAB 操作的目标对象。它必须有稳定的 `targetId`,用于锁、trace、evidence 和用户界面归因。
### `debugInterface`
`debugInterface` 是设备的开发和调试接口,代表下载、烧录、复位、debug probe 状态等能力。典型物理实现包括 DAPLink、J-Link、ST-Link 或厂商下载器。
第一版路径固定为:
```text
device-pod -> cloud-api -> gateway -> cmd -> device-host-cli -> downloader/debug probe -> target
```
`debugInterface` 只暴露设备语义能力,例如 `debug.probe``debug.download``debug.reset`。不得把它退化成任意 shell 执行入口。
`device-host-cli` 必须是用户 PC 侧自包含组件;Keil、串口、DAPLink、J-Link 或其他 skill 代码只能作为实现参考,不能成为运行时依赖。
`debugInterface` 不承载源码编译、工程发现或工具链定义;这些属于
`projectWorkspace``debugInterface` 可以消费 `projectWorkspace` 产生的
artifact,例如 `.hex``.bin``.elf`,并负责把该 artifact 下载、校验、
复位或附着调试到 `deviceTarget`
### `projectWorkspace`
`projectWorkspace` 是设备对应的源码、工程文件和编译工具链上下文,例如 Keil 工程、target 名称、构建脚本和 workspace root。它描述如何从源码生成可下载产物,也为 debug/download job 提供工程路径和工具链边界。
`projectWorkspace` 可以和 `debugInterface` 位于同一台用户 PC,也可以只通过 gateway 暴露受控 CLI。HWLAB 不直接读取 secret、kubeconfig、DB URL 或完整源码内容;探测必须有界。
工程源码的编译和工具链归属 `projectWorkspace`,包括:
- 源码根目录、工程文件和 target 名称;
- build profile、编译参数和工具链入口;
- build、clean、artifact list 等工程动作;
- `.hex``.bin``.elf` 等下载产物的位置和元数据。
因此 build 失败应归类为 workspace/toolchain blockerdownload、reset 或
probe attach 失败才归类为 debug/probe/target blocker。
典型流程为:
```text
projectWorkspace.build
-> artifact
-> debugInterface.download
-> debugInterface.reset
-> ioInterface.status/sample/uart
```
### `ioInterface`
`ioInterface` 是设备的实时或近实时 I/O 观测与控制接口,代表 UART、AI、AO、DI、DO、状态采样、日志抓取、截图等能力。典型实现包括 DAPLink/MKLink 自带串口、独立串口工具、调试 box、USB 摄像头、USB/WiFi/厂商协议上位机或 `device-host-cli`
MVP 推荐路径为:
```text
device-pod -> cloud-api -> gateway -> cmd -> device-host-cli -> serial/WiFi/USB/vendor protocol -> target
```
这里 `cmd` 只作为启动受控 PC 侧 CLI 的 transport;串口、WiFi、厂商协议和硬件细节必须隔离在 `device-host-cli` 或等价上位机 CLI 后面。
## 接口拆分
`debugInterface``ioInterface` 必须在模型和 API 中拆开,即使它们由同一个物理探针提供。例如 DAPLink 可以同时提供 SWD/CMSIS-DAP 下载调试口和 UART 串口:
```text
DAPLink physical probe
-> debugInterface: SWD/CMSIS-DAP
-> ioInterface: UART
```
拆分原因:
- `debug.download``debug.reset` 是低频强副作用动作,通常需要 approval 和 target 互斥锁。
- `io.status.read``io.sample` 是短读或短窗口采样,关注 freshness、采样窗口和输出有界性。
- `io.write` 类能力属于硬件 I/O 控制,未来也需要 approval,但不能和下载/烧录混成同一类风险。
- trace、audit、evidence 必须能区分 `debug` 路径和 `io` 路径。
MVP 不拆成两个 k8s Pod;同一个 `device-pod` 内保留两个一等接口,共享 `deviceTarget``projectWorkspace`、锁、job 和 evidence 归因。
## 最小 REST 口径
同步 API 只用于短状态和短探测:
```text
GET /health
GET /v1/profile
GET /v1/status
GET /v1/capabilities
GET /v1/workspace/status
GET /v1/debug/status
GET /v1/io/status
```
异步 API 用于下载、复位、采样等动作;每个 HTTP 调用必须短,长耗时由 job 轮询表达:
```text
POST /v1/workspace/jobs
POST /v1/debug/jobs
POST /v1/io/jobs
GET /v1/jobs/{jobId}
GET /v1/jobs/{jobId}/output
POST /v1/jobs/{jobId}/cancel
```
第一版可接受的 intent 示例:
```text
workspace.detect
workspace.build
workspace.clean
workspace.artifact.list
debug.probe
debug.download
debug.reset
io.status.read
io.sample
io.uart.fetch
```
所有响应必须保留 `devicePodId``targetId``traceId``operationId``gatewaySessionId``interface``intent``route``status` 和 blocker/evidence 字段。真实控制动作不得用 `SOURCE``LOCAL``DRY-RUN` 或前端状态冒充 `DEV-LIVE`
## 最小系统示例
一个 STM32F103 最小系统加 DAPLink 可以完整构成一个 `device-pod`
```text
deviceTarget: STM32F103 最小系统
debugInterface: DAPLink SWD/CMSIS-DAP
projectWorkspace: STM32F103 源码、Keil 工程和编译工具链
ioInterface: DAPLink UART 串口
```
最小真实闭环也可以表述为:STM32F103 最小系统板作为 `deviceTarget`,一只 MKLink/DAPLink 类探针同时提供 `debugInterface` 和第一版 `ioInterface`,其中 debug 侧负责下载、复位和芯片识别,I/O 侧先只开放 UART;`projectWorkspace` 映射到用户 PC 上的源码目录、Keil 工程和工具链,再通过 gateway/device-host-cli 暴露受控构建和 artifact 能力。这样四要素齐备后,云端 code agent 就能围绕同一个 `device-pod` 完成改源码、编译、下载、复位、读串口的最小嵌入式开发闭环。
该模型后续可以扩展到更多 target 或更复杂 I/O probe,但每个 `device-pod` 仍只代表一个明确的设备目标能力单元。