内容
# 智能硬件闭环测试
**您的 AI 代理可以独立开发固件 — 因为智能硬件闭环测试(Agentic HIL)与真实硬件闭环。**
```
+--> 构建 --> 烧录 --> 刺激 --> 观察 --+
| |
+<-------------- 诊断与修复 -----------------+
```
您的代理,无需人工干预 — 您只需审查拉取请求。
Agentic HIL 是一个 Python 包,提供有限的 MCP 工具,用于探测、烧录、重置、验证、串行和 CAN 刺激/反馈、测试适配器、报告和日志 — 而无需给予代理任意的主机或调试器访问权限。项目本地策略文件(`.hardci/config.yaml`)定义了允许的设备、操作、路径和限制。正是这个策略门槛使得无人值守的硬件访问成为可能。
HardCI 适配器是 Agentic HIL 的参考硬件:用于传感器模拟、负载和故障注入的物理 pytest 夹具。
## 为什么
在嵌入式开发中,仅仅获得一个绿色构建是不够的:固件必须在真实的板子上正确运行。经典工具自动化单个步骤 — 在这里烧录,在那里读取日志 — 但是当需要真实硬件响应时,人又回到了循环中。给代理一个原始的调试器 shell 或直接的串行访问既不安全也不可复制。Agentic HIL 通过一个小型的、可审计的门槛来弥补这一差距:
```
AI 代理 / CI ──MCP (stdio)──▶ Agentic HIL ──策略检查──▶ OpenOCD / pyOCD / STM32CubeProgrammer
│ 串行端口 (pyserial)
│ CAN (PEAK / SocketCAN / 桥接)
▼
结构化结果、报告、日志
```
每个硬件操作都根据项目策略进行验证,执行超时,记录到 `.hardci/logs/`,并以结构化的 JSON 结果(`ok`、`error_type`、`summary`、`likely_causes`、`report_path`、`log_path`)回复,代理可以对此采取行动。
## 安装
最简单的路径:告诉您的 AI 代理
> 安装 Agentic HIL 并为此项目设置。
代理遵循 [AI_AGENT_QUICKSTART.md](AI_AGENT_QUICKSTART.md) — 所有内容都安装在用户本地,**无需管理员权限**。
手动安装,无需安装任何内容(无需更改 `PATH`;需要 [uv](https://docs.astral.sh/uv/) 或 pipx):
```bash
uvx agentic-hil --version
uvx --from git+https://github.com/agentic-hil/agentic-hil agentic-hil --version
```
持久用户本地安装(推荐用于 MCP 服务器条目):
```bash
uv tool install agentic-hil # 或:pipx install agentic-hil
agentic-hil init
agentic-hil doctor
agentic-hil mcp-config --output .mcp.json
```
对于直接 PEAK/SocketCAN 访问,安装 CAN 额外包:`uv tool install 'agentic-hil[can]'`。如果某些内容无法启动,请参阅 [TROUBLESHOOTING.md](TROUBLESHOOTING.md)。
## MCP 入口
项目本地 `.mcp.json`:
```json
{
"mcpServers": {
"agentic-hil": {
"command": "agentic-hil",
"args": ["mcp-stdio", "--config", ".hardci/config.yaml"]
}
}
}
```
## 配置
`agentic-hil init` 会写入一个初始的 `.hardci/config.yaml`。该文件是策略 — 它命名目标、调试器后端、允许的工件根、命名的串行端口和 CAN 总线,以及每个操作的权限:
```yaml
target:
name: "sensor-board"
controller: "stm32f4"
debugger:
type: "openocd" # 或 "pyocd"(大多数 Cortex-M 目标),或 "stlink"(STM32CubeProgrammer CLI)
interface_cfg: "interface/stlink.cfg"
target_cfg: "target/stm32f4x.cfg"
timeout_s: 60
artifacts:
allowed_roots: ["build"] # 固件只能从此处烧录
allowed_extensions: [".elf", ".hex", ".bin"]
com_ports:
dut_uart:
device: "/dev/ttyACM0"
baudrate: 115200
can_buses:
dut_can:
adapter: "socketcan" # 或 "peak",或 "process" 用于自定义桥接
channel: "can0"
bitrate: 500000
adapters:
ntc_sim: # 传感器/执行器/故障模拟桥接
executable: "examples/adapters/sim_ntc_adapter.py"
channels: ["temperature", "resistance"]
faults: ["open", "short_to_gnd", "short_to_vcc"]
permissions:
allow_flash: true
allow_com_write: true
allow_can_write: true
allow_adapter_write: true
allow_raw_debugger_commands: false
allow_mass_erase: false
```
使用 `agentic-hil schema --output agentic-hil-config.schema.json` 导出完整的 JSON 模式。
## MCP 工具
| 组 | 工具 | 备注 |
|-------|-------|-------|
| 调试器 | `hardci_debugger_info`, `hardci_probe_target`, `hardci_reset_target` | OpenOCD, pyOCD, 或 STM32CubeProgrammer CLI |
| 固件 | `hardci_flash_firmware`, `hardci_artifact_upload` | 工件在烧录前会验证(路径、扩展名、格式、SHA-256);烧录后重置需要 `reset_after_flash: true` |
| 串行 | `hardci_com_ports_list`, `hardci_com_session_start`, `hardci_com_session_stop`, `hardci_com_write`, `hardci_com_read` | 仅限命名端口,缓冲后台读取 |
| CAN | `hardci_can_buses_list`, `hardci_can_session_start`, `hardci_can_session_stop`, `hardci_can_send`, `hardci_can_read` | PEAK, SocketCAN, 或进程桥接 |
| 测试适配器 | `hardci_adapters_list`, `hardci_adapter_session_start`, `hardci_adapter_session_stop`, `hardci_adapter_set_value`, `hardci_adapter_inject_fault`, `hardci_adapter_clear_fault`, `hardci_adapter_measure` | 通过 [适配器桥接协议](examples/adapters/README.md) 进行传感器/执行器/故障模拟 |
| 诊断 | `hardci_get_last_report`, `hardci_classify_last_error` | 带有可能原因的结构化错误分类 |
| 调试会话 | `hardci_debug_*`(启动/停止/状态、断点、继续/暂停、符号信息、内存转储) | 通过 OpenOCD 后端的 gdbserver 进行类型化的 GDB/MI 会话;意外的断点和目标异常作为结构化的停止原因返回;符号允许列表和转储大小限制来自 `debug:` 策略部分 |
典型的循环:构建固件 → 使用 `reset_after_flash: true` 时的 `hardci_flash_firmware` → `hardci_com_session_start` → 通过 `hardci_com_write`/`hardci_can_send`/`hardci_adapter_set_value` 进行刺激 → 在 `hardci_com_read`/`hardci_can_read`/`hardci_adapter_measure` 上断言 → 失败时,`hardci_classify_last_error`。
## 测试适配器
现实世界的固件错误出现在标准实验室工具无法按需重现的电气条件下:打开或短路的传感器,漂移的 NTC,缺少负载,弹跳的接触器。`adapters:` 部分将 HardCI 连接到测试适配器,这些适配器模拟这些状态 — 物理适配器硬件或纯软件模拟器,都使用相同的 [JSON 桥接协议](examples/adapters/README.md)。
使用捆绑的 NTC 模拟器(`examples/adapters/sim_ntc_adapter.py`)的示例诊断循环:烧录固件,将模拟传感器设置为 25 °C 并断言标称行为,注入一个 `open` 故障并断言固件报告传感器故障,清除故障并断言恢复 — 每个步骤都是自动的、可复制的,并且是策略门的。
## 安全模型
- 代理永远不会获得 shell、原始调试器或设备路径 — 只有命名的、配置的资源。
- 工件必须位于 `artifacts.allowed_roots` 下,匹配允许的扩展名,通过格式合理性检查,并且在烧录前进行哈希。拒绝路径遍历。
- 权限开关控制高风险操作类别;`permission_denied` 结果是权威的,代理被指示停止(参见 [AGENTS.md](AGENTS.md))。
- 故意互锁:在启用 `allow_raw_debugger_commands` 或 `allow_mass_erase` 时,拒绝烧录 — 验证的烧录和不受限制的调试器访问是相互排斥的策略。
- 串行/CAN 写操作的大小上限(`max_write_bytes`、`max_frame_data_bytes`);读取操作有缓冲区上限。调试器调用在超时和禁用 TCP 服务器的情况下运行(OpenOCD `gdb_port`/`tcl_port`/`telnet_port disabled`);只有类型化的调试会话打开一个 `gdb_port`,绑定到 `localhost` 上的临时端口,仅用于该会话,并在会话结束后被拆除。
- 测试适配器通道和故障名称是明确的允许列表 — 在到达适配器桥接之前,HardCI 拒绝配置文件中未命名的任何内容。
- 所有操作都记录到 `.hardci/logs/` 并写入 `.hardci/reports/` 的结构化报告。
## pytest 插件
安装 `agentic-hil` 会注册一个 pytest 插件,因此 CI 回归套件可以在没有 MCP 客户端的情况下驱动相同的策略门控工具:
```python
def test_open_sensor_diagnosis(agentic_hil):
started = agentic_hil.call("hardci_adapter_session_start", {"adapter_id": "ntc_sim"})
assert started["ok"] is True
injected = agentic_hil.call("hardci_adapter_inject_fault", {"adapter_id": "ntc_sim", "fault": "open"})
assert injected["ok"] is True
# ... 在 hardci_com_read 上断言固件的反应 ...
```
`agentic_hil` 夹具加载相对于 pytest rootdir 的 `.hardci/config.yaml`(使用 `--hardci-config` 或 `hardci_config` ini 选项覆盖)。如果不存在配置文件,则跳过测试,但存在无效配置文件会报错 — 配置错误必须不会在 CI 中静默禁用硬件套件。测试期间打开的适配器、COM 和 CAN 会话在测试结束后停止,因此刺激状态不会在测试之间泄漏。有关完整的诊断循环示例,请参阅 [examples/pytest/](examples/pytest/),有关真实硬件上的完整循环,请参阅 [examples/nucleo-f446re_demo/](examples/nucleo-f446re_demo/):一个裸金属 STM32 固件,构建、烧录、重置,并通过其 UART 启动横幅进行断言。
## 常用命令
```text
agentic-hil init
agentic-hil doctor
agentic-hil com-ports
agentic-hil mcp-config --output .mcp.json
agentic-hil mcp-stdio --config .hardci/config.yaml
agentic-hil com-stdio --config .hardci/config.yaml --port dut_uart
agentic-hil schema --output agentic-hil-config.schema.json
agentic-hil skill-install --agent opencode
```
## 平台支持
Linux、macOS 和 Windows(在 Python 3.10–3.13 上进行 CI 测试)。调试器后端:OpenOCD、pyOCD(`agentic-hil[pyocd]` — 通过 CMSIS packs 和 CMSIS-DAP/ST-Link/J-Link 探针覆盖大多数 ARM Cortex-M 目标,设置 `debugger.target_type`),和 STM32CubeProgrammer CLI(在 Windows 上自动发现)。直接 CAN 需要 `agentic-hil[can]`(python-can);任何其他适配器都可以通过 `process` 桥接协议连接。
## 开发
```bash
python -m pip install -e '.[dev]'
ruff check src tests
pytest
python -m build
twine check dist/*
```
该包通过 GitHub 受信任的发布功能在 `.github/workflows/workflow.yml` 中配置为 PyPI 发布。
## 安全
策略绕过被视为漏洞 — 参见 [SECURITY.md](SECURITY.md)。
## 许可证
Apache-2.0 — 参见 [LICENSE](LICENSE)。