firmwareloop 0.9.1__tar.gz → 0.11.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/PKG-INFO +60 -8
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/README.md +59 -7
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/firmwareloop.egg-info/PKG-INFO +60 -8
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/firmwareloop.egg-info/SOURCES.txt +3 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/pyproject.toml +1 -1
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/__init__.py +1 -1
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/build.ps1 +3 -2
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/can.ps1 +7 -4
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/check-qoder-mcp.ps1 +3 -2
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/common/fw.psm1 +114 -0
- firmwareloop-0.11.1/tools/doctor.ps1 +668 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/flash.ps1 +3 -2
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/fw_mcp_server.py +313 -18
- firmwareloop-0.11.1/tools/lib/doctor_summary.py +190 -0
- firmwareloop-0.11.1/tools/lib/session_run.py +279 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/logic_capture.ps1 +64 -10
- firmwareloop-0.11.1/tools/logic_capture_summary.py +204 -0
- firmwareloop-0.11.1/tools/logic_decode.ps1 +503 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/reset.ps1 +3 -2
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/setup-agent-mcp.ps1 +2 -2
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/sigrok_csv_to_fwloop.py +9 -4
- firmwareloop-0.9.1/tools/doctor.ps1 +0 -274
- firmwareloop-0.9.1/tools/logic_decode.ps1 +0 -308
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/LICENSE +0 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/firmwareloop.egg-info/dependency_links.txt +0 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/firmwareloop.egg-info/entry_points.txt +0 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/firmwareloop.egg-info/requires.txt +0 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/firmwareloop.egg-info/top_level.txt +0 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/setup.cfg +0 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/acceptance-scenario.ps1 +0 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/common/build-backends.psm1 +0 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/common/uart_probe.py +0 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/instrument_cli.py +0 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/lib/__init__.py +0 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/lib/instruments.py +0 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/lib/ndtdbg.py +0 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/lib/serial_assistant.py +0 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/ndtdbg_bridge.ps1 +0 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/ndtdbg_cli.py +0 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/serial_cli.py +0 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/templates/lab.example.yaml +0 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/templates/skill-firmwareloop.md +0 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/templates/skill-fwloop-adapter.md +0 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/test-backends.ps1 +0 -0
- {firmwareloop-0.9.1 → firmwareloop-0.11.1}/tools/test.ps1 +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: firmwareloop
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.1
|
|
4
4
|
Summary: AI Agent Firmware Development and Lab Automation Platform (Dual-Tier MCP Server)
|
|
5
5
|
Author-email: WeilinZhang <19523330249@163.com>
|
|
6
6
|
License: MIT
|
|
@@ -109,10 +109,32 @@ FirmwareLoop 为 AI Agent 暴露了开箱即用的 MCP 工具,涵盖 5 大核
|
|
|
109
109
|
|
|
110
110
|
## NDT 公司同事快捷通道(一键离线部署)
|
|
111
111
|
|
|
112
|
-
拿到 `Fwloop_setup_pack` 交付包后,双击 **`fwloop-deploy-setup.exe`**,按向导填入 NdtDebugTool
|
|
112
|
+
拿到 `Fwloop_setup_pack` 交付包后,双击 **`fwloop-deploy-setup.exe`**,按向导填入 NdtDebugTool 根目录即可,全程离线。
|
|
113
113
|
完整指南与常见错误速查见随包分发的 [`Fwloop_setup_pack/README.md`](Fwloop_setup_pack/README.md)。
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
**安装器自动完成**:uv + 离线 wheel 安装 fwloop、`fwloop setup`(注册 Agent + 生成全局配置)、写入 NdtDebugTool 路径、
|
|
116
|
+
Saleae Logic16 固件落位(`%LOCALAPPDATA%\sigrok-firmware`)、sigrok-cli 安装。
|
|
117
|
+
|
|
118
|
+
**安装器不装驱动 —— 这一步只在需要时由人工完成(两类,互不相关)**
|
|
119
|
+
|
|
120
|
+
| 需要什么 | 什么时候才需要 | 怎么做 |
|
|
121
|
+
|---|---|---|
|
|
122
|
+
| **NdtBox 驱动(CH341PAR)** | 这台电脑**从没连过 NdtBox** 才需要(上位机报 Device Not Found / 设备管理器带 ⚠️)。平时能用 NdtDebugTool 就说明已装好 | 运行包内 `assets\NDTBoxDriver\CH341PAR.EXE`(串口场景另装 `CH341SER.EXE`) |
|
|
123
|
+
| **逻辑分析仪驱动(Zadig → `libusb-win32`)** | 只做寄存器读写**不需要**;要用**抓波形 / 波形证据**(`fw_logic_capture`、`fw_ndtdbg_capture_seq`)时才需要 | 按 `Fwloop_setup_pack\README.md` 第 2 步:Zadig → 选中 Logic S/16 → 驱动选 `libusb-win32` → 拔插一次。**装好了怎么确认**见下方说明(一句话:让 Agent 抓一次波形,能抓到就算装好了) |
|
|
124
|
+
|
|
125
|
+
> **怎么确认逻辑分析仪驱动装好了(第 1 条对人足够)**
|
|
126
|
+
>
|
|
127
|
+
> 1. **让 Agent 抓一次波形**,例如对它说"用 fwloop 抓一次 I2C 波形并解码"——**能抓到波形,就说明驱动装好了**;
|
|
128
|
+
> 2. 想亲自核对:设备管理器 → 那台 Saleae → 右键属性 → 驱动程序 → 服务显示 `libusb-win32`;
|
|
129
|
+
> 3. 抓不到时的现象:报 `Failed to open device.` 或 `... EP1 command ... LIBUSB_ERROR_IO` ⇒ 驱动没绑对,回第 1 步重做(换 USB 口后也要重做);
|
|
130
|
+
> 4. Agent 自查用的技术判据:`fwloop doctor` 的仪器深检项 `checks.instruments` —— `status=ok`,且 `libusb_bound` 中该仪器的 `service` 为 `libusb0`/`libusbK`。
|
|
131
|
+
>
|
|
132
|
+
> **为什么"能扫到"不等于"能用"**:驱动绑定不对时 `sigrok-cli --scan` 依然列得出设备,但采集初始化会失败在
|
|
133
|
+
> `Failed to receive reply to EP1 command 0x7d: LIBUSB_ERROR_IO`。原理与三个高频坑(换 USB 口后需重绑、
|
|
134
|
+
> 拔插后需重试一次、阈值要匹配被测电平)详见下文 **《前置条件:仪器接入(Windows)》**。
|
|
135
|
+
|
|
136
|
+
**装完后**:重启 AI Agent,先让它跑一次环境检查(`fw_doctor`,它会用人话汇报每台仪器/串口能不能用、缺什么怎么补),再操作 NdtBox
|
|
137
|
+
(状态检查 / 数据采集 / 固件烧录 / 抓波形——抓波形前按上表确认逻辑分析仪驱动已就绪)。
|
|
116
138
|
若还要在某个单片机工程里做编译 / 烧录 / HIL 测试,进入该工程根目录执行一次 `fwloop init`(每个新工程一次)。
|
|
117
139
|
|
|
118
140
|
---
|
|
@@ -132,6 +154,36 @@ uv tool install agentic-hil
|
|
|
132
154
|
|
|
133
155
|
---
|
|
134
156
|
|
|
157
|
+
### 前置条件:仪器接入(Windows)
|
|
158
|
+
|
|
159
|
+
框架通过 libusb / VCP 类后端访问 USB 逻辑分析仪、USB 转 IIC/UART 桥等仪器。
|
|
160
|
+
**首次在这台电脑使用某台仪器、或换过 USB 端口之后**,请先确认驱动绑定——这是"仪器打不开"最常见的原因:
|
|
161
|
+
|
|
162
|
+
| 仪器类别 | 需要什么 | 自查方法 | 装错/没装时的症状 |
|
|
163
|
+
|---|---|---|---|
|
|
164
|
+
| USB 逻辑分析仪(sigrok/Saleae 类,含 FX2/EZ-USB 固件上传型) | 绑定到 libusb 类驱动(`libusb-win32`,或 `WinUSB`) | 最直接:让它抓一次波形,能抓到就行;手工核对:设备管理器 → 设备 → 属性 → 驱动程序/服务(应显示 `libusb-win32` / `libusb0` / `libusbK` / `WinUSB`);也可让 Agent 读 `fwloop doctor` 的仪器深检项 | 采集报 `Failed to open device.`;初始化阶段报 `... EP1 command ... LIBUSB_ERROR_IO` |
|
|
165
|
+
| USB 转 IIC/UART 桥(CH340/CH341、CP210x、FTDI…) | 厂商 VCP 驱动 | 出现 COM 口,`fwloop doctor` 的 `com_ports` 能列出 | 端口不存在 / 打开报占用 |
|
|
166
|
+
| 蓝牙或 ELTIMA 等虚拟串口 | 不作为被测口 | `fwloop doctor` 会把虚拟口单独列出来(不与真实口混在一起) | 能打开但永远无数据 |
|
|
167
|
+
|
|
168
|
+
**用 Zadig 给逻辑分析仪绑定驱动(人工一次,需管理员)**
|
|
169
|
+
|
|
170
|
+
1. 关闭一切可能占用该设备的软件(厂商上位机、PulseView、Saleae Logic 2 等)——**独占是前提**。
|
|
171
|
+
2. 管理员运行 Zadig(sigrok 安装目录自带 `zadig.exe`;也可用官方包)→ `Options → List All Devices`。
|
|
172
|
+
3. 选中**当前在线**的那台设备(按 VID/PID 核对;忽略"幽灵"残留节点),目标驱动选 `WinUSB` → `Replace Driver`。
|
|
173
|
+
4. **拔插一次**设备,再让 Agent 重试。
|
|
174
|
+
5. 若仍打不开、或初始化阶段报 EP1/命令无应答:对该设备改绑 `libusb-win32` 再试(两者互为 A/B 对照)。
|
|
175
|
+
|
|
176
|
+
**三个会反复踩的坑**
|
|
177
|
+
|
|
178
|
+
- 驱动绑定**跟随 USB 端口实例**:换一个 USB 口 = 新的设备实例,Windows 可能重新绑回默认驱动 → 需对该实例重做一次 Zadig。
|
|
179
|
+
- 拔插会**重置设备状态**:刚初始化的设备拔插后要重新初始化;首次打开报"等待设备重启 / 初始化失败"时,等 3–5 秒重试一次通常即可。
|
|
180
|
+
- **阈值/量程必须覆盖被测电平**:采集前确认被测逻辑电平落在仪器档位内(例:1.8 V 逻辑需选覆盖 1.4–3.6 V 的档位,而不是 0.7–1.4 V;示波器注意探针 1x/10x 衰减比)。
|
|
181
|
+
|
|
182
|
+
> 驱动安装需要管理员权限与设备选择,误绑会影响其它软件,因此框架**不自动安装驱动**,只做「检测 → 指引 → 复验」:
|
|
183
|
+
> `fwloop doctor` 会报告每台仪器当前的就绪状态**和下一步该怎么修**(Agent 读的也是同一份内容)。公司交付包覆盖的环境由安装器代做(见 [`Fwloop_setup_pack/README.md`](Fwloop_setup_pack/README.md))。
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
135
187
|
### 可选:接入 NdtBox 调试盒(公司内部 USB→IIC 调试工具)
|
|
136
188
|
|
|
137
189
|
如需用 Agent 直接操作 NdtBox(固件寄存器读写 / 数据采集 / 逻辑分析仪协议验证),安装后执行一次:
|
|
@@ -156,7 +208,7 @@ fwloop ndtdebugtool "C:/Users/weilin.zhang/Desktop/zwl/NdtDebugTool-v1.0.19"
|
|
|
156
208
|
**前置要求:**
|
|
157
209
|
|
|
158
210
|
- **CH341 驱动**:首次在这台电脑使用 NdtBox 时,运行交付包内 `assets\NDTBoxDriver\CH341PAR.EXE`(USB 转 IIC);COM 串口场景另装 `CH341SER.EXE`
|
|
159
|
-
- **Saleae 波形证据**(可选):Saleae Logic16
|
|
211
|
+
- **Saleae 波形证据**(可选):Saleae Logic16 固件落位 `%LOCALAPPDATA%\sigrok-firmware` + sigrok-cli;**驱动绑定(Zadig)见上文《前置条件:仪器接入(Windows)》**——交付包一键安装器会自动完成这两步,手工部署详见 [`Fwloop_setup_pack/README.md`](Fwloop_setup_pack/README.md)
|
|
160
212
|
- **USB 独占**:测试时退出 NdtDebugTool 上位机 STDataCollection.exe(同时打开会互踢)
|
|
161
213
|
|
|
162
214
|
---
|
|
@@ -233,7 +285,7 @@ fwloop init
|
|
|
233
285
|
|---|---|---|---|
|
|
234
286
|
| **`fwloop setup`** | **系统全局级** | 给各大 Agent(Antigravity / Claude Code / Qoder / Qoder CN / CodeBuddy)配置全局 MCP 与同步技能包 | **全电脑只需跑 1 次** |
|
|
235
287
|
| **`fwloop init`** | **工程项目级** | 在当前单片机代码目录下生成 `AGENTS.md`、`GEMINI.md`、`CLAUDE.md` 与台架配置 | **每个新单片机项目跑 1 次** |
|
|
236
|
-
| **`fwloop doctor`** | **环境诊断** |
|
|
288
|
+
| **`fwloop doctor`** | **环境诊断** | 一屏人话摘要:核心工具链是否正常、仪器能不能用(逻辑分析仪/串口/探针…)、缺什么怎么补。加 `--json` 看原始数据 | 随时排查环境时使用 |
|
|
237
289
|
| **`fwloop update`** | **自动更新** | 一键自动拉取最新代码并热重载依赖 | 升级工具版本时使用 |
|
|
238
290
|
|
|
239
291
|
---
|
|
@@ -309,7 +361,7 @@ fwloop update
|
|
|
309
361
|
|
|
310
362
|
3. 环境健康体检与依赖诊断:
|
|
311
363
|
```bash
|
|
312
|
-
fwloop doctor
|
|
364
|
+
fwloop doctor # 人话摘要; 需要原始数据时另加 --json
|
|
313
365
|
```
|
|
314
366
|
|
|
315
367
|
4. 查看或生成各大 Agent MCP 注册指令:
|
|
@@ -387,7 +439,7 @@ claude mcp remove --scope user agentic-hil
|
|
|
387
439
|
├── demo-firmware/ 示例固件(CMake;宿主编译模拟 MCU,闭环验证载体)
|
|
388
440
|
├── demo-make/ 示例固件(Make;构建测试载体)
|
|
389
441
|
├── docs/ DEPENDENCY_MATRIX / REUSE_PLAN / V0.0.2_GAP_VERIFICATION
|
|
390
|
-
├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.
|
|
442
|
+
├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.11.1)
|
|
391
443
|
├── .mcp.example.json 双层 MCP 配置模板(firmwareloop + agentic-hil)
|
|
392
444
|
├── AGENTS.md 通用智能体规范(Antigravity / Qoder / Cursor 等)
|
|
393
445
|
├── CLAUDE.md Claude Code CLI 指南
|
|
@@ -397,7 +449,7 @@ claude mcp remove --scope user agentic-hil
|
|
|
397
449
|
|
|
398
450
|
---
|
|
399
451
|
|
|
400
|
-
## 能力验证状态(v0.
|
|
452
|
+
## 能力验证状态(v0.11.1)
|
|
401
453
|
|
|
402
454
|
> 状态定义:`Implemented`(已实现)/ `Simulator Validated`(模拟验证)/
|
|
403
455
|
> `Real Hardware Validated`(真机验证)/ `Experimental` / `Not Implemented`
|
|
@@ -79,10 +79,32 @@ FirmwareLoop 为 AI Agent 暴露了开箱即用的 MCP 工具,涵盖 5 大核
|
|
|
79
79
|
|
|
80
80
|
## NDT 公司同事快捷通道(一键离线部署)
|
|
81
81
|
|
|
82
|
-
拿到 `Fwloop_setup_pack` 交付包后,双击 **`fwloop-deploy-setup.exe`**,按向导填入 NdtDebugTool
|
|
82
|
+
拿到 `Fwloop_setup_pack` 交付包后,双击 **`fwloop-deploy-setup.exe`**,按向导填入 NdtDebugTool 根目录即可,全程离线。
|
|
83
83
|
完整指南与常见错误速查见随包分发的 [`Fwloop_setup_pack/README.md`](Fwloop_setup_pack/README.md)。
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
**安装器自动完成**:uv + 离线 wheel 安装 fwloop、`fwloop setup`(注册 Agent + 生成全局配置)、写入 NdtDebugTool 路径、
|
|
86
|
+
Saleae Logic16 固件落位(`%LOCALAPPDATA%\sigrok-firmware`)、sigrok-cli 安装。
|
|
87
|
+
|
|
88
|
+
**安装器不装驱动 —— 这一步只在需要时由人工完成(两类,互不相关)**
|
|
89
|
+
|
|
90
|
+
| 需要什么 | 什么时候才需要 | 怎么做 |
|
|
91
|
+
|---|---|---|
|
|
92
|
+
| **NdtBox 驱动(CH341PAR)** | 这台电脑**从没连过 NdtBox** 才需要(上位机报 Device Not Found / 设备管理器带 ⚠️)。平时能用 NdtDebugTool 就说明已装好 | 运行包内 `assets\NDTBoxDriver\CH341PAR.EXE`(串口场景另装 `CH341SER.EXE`) |
|
|
93
|
+
| **逻辑分析仪驱动(Zadig → `libusb-win32`)** | 只做寄存器读写**不需要**;要用**抓波形 / 波形证据**(`fw_logic_capture`、`fw_ndtdbg_capture_seq`)时才需要 | 按 `Fwloop_setup_pack\README.md` 第 2 步:Zadig → 选中 Logic S/16 → 驱动选 `libusb-win32` → 拔插一次。**装好了怎么确认**见下方说明(一句话:让 Agent 抓一次波形,能抓到就算装好了) |
|
|
94
|
+
|
|
95
|
+
> **怎么确认逻辑分析仪驱动装好了(第 1 条对人足够)**
|
|
96
|
+
>
|
|
97
|
+
> 1. **让 Agent 抓一次波形**,例如对它说"用 fwloop 抓一次 I2C 波形并解码"——**能抓到波形,就说明驱动装好了**;
|
|
98
|
+
> 2. 想亲自核对:设备管理器 → 那台 Saleae → 右键属性 → 驱动程序 → 服务显示 `libusb-win32`;
|
|
99
|
+
> 3. 抓不到时的现象:报 `Failed to open device.` 或 `... EP1 command ... LIBUSB_ERROR_IO` ⇒ 驱动没绑对,回第 1 步重做(换 USB 口后也要重做);
|
|
100
|
+
> 4. Agent 自查用的技术判据:`fwloop doctor` 的仪器深检项 `checks.instruments` —— `status=ok`,且 `libusb_bound` 中该仪器的 `service` 为 `libusb0`/`libusbK`。
|
|
101
|
+
>
|
|
102
|
+
> **为什么"能扫到"不等于"能用"**:驱动绑定不对时 `sigrok-cli --scan` 依然列得出设备,但采集初始化会失败在
|
|
103
|
+
> `Failed to receive reply to EP1 command 0x7d: LIBUSB_ERROR_IO`。原理与三个高频坑(换 USB 口后需重绑、
|
|
104
|
+
> 拔插后需重试一次、阈值要匹配被测电平)详见下文 **《前置条件:仪器接入(Windows)》**。
|
|
105
|
+
|
|
106
|
+
**装完后**:重启 AI Agent,先让它跑一次环境检查(`fw_doctor`,它会用人话汇报每台仪器/串口能不能用、缺什么怎么补),再操作 NdtBox
|
|
107
|
+
(状态检查 / 数据采集 / 固件烧录 / 抓波形——抓波形前按上表确认逻辑分析仪驱动已就绪)。
|
|
86
108
|
若还要在某个单片机工程里做编译 / 烧录 / HIL 测试,进入该工程根目录执行一次 `fwloop init`(每个新工程一次)。
|
|
87
109
|
|
|
88
110
|
---
|
|
@@ -102,6 +124,36 @@ uv tool install agentic-hil
|
|
|
102
124
|
|
|
103
125
|
---
|
|
104
126
|
|
|
127
|
+
### 前置条件:仪器接入(Windows)
|
|
128
|
+
|
|
129
|
+
框架通过 libusb / VCP 类后端访问 USB 逻辑分析仪、USB 转 IIC/UART 桥等仪器。
|
|
130
|
+
**首次在这台电脑使用某台仪器、或换过 USB 端口之后**,请先确认驱动绑定——这是"仪器打不开"最常见的原因:
|
|
131
|
+
|
|
132
|
+
| 仪器类别 | 需要什么 | 自查方法 | 装错/没装时的症状 |
|
|
133
|
+
|---|---|---|---|
|
|
134
|
+
| USB 逻辑分析仪(sigrok/Saleae 类,含 FX2/EZ-USB 固件上传型) | 绑定到 libusb 类驱动(`libusb-win32`,或 `WinUSB`) | 最直接:让它抓一次波形,能抓到就行;手工核对:设备管理器 → 设备 → 属性 → 驱动程序/服务(应显示 `libusb-win32` / `libusb0` / `libusbK` / `WinUSB`);也可让 Agent 读 `fwloop doctor` 的仪器深检项 | 采集报 `Failed to open device.`;初始化阶段报 `... EP1 command ... LIBUSB_ERROR_IO` |
|
|
135
|
+
| USB 转 IIC/UART 桥(CH340/CH341、CP210x、FTDI…) | 厂商 VCP 驱动 | 出现 COM 口,`fwloop doctor` 的 `com_ports` 能列出 | 端口不存在 / 打开报占用 |
|
|
136
|
+
| 蓝牙或 ELTIMA 等虚拟串口 | 不作为被测口 | `fwloop doctor` 会把虚拟口单独列出来(不与真实口混在一起) | 能打开但永远无数据 |
|
|
137
|
+
|
|
138
|
+
**用 Zadig 给逻辑分析仪绑定驱动(人工一次,需管理员)**
|
|
139
|
+
|
|
140
|
+
1. 关闭一切可能占用该设备的软件(厂商上位机、PulseView、Saleae Logic 2 等)——**独占是前提**。
|
|
141
|
+
2. 管理员运行 Zadig(sigrok 安装目录自带 `zadig.exe`;也可用官方包)→ `Options → List All Devices`。
|
|
142
|
+
3. 选中**当前在线**的那台设备(按 VID/PID 核对;忽略"幽灵"残留节点),目标驱动选 `WinUSB` → `Replace Driver`。
|
|
143
|
+
4. **拔插一次**设备,再让 Agent 重试。
|
|
144
|
+
5. 若仍打不开、或初始化阶段报 EP1/命令无应答:对该设备改绑 `libusb-win32` 再试(两者互为 A/B 对照)。
|
|
145
|
+
|
|
146
|
+
**三个会反复踩的坑**
|
|
147
|
+
|
|
148
|
+
- 驱动绑定**跟随 USB 端口实例**:换一个 USB 口 = 新的设备实例,Windows 可能重新绑回默认驱动 → 需对该实例重做一次 Zadig。
|
|
149
|
+
- 拔插会**重置设备状态**:刚初始化的设备拔插后要重新初始化;首次打开报"等待设备重启 / 初始化失败"时,等 3–5 秒重试一次通常即可。
|
|
150
|
+
- **阈值/量程必须覆盖被测电平**:采集前确认被测逻辑电平落在仪器档位内(例:1.8 V 逻辑需选覆盖 1.4–3.6 V 的档位,而不是 0.7–1.4 V;示波器注意探针 1x/10x 衰减比)。
|
|
151
|
+
|
|
152
|
+
> 驱动安装需要管理员权限与设备选择,误绑会影响其它软件,因此框架**不自动安装驱动**,只做「检测 → 指引 → 复验」:
|
|
153
|
+
> `fwloop doctor` 会报告每台仪器当前的就绪状态**和下一步该怎么修**(Agent 读的也是同一份内容)。公司交付包覆盖的环境由安装器代做(见 [`Fwloop_setup_pack/README.md`](Fwloop_setup_pack/README.md))。
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
105
157
|
### 可选:接入 NdtBox 调试盒(公司内部 USB→IIC 调试工具)
|
|
106
158
|
|
|
107
159
|
如需用 Agent 直接操作 NdtBox(固件寄存器读写 / 数据采集 / 逻辑分析仪协议验证),安装后执行一次:
|
|
@@ -126,7 +178,7 @@ fwloop ndtdebugtool "C:/Users/weilin.zhang/Desktop/zwl/NdtDebugTool-v1.0.19"
|
|
|
126
178
|
**前置要求:**
|
|
127
179
|
|
|
128
180
|
- **CH341 驱动**:首次在这台电脑使用 NdtBox 时,运行交付包内 `assets\NDTBoxDriver\CH341PAR.EXE`(USB 转 IIC);COM 串口场景另装 `CH341SER.EXE`
|
|
129
|
-
- **Saleae 波形证据**(可选):Saleae Logic16
|
|
181
|
+
- **Saleae 波形证据**(可选):Saleae Logic16 固件落位 `%LOCALAPPDATA%\sigrok-firmware` + sigrok-cli;**驱动绑定(Zadig)见上文《前置条件:仪器接入(Windows)》**——交付包一键安装器会自动完成这两步,手工部署详见 [`Fwloop_setup_pack/README.md`](Fwloop_setup_pack/README.md)
|
|
130
182
|
- **USB 独占**:测试时退出 NdtDebugTool 上位机 STDataCollection.exe(同时打开会互踢)
|
|
131
183
|
|
|
132
184
|
---
|
|
@@ -203,7 +255,7 @@ fwloop init
|
|
|
203
255
|
|---|---|---|---|
|
|
204
256
|
| **`fwloop setup`** | **系统全局级** | 给各大 Agent(Antigravity / Claude Code / Qoder / Qoder CN / CodeBuddy)配置全局 MCP 与同步技能包 | **全电脑只需跑 1 次** |
|
|
205
257
|
| **`fwloop init`** | **工程项目级** | 在当前单片机代码目录下生成 `AGENTS.md`、`GEMINI.md`、`CLAUDE.md` 与台架配置 | **每个新单片机项目跑 1 次** |
|
|
206
|
-
| **`fwloop doctor`** | **环境诊断** |
|
|
258
|
+
| **`fwloop doctor`** | **环境诊断** | 一屏人话摘要:核心工具链是否正常、仪器能不能用(逻辑分析仪/串口/探针…)、缺什么怎么补。加 `--json` 看原始数据 | 随时排查环境时使用 |
|
|
207
259
|
| **`fwloop update`** | **自动更新** | 一键自动拉取最新代码并热重载依赖 | 升级工具版本时使用 |
|
|
208
260
|
|
|
209
261
|
---
|
|
@@ -279,7 +331,7 @@ fwloop update
|
|
|
279
331
|
|
|
280
332
|
3. 环境健康体检与依赖诊断:
|
|
281
333
|
```bash
|
|
282
|
-
fwloop doctor
|
|
334
|
+
fwloop doctor # 人话摘要; 需要原始数据时另加 --json
|
|
283
335
|
```
|
|
284
336
|
|
|
285
337
|
4. 查看或生成各大 Agent MCP 注册指令:
|
|
@@ -357,7 +409,7 @@ claude mcp remove --scope user agentic-hil
|
|
|
357
409
|
├── demo-firmware/ 示例固件(CMake;宿主编译模拟 MCU,闭环验证载体)
|
|
358
410
|
├── demo-make/ 示例固件(Make;构建测试载体)
|
|
359
411
|
├── docs/ DEPENDENCY_MATRIX / REUSE_PLAN / V0.0.2_GAP_VERIFICATION
|
|
360
|
-
├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.
|
|
412
|
+
├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.11.1)
|
|
361
413
|
├── .mcp.example.json 双层 MCP 配置模板(firmwareloop + agentic-hil)
|
|
362
414
|
├── AGENTS.md 通用智能体规范(Antigravity / Qoder / Cursor 等)
|
|
363
415
|
├── CLAUDE.md Claude Code CLI 指南
|
|
@@ -367,7 +419,7 @@ claude mcp remove --scope user agentic-hil
|
|
|
367
419
|
|
|
368
420
|
---
|
|
369
421
|
|
|
370
|
-
## 能力验证状态(v0.
|
|
422
|
+
## 能力验证状态(v0.11.1)
|
|
371
423
|
|
|
372
424
|
> 状态定义:`Implemented`(已实现)/ `Simulator Validated`(模拟验证)/
|
|
373
425
|
> `Real Hardware Validated`(真机验证)/ `Experimental` / `Not Implemented`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: firmwareloop
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.1
|
|
4
4
|
Summary: AI Agent Firmware Development and Lab Automation Platform (Dual-Tier MCP Server)
|
|
5
5
|
Author-email: WeilinZhang <19523330249@163.com>
|
|
6
6
|
License: MIT
|
|
@@ -109,10 +109,32 @@ FirmwareLoop 为 AI Agent 暴露了开箱即用的 MCP 工具,涵盖 5 大核
|
|
|
109
109
|
|
|
110
110
|
## NDT 公司同事快捷通道(一键离线部署)
|
|
111
111
|
|
|
112
|
-
拿到 `Fwloop_setup_pack` 交付包后,双击 **`fwloop-deploy-setup.exe`**,按向导填入 NdtDebugTool
|
|
112
|
+
拿到 `Fwloop_setup_pack` 交付包后,双击 **`fwloop-deploy-setup.exe`**,按向导填入 NdtDebugTool 根目录即可,全程离线。
|
|
113
113
|
完整指南与常见错误速查见随包分发的 [`Fwloop_setup_pack/README.md`](Fwloop_setup_pack/README.md)。
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
**安装器自动完成**:uv + 离线 wheel 安装 fwloop、`fwloop setup`(注册 Agent + 生成全局配置)、写入 NdtDebugTool 路径、
|
|
116
|
+
Saleae Logic16 固件落位(`%LOCALAPPDATA%\sigrok-firmware`)、sigrok-cli 安装。
|
|
117
|
+
|
|
118
|
+
**安装器不装驱动 —— 这一步只在需要时由人工完成(两类,互不相关)**
|
|
119
|
+
|
|
120
|
+
| 需要什么 | 什么时候才需要 | 怎么做 |
|
|
121
|
+
|---|---|---|
|
|
122
|
+
| **NdtBox 驱动(CH341PAR)** | 这台电脑**从没连过 NdtBox** 才需要(上位机报 Device Not Found / 设备管理器带 ⚠️)。平时能用 NdtDebugTool 就说明已装好 | 运行包内 `assets\NDTBoxDriver\CH341PAR.EXE`(串口场景另装 `CH341SER.EXE`) |
|
|
123
|
+
| **逻辑分析仪驱动(Zadig → `libusb-win32`)** | 只做寄存器读写**不需要**;要用**抓波形 / 波形证据**(`fw_logic_capture`、`fw_ndtdbg_capture_seq`)时才需要 | 按 `Fwloop_setup_pack\README.md` 第 2 步:Zadig → 选中 Logic S/16 → 驱动选 `libusb-win32` → 拔插一次。**装好了怎么确认**见下方说明(一句话:让 Agent 抓一次波形,能抓到就算装好了) |
|
|
124
|
+
|
|
125
|
+
> **怎么确认逻辑分析仪驱动装好了(第 1 条对人足够)**
|
|
126
|
+
>
|
|
127
|
+
> 1. **让 Agent 抓一次波形**,例如对它说"用 fwloop 抓一次 I2C 波形并解码"——**能抓到波形,就说明驱动装好了**;
|
|
128
|
+
> 2. 想亲自核对:设备管理器 → 那台 Saleae → 右键属性 → 驱动程序 → 服务显示 `libusb-win32`;
|
|
129
|
+
> 3. 抓不到时的现象:报 `Failed to open device.` 或 `... EP1 command ... LIBUSB_ERROR_IO` ⇒ 驱动没绑对,回第 1 步重做(换 USB 口后也要重做);
|
|
130
|
+
> 4. Agent 自查用的技术判据:`fwloop doctor` 的仪器深检项 `checks.instruments` —— `status=ok`,且 `libusb_bound` 中该仪器的 `service` 为 `libusb0`/`libusbK`。
|
|
131
|
+
>
|
|
132
|
+
> **为什么"能扫到"不等于"能用"**:驱动绑定不对时 `sigrok-cli --scan` 依然列得出设备,但采集初始化会失败在
|
|
133
|
+
> `Failed to receive reply to EP1 command 0x7d: LIBUSB_ERROR_IO`。原理与三个高频坑(换 USB 口后需重绑、
|
|
134
|
+
> 拔插后需重试一次、阈值要匹配被测电平)详见下文 **《前置条件:仪器接入(Windows)》**。
|
|
135
|
+
|
|
136
|
+
**装完后**:重启 AI Agent,先让它跑一次环境检查(`fw_doctor`,它会用人话汇报每台仪器/串口能不能用、缺什么怎么补),再操作 NdtBox
|
|
137
|
+
(状态检查 / 数据采集 / 固件烧录 / 抓波形——抓波形前按上表确认逻辑分析仪驱动已就绪)。
|
|
116
138
|
若还要在某个单片机工程里做编译 / 烧录 / HIL 测试,进入该工程根目录执行一次 `fwloop init`(每个新工程一次)。
|
|
117
139
|
|
|
118
140
|
---
|
|
@@ -132,6 +154,36 @@ uv tool install agentic-hil
|
|
|
132
154
|
|
|
133
155
|
---
|
|
134
156
|
|
|
157
|
+
### 前置条件:仪器接入(Windows)
|
|
158
|
+
|
|
159
|
+
框架通过 libusb / VCP 类后端访问 USB 逻辑分析仪、USB 转 IIC/UART 桥等仪器。
|
|
160
|
+
**首次在这台电脑使用某台仪器、或换过 USB 端口之后**,请先确认驱动绑定——这是"仪器打不开"最常见的原因:
|
|
161
|
+
|
|
162
|
+
| 仪器类别 | 需要什么 | 自查方法 | 装错/没装时的症状 |
|
|
163
|
+
|---|---|---|---|
|
|
164
|
+
| USB 逻辑分析仪(sigrok/Saleae 类,含 FX2/EZ-USB 固件上传型) | 绑定到 libusb 类驱动(`libusb-win32`,或 `WinUSB`) | 最直接:让它抓一次波形,能抓到就行;手工核对:设备管理器 → 设备 → 属性 → 驱动程序/服务(应显示 `libusb-win32` / `libusb0` / `libusbK` / `WinUSB`);也可让 Agent 读 `fwloop doctor` 的仪器深检项 | 采集报 `Failed to open device.`;初始化阶段报 `... EP1 command ... LIBUSB_ERROR_IO` |
|
|
165
|
+
| USB 转 IIC/UART 桥(CH340/CH341、CP210x、FTDI…) | 厂商 VCP 驱动 | 出现 COM 口,`fwloop doctor` 的 `com_ports` 能列出 | 端口不存在 / 打开报占用 |
|
|
166
|
+
| 蓝牙或 ELTIMA 等虚拟串口 | 不作为被测口 | `fwloop doctor` 会把虚拟口单独列出来(不与真实口混在一起) | 能打开但永远无数据 |
|
|
167
|
+
|
|
168
|
+
**用 Zadig 给逻辑分析仪绑定驱动(人工一次,需管理员)**
|
|
169
|
+
|
|
170
|
+
1. 关闭一切可能占用该设备的软件(厂商上位机、PulseView、Saleae Logic 2 等)——**独占是前提**。
|
|
171
|
+
2. 管理员运行 Zadig(sigrok 安装目录自带 `zadig.exe`;也可用官方包)→ `Options → List All Devices`。
|
|
172
|
+
3. 选中**当前在线**的那台设备(按 VID/PID 核对;忽略"幽灵"残留节点),目标驱动选 `WinUSB` → `Replace Driver`。
|
|
173
|
+
4. **拔插一次**设备,再让 Agent 重试。
|
|
174
|
+
5. 若仍打不开、或初始化阶段报 EP1/命令无应答:对该设备改绑 `libusb-win32` 再试(两者互为 A/B 对照)。
|
|
175
|
+
|
|
176
|
+
**三个会反复踩的坑**
|
|
177
|
+
|
|
178
|
+
- 驱动绑定**跟随 USB 端口实例**:换一个 USB 口 = 新的设备实例,Windows 可能重新绑回默认驱动 → 需对该实例重做一次 Zadig。
|
|
179
|
+
- 拔插会**重置设备状态**:刚初始化的设备拔插后要重新初始化;首次打开报"等待设备重启 / 初始化失败"时,等 3–5 秒重试一次通常即可。
|
|
180
|
+
- **阈值/量程必须覆盖被测电平**:采集前确认被测逻辑电平落在仪器档位内(例:1.8 V 逻辑需选覆盖 1.4–3.6 V 的档位,而不是 0.7–1.4 V;示波器注意探针 1x/10x 衰减比)。
|
|
181
|
+
|
|
182
|
+
> 驱动安装需要管理员权限与设备选择,误绑会影响其它软件,因此框架**不自动安装驱动**,只做「检测 → 指引 → 复验」:
|
|
183
|
+
> `fwloop doctor` 会报告每台仪器当前的就绪状态**和下一步该怎么修**(Agent 读的也是同一份内容)。公司交付包覆盖的环境由安装器代做(见 [`Fwloop_setup_pack/README.md`](Fwloop_setup_pack/README.md))。
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
135
187
|
### 可选:接入 NdtBox 调试盒(公司内部 USB→IIC 调试工具)
|
|
136
188
|
|
|
137
189
|
如需用 Agent 直接操作 NdtBox(固件寄存器读写 / 数据采集 / 逻辑分析仪协议验证),安装后执行一次:
|
|
@@ -156,7 +208,7 @@ fwloop ndtdebugtool "C:/Users/weilin.zhang/Desktop/zwl/NdtDebugTool-v1.0.19"
|
|
|
156
208
|
**前置要求:**
|
|
157
209
|
|
|
158
210
|
- **CH341 驱动**:首次在这台电脑使用 NdtBox 时,运行交付包内 `assets\NDTBoxDriver\CH341PAR.EXE`(USB 转 IIC);COM 串口场景另装 `CH341SER.EXE`
|
|
159
|
-
- **Saleae 波形证据**(可选):Saleae Logic16
|
|
211
|
+
- **Saleae 波形证据**(可选):Saleae Logic16 固件落位 `%LOCALAPPDATA%\sigrok-firmware` + sigrok-cli;**驱动绑定(Zadig)见上文《前置条件:仪器接入(Windows)》**——交付包一键安装器会自动完成这两步,手工部署详见 [`Fwloop_setup_pack/README.md`](Fwloop_setup_pack/README.md)
|
|
160
212
|
- **USB 独占**:测试时退出 NdtDebugTool 上位机 STDataCollection.exe(同时打开会互踢)
|
|
161
213
|
|
|
162
214
|
---
|
|
@@ -233,7 +285,7 @@ fwloop init
|
|
|
233
285
|
|---|---|---|---|
|
|
234
286
|
| **`fwloop setup`** | **系统全局级** | 给各大 Agent(Antigravity / Claude Code / Qoder / Qoder CN / CodeBuddy)配置全局 MCP 与同步技能包 | **全电脑只需跑 1 次** |
|
|
235
287
|
| **`fwloop init`** | **工程项目级** | 在当前单片机代码目录下生成 `AGENTS.md`、`GEMINI.md`、`CLAUDE.md` 与台架配置 | **每个新单片机项目跑 1 次** |
|
|
236
|
-
| **`fwloop doctor`** | **环境诊断** |
|
|
288
|
+
| **`fwloop doctor`** | **环境诊断** | 一屏人话摘要:核心工具链是否正常、仪器能不能用(逻辑分析仪/串口/探针…)、缺什么怎么补。加 `--json` 看原始数据 | 随时排查环境时使用 |
|
|
237
289
|
| **`fwloop update`** | **自动更新** | 一键自动拉取最新代码并热重载依赖 | 升级工具版本时使用 |
|
|
238
290
|
|
|
239
291
|
---
|
|
@@ -309,7 +361,7 @@ fwloop update
|
|
|
309
361
|
|
|
310
362
|
3. 环境健康体检与依赖诊断:
|
|
311
363
|
```bash
|
|
312
|
-
fwloop doctor
|
|
364
|
+
fwloop doctor # 人话摘要; 需要原始数据时另加 --json
|
|
313
365
|
```
|
|
314
366
|
|
|
315
367
|
4. 查看或生成各大 Agent MCP 注册指令:
|
|
@@ -387,7 +439,7 @@ claude mcp remove --scope user agentic-hil
|
|
|
387
439
|
├── demo-firmware/ 示例固件(CMake;宿主编译模拟 MCU,闭环验证载体)
|
|
388
440
|
├── demo-make/ 示例固件(Make;构建测试载体)
|
|
389
441
|
├── docs/ DEPENDENCY_MATRIX / REUSE_PLAN / V0.0.2_GAP_VERIFICATION
|
|
390
|
-
├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.
|
|
442
|
+
├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.11.1)
|
|
391
443
|
├── .mcp.example.json 双层 MCP 配置模板(firmwareloop + agentic-hil)
|
|
392
444
|
├── AGENTS.md 通用智能体规范(Antigravity / Qoder / Cursor 等)
|
|
393
445
|
├── CLAUDE.md Claude Code CLI 指南
|
|
@@ -397,7 +449,7 @@ claude mcp remove --scope user agentic-hil
|
|
|
397
449
|
|
|
398
450
|
---
|
|
399
451
|
|
|
400
|
-
## 能力验证状态(v0.
|
|
452
|
+
## 能力验证状态(v0.11.1)
|
|
401
453
|
|
|
402
454
|
> 状态定义:`Implemented`(已实现)/ `Simulator Validated`(模拟验证)/
|
|
403
455
|
> `Real Hardware Validated`(真机验证)/ `Experimental` / `Not Implemented`
|
|
@@ -17,6 +17,7 @@ tools/flash.ps1
|
|
|
17
17
|
tools/fw_mcp_server.py
|
|
18
18
|
tools/instrument_cli.py
|
|
19
19
|
tools/logic_capture.ps1
|
|
20
|
+
tools/logic_capture_summary.py
|
|
20
21
|
tools/logic_decode.ps1
|
|
21
22
|
tools/ndtdbg_bridge.ps1
|
|
22
23
|
tools/ndtdbg_cli.py
|
|
@@ -30,9 +31,11 @@ tools/common/build-backends.psm1
|
|
|
30
31
|
tools/common/fw.psm1
|
|
31
32
|
tools/common/uart_probe.py
|
|
32
33
|
tools/lib/__init__.py
|
|
34
|
+
tools/lib/doctor_summary.py
|
|
33
35
|
tools/lib/instruments.py
|
|
34
36
|
tools/lib/ndtdbg.py
|
|
35
37
|
tools/lib/serial_assistant.py
|
|
38
|
+
tools/lib/session_run.py
|
|
36
39
|
tools/templates/lab.example.yaml
|
|
37
40
|
tools/templates/skill-firmwareloop.md
|
|
38
41
|
tools/templates/skill-fwloop-adapter.md
|
|
@@ -49,8 +49,9 @@ $repoRoot = Get-FwRepoRoot
|
|
|
49
49
|
$sw = [System.Diagnostics.Stopwatch]::StartNew()
|
|
50
50
|
|
|
51
51
|
function Exit-WithError {
|
|
52
|
-
|
|
53
|
-
$
|
|
52
|
+
# v0.11.0: -Remedy 透传到 New-FwError (未给则按 error_class 取默认建议)
|
|
53
|
+
param([string]$Class, [string]$Message, [string]$Detail, [string]$Remedy)
|
|
54
|
+
$body = New-FwError -ErrorClass $Class -Message $Message -Detail $Detail -Remedy $Remedy
|
|
54
55
|
if ($Json) { Write-FwJson $body -Compact } else { Write-FwJson $body; Write-Error "$Class : $Message" -ErrorAction Continue }
|
|
55
56
|
exit 2
|
|
56
57
|
}
|
|
@@ -39,22 +39,25 @@ $repoRoot = Get-FwRepoRoot
|
|
|
39
39
|
$stamp = Get-Date -Format 'yyyyMMdd-HHmmss'
|
|
40
40
|
|
|
41
41
|
function Exit-WithError {
|
|
42
|
-
|
|
43
|
-
$
|
|
42
|
+
# v0.11.0: -Remedy 透传到 New-FwError (未给则按 error_class 取默认建议)
|
|
43
|
+
param([string]$Class, [string]$Message, [string]$Detail, [string]$Remedy)
|
|
44
|
+
$body = New-FwError -ErrorClass $Class -Message $Message -Detail $Detail -Remedy $Remedy
|
|
44
45
|
if ($Json) { Write-FwJson $body -Compact } else { Write-FwJson $body; Write-Error "$Class : $Message" -ErrorAction Continue }
|
|
45
46
|
exit 2
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
# CAN TX default requires explicit authorization (Spec §12: 人工授权)
|
|
49
50
|
if ($Command -eq 'send' -and -not $Authorized) {
|
|
50
|
-
Exit-WithError -Class 'PERMISSION_DENIED' -Message 'CAN TX requires explicit human authorization; pass -Authorized after approval (Spec §12/§24).'
|
|
51
|
+
Exit-WithError -Class 'PERMISSION_DENIED' -Message 'CAN TX requires explicit human authorization; pass -Authorized after approval (Spec §12/§24).' `
|
|
52
|
+
-Remedy 'CAN TX 属需授权操作: 取得人工批准后加 -Authorized 重跑; 只读场景用 read/session-start'
|
|
51
53
|
}
|
|
52
54
|
|
|
53
55
|
$cmd = Get-Command agentic-hil -ErrorAction SilentlyContinue
|
|
54
56
|
$tool = if ($cmd) { $cmd.Source } else { $null }
|
|
55
57
|
|
|
56
58
|
if ($Backend -eq 'agentic-hil' -and -not $tool) {
|
|
57
|
-
Exit-WithError -Class 'PROBE_NOT_FOUND' -Message "'agentic-hil' is not installed; CAN is not available until Agentic HIL is installed (Spec §32)." -Detail 'Install Agentic HIL, then verify its CAN schema with: agentic-hil --help'
|
|
59
|
+
Exit-WithError -Class 'PROBE_NOT_FOUND' -Message "'agentic-hil' is not installed; CAN is not available until Agentic HIL is installed (Spec §32)." -Detail 'Install Agentic HIL, then verify its CAN schema with: agentic-hil --help' `
|
|
60
|
+
-Remedy 'uv tool install agentic-hil (或 uv pip install agentic-hil), 然后 fwloop setup 注册 MCP; 复核: fwloop doctor 的 agentic_hil 项'
|
|
58
61
|
}
|
|
59
62
|
|
|
60
63
|
# Resolve lab config for adapter/channel/bitrate defaults (never hardcoded)
|
|
@@ -26,8 +26,9 @@ Import-Module (Join-Path $PSScriptRoot 'common\fw.psm1') -Force
|
|
|
26
26
|
$repoRoot = Get-FwRepoRoot
|
|
27
27
|
|
|
28
28
|
function Exit-WithError {
|
|
29
|
-
|
|
30
|
-
$
|
|
29
|
+
# v0.11.0: -Remedy 透传到 New-FwError (未给则按 error_class 取默认建议)
|
|
30
|
+
param([string]$Class, [string]$Message, [string]$Detail, [string]$Remedy)
|
|
31
|
+
$body = New-FwError -ErrorClass $Class -Message $Message -Detail $Detail -Remedy $Remedy
|
|
31
32
|
if ($Json) { Write-FwJson $body -Compact } else { Write-FwJson $body; Write-Error "$Class : $Message" -ErrorAction Continue }
|
|
32
33
|
exit 2
|
|
33
34
|
}
|
|
@@ -5,12 +5,27 @@
|
|
|
5
5
|
Set-StrictMode -Version Latest
|
|
6
6
|
$ErrorActionPreference = 'Stop'
|
|
7
7
|
|
|
8
|
+
# --- 输出编码 (v0.9.2 中央化) ---------------------------------------------------
|
|
9
|
+
# 面向 agent/管道消费: 统一 UTF-8。中文 Windows 默认码页是 CP936, 脚本若不显式设置,
|
|
10
|
+
# stdout 会按本地码页写出, 消费端 (MCP run_process / Agent shell) 按 UTF-8 解码即得
|
|
11
|
+
# "鎺掑簭" 型 mojibake。此前只有 3/13 个脚本各自设置过, 改为本模块加载时一次性覆盖:
|
|
12
|
+
# 所有脚本都 Import-Module 本模块, 一处生效; 子进程 (python) 同编码。
|
|
13
|
+
try { [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 } catch { }
|
|
14
|
+
try { $global:OutputEncoding = [System.Text.Encoding]::UTF8 } catch { }
|
|
15
|
+
$env:PYTHONIOENCODING = 'utf-8'
|
|
16
|
+
|
|
8
17
|
# --- Error Classes (Spec §22 + v0.0.2 §24 additions) --------------------------
|
|
9
18
|
$script:FW_ERROR_CLASSES = @(
|
|
10
19
|
'BUILD_ERROR', 'ARTIFACT_NOT_FOUND', 'PROBE_NOT_FOUND', 'TARGET_MISMATCH',
|
|
11
20
|
'FLASH_ERROR', 'FLASH_VERIFY_ERROR', 'RESET_ERROR', 'UART_TIMEOUT',
|
|
12
21
|
'UART_BUSY', 'CAN_ERROR', 'DEBUGGER_ERROR', 'LOGIC_CAPTURE_ERROR',
|
|
22
|
+
# v0.11.1: 与 AI_DEV_GUIDE §4 清单对齐 —— 文档列过但白名单没有的类会让 PS 侧透传
|
|
23
|
+
# 直接抛 "Illegal error class", 反而破坏"始终给结构化信封"的契约 (实测 2026-09-14)。
|
|
24
|
+
'SERIAL_PORT_ERROR', 'PROTOCOL_ERROR', 'PROTOCOL_DESYNC', 'BOOT_NOT_ENTERED',
|
|
25
|
+
'INCOMPLETE_FLASH', 'COLD_BOOT_VERIFY_FAILED',
|
|
13
26
|
'INSTRUMENT_NOT_FOUND', 'INSTRUMENT_TIMEOUT', 'MEASUREMENT_OUT_OF_RANGE',
|
|
27
|
+
# v0.11.1: 仪器接入(驱动绑定/占用/阈值) —— 与 README《前置条件: 仪器接入》成对
|
|
28
|
+
'INSTRUMENT_DRIVER_BINDING', 'INSTRUMENT_BUSY', 'INSTRUMENT_THRESHOLD_MISMATCH',
|
|
14
29
|
'TEST_FAILED', 'PERMISSION_DENIED', 'SAFETY_LIMIT', 'CONFIG_ERROR',
|
|
15
30
|
'TOOL_MISSING', 'UNKNOWN_ERROR',
|
|
16
31
|
# v0.0.2 additions (Gap spec §24)
|
|
@@ -18,6 +33,98 @@ $script:FW_ERROR_CLASSES = @(
|
|
|
18
33
|
'HARDWARE_GATE_BYPASSED', 'REAL_HARDWARE_REQUIRED', 'HARDWARE_VALIDATION_FAILED'
|
|
19
34
|
)
|
|
20
35
|
|
|
36
|
+
# --- Error Class → remedy (v0.11.0) -------------------------------------------
|
|
37
|
+
# 结构化错误必须给出"下一步做什么": Agent 按 error_class 决策, 不该靠猜日志/翻源码。
|
|
38
|
+
# 此处是**默认文案**的唯一维护点; 具体调用点可用 -Remedy 覆盖成更精确的建议
|
|
39
|
+
# (例: logic_capture 的 sigrok 缺失 → 直接给安装指引)。
|
|
40
|
+
$script:FW_ERROR_REMEDIES = [ordered]@{
|
|
41
|
+
'BUILD_ERROR' = '先修 detail 里第一条编译诊断 (file:line), 再 fw_build 重跑; 需要干净重来用 clean=true'
|
|
42
|
+
'ARTIFACT_NOT_FOUND' = '先 fw_build 产出固件, 并核对 fw_doctor 的 lab_yaml 项 (source/artifact 路径与后端)'
|
|
43
|
+
'PROBE_NOT_FOUND' = '接好调试探针 (ST-Link/J-Link/CMSIS-DAP) 并确认 USB 可见; fw_scan_hardware 可复核'
|
|
44
|
+
'TARGET_MISMATCH' = '目标不符已拦截 (正确行为): 复核芯片型号与 lab.yaml 的 expected_target, 不要绕过校验'
|
|
45
|
+
'FLASH_ERROR' = '确认目标已进入 BOOT 且停止运行, 检查供电与探针接线后重试; 细节看 detail'
|
|
46
|
+
'FLASH_VERIFY_ERROR' = '烧录后校验失败: 重试一次; 仍失败查供电/时钟与 flash 算法 (不要降低校验强度)'
|
|
47
|
+
'RESET_ERROR' = '复位失败: 确认复位方式可用 (探针 nRST 或 agentic-hil 掉电复位, 后者需 relay 授权)'
|
|
48
|
+
'UART_TIMEOUT' = '确认波特率/接线与目标确实在输出; 开机打印只在复位瞬间出现, 用 fw_serial_capture 的 power_cycle_off_ms 抓'
|
|
49
|
+
'UART_BUSY' = '会话未打开或端口被占: 先 fw_serial_open; fw_serial_status 可看占用嫌疑名单 (NDT Debug Tool 等)'
|
|
50
|
+
'CAN_ERROR' = '确认适配器/终端电阻与 bitrate; CAN TX 需人工授权后加 -Authorized 重跑'
|
|
51
|
+
'DEBUGGER_ERROR' = '调试会话失败: 确认探针未被 IDE 调试器独占, 并用 fw_doctor 复核 pyocd/openocd 就绪'
|
|
52
|
+
'LOGIC_CAPTURE_ERROR' = '抓取/解码失败: 复核通道映射与接线 (fw_doctor 的 sigrok_cli 项), 必要时加大 duration_ms'
|
|
53
|
+
# v0.11.1: 补齐 AI_DEV_GUIDE §4 列出、但此前既不在白名单也没有 remedy 的类
|
|
54
|
+
'SERIAL_PORT_ERROR' = '串口不存在/被占用/参数非法: 确认设备管理器有该 COM 口且未被上位机占用, 再用 fw_serial_status 复核; 蓝牙/虚拟口不作被测口'
|
|
55
|
+
'PROTOCOL_ERROR' = '协议帧非法(长度/校验/字段越界): 用 fw_logic_capture + 协议注解抓原始帧, 对照协议文档复核; 不要靠放宽校验掩盖'
|
|
56
|
+
'PROTOCOL_DESYNC' = '协议错位/丢帧: 复核波特率或时钟、起始边界与抓取窗口是否覆盖完整事务; 加大窗口或改触发后抓取再判定'
|
|
57
|
+
'BOOT_NOT_ENTERED' = '目标未进入 BOOT/烧录态: 按烧录流程断电→上电进 BOOT, 并确认 BOOT 引脚/时序与供电; 不要重复同一时序期待不同结果'
|
|
58
|
+
'INCOMPLETE_FLASH' = '芯片处于半擦写态(内容不可信): 停并整片重烧, 回读校验通过后再使用; 不要在此基础上跑功能测试'
|
|
59
|
+
'COLD_BOOT_VERIFY_FAILED' = '字节校验已过但断电重上电后无有效应答: 属"烧进去了但跑不起来", 按冷启动路径排查(时钟/复位/看门狗), 或用 cold_boot_expect 指定期望值复验'
|
|
60
|
+
'INSTRUMENT_DRIVER_BINDING' = '打开失败/初始化命令无应答(如 EP1 超时): 停, 按 README《前置条件: 仪器接入》用 Zadig 重绑驱动 (WinUSB <-> libusb-win32 互为 A/B), 装完拔插一次再复验; 禁止伪造数据或静默降级 simulator'
|
|
61
|
+
'INSTRUMENT_BUSY' = '仪器被占用: 关闭占用软件(厂商上位机/PulseView/Logic 2 等), 先跑 fw_doctor 复核 instruments 段, 再重试原操作'
|
|
62
|
+
'INSTRUMENT_THRESHOLD_MISMATCH' = '采集成功但解码为空且通道无跳变: 核对探针位置、共地与阈值档位, 用每通道活动摘要定位未接上的信号; 不得把没有数据当成功能正常'
|
|
63
|
+
'INSTRUMENT_NOT_FOUND' = '未发现 VISA 仪器: 确认 USB/网口可见 (python -m pyvisa info) 且 lab/limits.yaml 声明了资源名'
|
|
64
|
+
'INSTRUMENT_TIMEOUT' = '仪器无响应: 加大 timeout 并确认远端未被 NI-MAX/上位机独占'
|
|
65
|
+
'MEASUREMENT_OUT_OF_RANGE' = '读数越界: 检查量程与接线是否符合目标规格; 不要让 limits 被改动后重试同一操作'
|
|
66
|
+
'TEST_FAILED' = '看失败用例与 evidence (uart.log/measurements.json/采集文件): 先复现单例, 再改实现'
|
|
67
|
+
'PERMISSION_DENIED' = '该操作需人工授权: 按 detail 说明取得授权 (confirm/write_allowed/-Authorized) 后重试'
|
|
68
|
+
'SAFETY_LIMIT' = '安全限值拦截: 复核 lab/limits.yaml 与目标规格; 禁止改限值后重试同一操作'
|
|
69
|
+
'CONFIG_ERROR' = '配置缺失或非法: 按 detail 补齐 lab.yaml (fwloop init 生成模板) 或显式传入参数'
|
|
70
|
+
'TOOL_MISSING' = '外部工具缺失: 按 detail 安装并加入 PATH, 然后 fwloop doctor 复核该项'
|
|
71
|
+
'UNKNOWN_ERROR' = '未归类错误: 保留 detail 原文与复现命令, 用 fw_doctor 采集环境快照后上报'
|
|
72
|
+
'CAPABILITY_NOT_SUPPORTED' = '能力未实现或未启用: 用 detail 给出的替代路径; 需要新能力请登记到 06_TODO'
|
|
73
|
+
'DEPENDENCY_DISCOVERY_REQUIRED' = '需先发现依赖/后端: 跑 fw_doctor (或 tools/test-backends.ps1) 后再决定用哪个后端'
|
|
74
|
+
'HARDWARE_GATE_BYPASSED' = '硬件门被绕过: 立即停止, 复核证据是否真机产出 (simulator 结果不得当真实测量)'
|
|
75
|
+
'REAL_HARDWARE_REQUIRED' = '该操作必须真机: 接好硬件后重跑; 离线演练请显式选择 simulator 后端'
|
|
76
|
+
'HARDWARE_VALIDATION_FAILED' = '硬件校验未过: 对照 detail 的实测值/期望值, 复核接线、供电与目标型号'
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function Get-FwRemedy {
|
|
80
|
+
<#
|
|
81
|
+
.SYNOPSIS
|
|
82
|
+
Default remedy text for an error class (Spec §22). Returns $null when the
|
|
83
|
+
class has no entry — never invent advice.
|
|
84
|
+
#>
|
|
85
|
+
param([Parameter(Mandatory = $true)][string]$ErrorClass)
|
|
86
|
+
if ($script:FW_ERROR_REMEDIES.Contains($ErrorClass)) {
|
|
87
|
+
return [string]$script:FW_ERROR_REMEDIES[$ErrorClass]
|
|
88
|
+
}
|
|
89
|
+
return $null
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
# --- instrument usability (doctor 顶层段与单测共用) ----------------------------
|
|
93
|
+
function Get-FwLogicAnalyzerStatus {
|
|
94
|
+
<#
|
|
95
|
+
.SYNOPSIS
|
|
96
|
+
Derive logic-analyzer usability from backend readiness + device visibility +
|
|
97
|
+
the deep driver-binding verdict. Pure function: no probing, unit-testable.
|
|
98
|
+
.NOTES
|
|
99
|
+
v0.11.1 (现场反馈 2026-09-14): "sigrok-cli --scan 能看到设备" ≠ "能采集"——
|
|
100
|
+
FX2 类设备绑在 WinUSB 上时照样可枚举, 但初始化会失败在 EP1 命令 (LIBUSB_ERROR_IO)。
|
|
101
|
+
故引入第三态 degraded: 设备可见 + 无 libusb 类绑定 ⇒ 必须给改绑建议, 不得报 ready。
|
|
102
|
+
#>
|
|
103
|
+
param(
|
|
104
|
+
[bool]$SigrokOk,
|
|
105
|
+
[bool]$Logic2Ok = $false,
|
|
106
|
+
[int]$DeviceCount = 0,
|
|
107
|
+
[string]$DeepStatus = $null
|
|
108
|
+
)
|
|
109
|
+
$remedyNoBackend = '装 sigrok-cli (https://sigrok.org/wiki/Downloads) 或启动 Saleae Logic 2 (开 10530 MCP), 然后重跑 fwloop doctor'
|
|
110
|
+
$remedyNoDevice = '后端未发现可驱动仪器: 插好仪器并确认供电后重跑; 仍不可见时看 checks.instruments 的 libusb_bound / firmware_dirs (Zadig 绑定, 见 README 前置条件)'
|
|
111
|
+
$remedyBinding = '设备可见但驱动绑定不合格(常见: 仅 WinUSB): 用 Zadig 改绑 libusb-win32, 装完拔插一次再复验; 细节见 README《前置条件: 仪器接入》与 checks.instruments.libusb_bound'
|
|
112
|
+
if (-not ($SigrokOk -or $Logic2Ok)) {
|
|
113
|
+
return [pscustomobject]@{ status = 'missing'; remedy = $remedyNoBackend }
|
|
114
|
+
}
|
|
115
|
+
if (-not $SigrokOk) {
|
|
116
|
+
# 仅 Logic 2 后端: 设备可见性不由 sigrok 提供, 不臆造结论
|
|
117
|
+
return [pscustomobject]@{ status = 'ready'; remedy = $null }
|
|
118
|
+
}
|
|
119
|
+
if ($DeviceCount -le 0) {
|
|
120
|
+
return [pscustomobject]@{ status = 'software_only'; remedy = $remedyNoDevice }
|
|
121
|
+
}
|
|
122
|
+
if ($DeepStatus -eq 'warn') {
|
|
123
|
+
return [pscustomobject]@{ status = 'degraded'; remedy = $remedyBinding }
|
|
124
|
+
}
|
|
125
|
+
return [pscustomobject]@{ status = 'ready'; remedy = $null }
|
|
126
|
+
}
|
|
127
|
+
|
|
21
128
|
# --- JSON output --------------------------------------------------------------
|
|
22
129
|
function Write-FwJson {
|
|
23
130
|
<#
|
|
@@ -55,11 +162,16 @@ function New-FwError {
|
|
|
55
162
|
.SYNOPSIS
|
|
56
163
|
Deterministic failure envelope. Every external-process failure must
|
|
57
164
|
return one of these (Spec Rule: every operation returns structured errors).
|
|
165
|
+
.NOTES
|
|
166
|
+
v0.11.0: the `remedy` key is always present (explicit -Remedy > class
|
|
167
|
+
default from FW_ERROR_REMEDIES > $null) so callers/agents never have to
|
|
168
|
+
guess the next step; 形状固定也避免 PS StrictMode 下缺键访问抛错。
|
|
58
169
|
#>
|
|
59
170
|
param(
|
|
60
171
|
[Parameter(Mandatory = $true)][string]$ErrorClass,
|
|
61
172
|
[Parameter(Mandatory = $true)][string]$Message,
|
|
62
173
|
[string]$Detail = $null,
|
|
174
|
+
[string]$Remedy = $null,
|
|
63
175
|
[int]$ExitCode = 1
|
|
64
176
|
)
|
|
65
177
|
Get-FwErrorClass $ErrorClass | Out-Null
|
|
@@ -69,6 +181,7 @@ function New-FwError {
|
|
|
69
181
|
error = $Message
|
|
70
182
|
}
|
|
71
183
|
if ($Detail) { $body.detail = $Detail }
|
|
184
|
+
$body.remedy = if ($Remedy) { $Remedy } else { Get-FwRemedy -ErrorClass $ErrorClass }
|
|
72
185
|
[pscustomobject]$body
|
|
73
186
|
}
|
|
74
187
|
|
|
@@ -332,5 +445,6 @@ function Get-FwLabConfig {
|
|
|
332
445
|
}
|
|
333
446
|
|
|
334
447
|
Export-ModuleMember -Function Write-FwJson, Get-FwErrorClass, New-FwError, `
|
|
448
|
+
Get-FwRemedy, Get-FwLogicAnalyzerStatus, `
|
|
335
449
|
Resolve-FwPython, Get-FwRepoRoot, Save-FwLog, Get-FwTimestamp, `
|
|
336
450
|
Get-FwRunId, Get-FwGitInfo, Get-FwDiagnostics, Invoke-FwProcess, Get-FwLabConfig
|