firmwareloop 0.3.0__tar.gz → 0.4.0__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.
Files changed (36) hide show
  1. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/PKG-INFO +3 -3
  2. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/README.md +2 -2
  3. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/firmwareloop.egg-info/PKG-INFO +3 -3
  4. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/pyproject.toml +1 -1
  5. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/__init__.py +1 -1
  6. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/fw_mcp_server.py +104 -7
  7. firmwareloop-0.4.0/tools/lib/ndtdbg.py +794 -0
  8. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/ndtdbg_bridge.ps1 +99 -2
  9. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/setup-agent-mcp.ps1 +2 -2
  10. firmwareloop-0.3.0/tools/lib/ndtdbg.py +0 -542
  11. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/LICENSE +0 -0
  12. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/firmwareloop.egg-info/SOURCES.txt +0 -0
  13. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/firmwareloop.egg-info/dependency_links.txt +0 -0
  14. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/firmwareloop.egg-info/entry_points.txt +0 -0
  15. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/firmwareloop.egg-info/requires.txt +0 -0
  16. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/firmwareloop.egg-info/top_level.txt +0 -0
  17. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/setup.cfg +0 -0
  18. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/acceptance-scenario.ps1 +0 -0
  19. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/build.ps1 +0 -0
  20. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/can.ps1 +0 -0
  21. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/check-qoder-mcp.ps1 +0 -0
  22. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/common/build-backends.psm1 +0 -0
  23. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/common/fw.psm1 +0 -0
  24. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/common/uart_probe.py +0 -0
  25. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/doctor.ps1 +0 -0
  26. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/flash.ps1 +0 -0
  27. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/instrument_cli.py +0 -0
  28. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/lib/__init__.py +0 -0
  29. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/lib/instruments.py +0 -0
  30. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/logic_capture.ps1 +0 -0
  31. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/logic_decode.ps1 +0 -0
  32. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/ndtdbg_cli.py +0 -0
  33. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/reset.ps1 +0 -0
  34. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/sigrok_csv_to_fwloop.py +0 -0
  35. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/test-backends.ps1 +0 -0
  36. {firmwareloop-0.3.0 → firmwareloop-0.4.0}/tools/test.ps1 +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: firmwareloop
3
- Version: 0.3.0
3
+ Version: 0.4.0
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
@@ -381,7 +381,7 @@ claude mcp remove --scope user agentic-hil
381
381
  ├── demo-firmware/ 示例固件(CMake;宿主编译模拟 MCU,闭环验证载体)
382
382
  ├── demo-make/ 示例固件(Make;构建测试载体)
383
383
  ├── docs/ DEPENDENCY_MATRIX / REUSE_PLAN / V0.0.2_GAP_VERIFICATION
384
- ├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.3.0)
384
+ ├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.4.0)
385
385
  ├── .mcp.example.json 双层 MCP 配置模板(firmwareloop + agentic-hil)
386
386
  ├── AGENTS.md 通用智能体规范(Antigravity / Qoder / Cursor 等)
387
387
  ├── CLAUDE.md Claude Code CLI 指南
@@ -391,7 +391,7 @@ claude mcp remove --scope user agentic-hil
391
391
 
392
392
  ---
393
393
 
394
- ## 能力验证状态(v0.3.0)
394
+ ## 能力验证状态(v0.4.0)
395
395
 
396
396
  > 状态定义:`Implemented`(已实现)/ `Simulator Validated`(模拟验证)/
397
397
  > `Real Hardware Validated`(真机验证)/ `Experimental` / `Not Implemented`
@@ -353,7 +353,7 @@ claude mcp remove --scope user agentic-hil
353
353
  ├── demo-firmware/ 示例固件(CMake;宿主编译模拟 MCU,闭环验证载体)
354
354
  ├── demo-make/ 示例固件(Make;构建测试载体)
355
355
  ├── docs/ DEPENDENCY_MATRIX / REUSE_PLAN / V0.0.2_GAP_VERIFICATION
356
- ├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.3.0)
356
+ ├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.4.0)
357
357
  ├── .mcp.example.json 双层 MCP 配置模板(firmwareloop + agentic-hil)
358
358
  ├── AGENTS.md 通用智能体规范(Antigravity / Qoder / Cursor 等)
359
359
  ├── CLAUDE.md Claude Code CLI 指南
@@ -363,7 +363,7 @@ claude mcp remove --scope user agentic-hil
363
363
 
364
364
  ---
365
365
 
366
- ## 能力验证状态(v0.3.0)
366
+ ## 能力验证状态(v0.4.0)
367
367
 
368
368
  > 状态定义:`Implemented`(已实现)/ `Simulator Validated`(模拟验证)/
369
369
  > `Real Hardware Validated`(真机验证)/ `Experimental` / `Not Implemented`
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: firmwareloop
3
- Version: 0.3.0
3
+ Version: 0.4.0
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
@@ -381,7 +381,7 @@ claude mcp remove --scope user agentic-hil
381
381
  ├── demo-firmware/ 示例固件(CMake;宿主编译模拟 MCU,闭环验证载体)
382
382
  ├── demo-make/ 示例固件(Make;构建测试载体)
383
383
  ├── docs/ DEPENDENCY_MATRIX / REUSE_PLAN / V0.0.2_GAP_VERIFICATION
384
- ├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.3.0)
384
+ ├── pyproject.toml 标准 Python 包配置与 CLI 入口声明 (v0.4.0)
385
385
  ├── .mcp.example.json 双层 MCP 配置模板(firmwareloop + agentic-hil)
386
386
  ├── AGENTS.md 通用智能体规范(Antigravity / Qoder / Cursor 等)
387
387
  ├── CLAUDE.md Claude Code CLI 指南
@@ -391,7 +391,7 @@ claude mcp remove --scope user agentic-hil
391
391
 
392
392
  ---
393
393
 
394
- ## 能力验证状态(v0.3.0)
394
+ ## 能力验证状态(v0.4.0)
395
395
 
396
396
  > 状态定义:`Implemented`(已实现)/ `Simulator Validated`(模拟验证)/
397
397
  > `Real Hardware Validated`(真机验证)/ `Experimental` / `Not Implemented`
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "firmwareloop"
7
- version = "0.3.0"
7
+ version = "0.4.0"
8
8
  description = "AI Agent Firmware Development and Lab Automation Platform (Dual-Tier MCP Server)"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -2,4 +2,4 @@
2
2
  FirmwareLoop - AI Agent Firmware Development and Lab Automation Platform.
3
3
  """
4
4
 
5
- __version__ = "0.3.0"
5
+ __version__ = "0.4.0"
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- fw_mcp_server.py - FirmwareLoop High-Level Workflow & Device MCP Server (v0.3.0).
3
+ fw_mcp_server.py - FirmwareLoop High-Level Workflow & Device MCP Server (v0.4.0).
4
4
 
5
5
  Exposes high-level firmware engineering and hardware management tools to AI Coding
6
6
  Agents (Antigravity CLI, Claude Code CLI, Qoder IDE, CodeBuddy IDE, Cursor) via the Model Context
@@ -1626,7 +1626,7 @@ def process_request(req: Dict[str, Any]) -> Optional[Dict[str, Any]]:
1626
1626
  },
1627
1627
  "serverInfo": {
1628
1628
  "name": "firmwareloop",
1629
- "version": "0.3.0"
1629
+ "version": "0.4.0"
1630
1630
  }
1631
1631
  }
1632
1632
  }
@@ -1761,7 +1761,7 @@ def _settle_stashed_entrypoints(stashed) -> None:
1761
1761
  def handle_cli_update() -> int:
1762
1762
  """Handle `firmwareloop update` command."""
1763
1763
  print("============================================================")
1764
- print(" FirmwareLoop Auto-Updater (v0.3.0)")
1764
+ print(" FirmwareLoop Auto-Updater (v0.4.0)")
1765
1765
  print("============================================================")
1766
1766
 
1767
1767
  is_git_repo = os.path.exists(os.path.join(REPO_ROOT, ".git"))
@@ -1830,6 +1830,100 @@ def handle_cli_update() -> int:
1830
1830
  return res.returncode
1831
1831
 
1832
1832
 
1833
+ def handle_cli_selftest(target: str = "ndtdbg") -> int:
1834
+ """`fwloop selftest ndtdbg`: 按 BACKLOG 验收标准自动回归 (需硬件在环)。
1835
+
1836
+ 流程: status 分层探测 -> stream 冒烟 (100ms x 10s, 帧守恒/性能线/gaps 断言) ->
1837
+ 写读回环 (write_allowed 双门内, 未授权 SKIP) -> 结构化汇总。任一 FAIL 则 exit 1。
1838
+ """
1839
+ if target != "ndtdbg":
1840
+ print(f"[-] Unknown selftest target: {target} (supported: ndtdbg)")
1841
+ return 2
1842
+ print("============================================================")
1843
+ print(" FirmwareLoop Self-Test: ndtdbg (BACKLOG 验收标准)")
1844
+ print("============================================================")
1845
+ results: list = []
1846
+
1847
+ def run_cli(*args, timeout=120):
1848
+ cli = os.path.join(REPO_ROOT, "tools", "ndtdbg_cli.py")
1849
+ try:
1850
+ proc = subprocess.run([sys.executable, cli, *args], capture_output=True,
1851
+ text=True, encoding="utf-8", errors="replace", timeout=timeout)
1852
+ except subprocess.TimeoutExpired:
1853
+ return -1, {"ok": False, "error_class": "INSTRUMENT_TIMEOUT",
1854
+ "error": f"子命令超时 >{timeout}s (疑似 USB 会话被残留进程占用或设备挂死)"}
1855
+ body = None
1856
+ for line in reversed((proc.stdout or "").strip().splitlines()):
1857
+ line = line.strip()
1858
+ if line.startswith("{"):
1859
+ try:
1860
+ body = json.loads(line)
1861
+ break
1862
+ except Exception:
1863
+ continue
1864
+ return proc.returncode, body
1865
+
1866
+ def report(name, status, detail=""):
1867
+ results.append((name, status, detail))
1868
+
1869
+ # 1. status 分层探测
1870
+ print("\n[1/4] status 探测 (Box / IIC bus / target chip) ...")
1871
+ rc, body = run_cli("status", timeout=30)
1872
+ if rc == 0 and body and body.get("ok"):
1873
+ data = body.get("data") or {}
1874
+ report("status", "PASS", data.get("summary", ""))
1875
+ else:
1876
+ report("status", "FAIL", (body or {}).get("error_class", f"exit {rc}"))
1877
+
1878
+ # 2. stream 冒烟 (100ms x 10s)
1879
+ print("[2/4] stream 冒烟 (100ms x 10s, int16 解码) ...")
1880
+ rc, body = run_cli("stream", "--regs", "0xEE:8:ch", "--interval-ms", "100",
1881
+ "--duration-s", "10", "--decode", "int16le", timeout=60)
1882
+ stream_data = (body or {}).get("data") if isinstance(body, dict) else None
1883
+ if rc == 0 and stream_data:
1884
+ total = stream_data.get("frames_total", 0)
1885
+ conserved = (stream_data.get("frames_ok", 0) + stream_data.get("frames_ff_gap", 0)
1886
+ + stream_data.get("frames_io_fail", 0)) == total
1887
+ avg = stream_data.get("interval_actual_avg_ms")
1888
+ report("stream.frames_conserved", "PASS" if conserved else "FAIL",
1889
+ f"total={total} (ok={stream_data.get('frames_ok')}, "
1890
+ f"ff_gap={stream_data.get('frames_ff_gap')}, io_fail={stream_data.get('frames_io_fail')})")
1891
+ report("stream.interval_perf", "PASS" if (avg is not None and avg <= 110) else "FAIL",
1892
+ f"avg={avg}ms (target 100ms, 验收线 <=110ms)")
1893
+ report("stream.io_overhead", "PASS" if stream_data.get("io_overhead_avg_ms") is not None else "FAIL",
1894
+ f"io_overhead_avg_ms={stream_data.get('io_overhead_avg_ms')}")
1895
+ report("stream.gaps", "PASS", f"gaps_n={stream_data.get('gaps_n', 0)} (仅 >2x target 计数)")
1896
+ else:
1897
+ report("stream", "FAIL", (body or {}).get("error_class", f"exit {rc}"))
1898
+
1899
+ # 3. 写读回环 (write_allowed 双门内; 未授权 SKIP, 不算 FAIL)
1900
+ print("[3/4] 写读回环 (0xBE debug_mode, 需 lab.yaml write_allowed) ...")
1901
+ rc, body = run_cli("write-reg", "--addr", "0xBE", "--data", "01", "--confirm")
1902
+ if rc == 0 and body and body.get("ok"):
1903
+ report("write.readback", "PASS", "0xBE=01 写入成功 (debug_mode 开启)")
1904
+ run_cli("write-reg", "--addr", "0xBE", "--data", "00", "--confirm")
1905
+ report("write.restore", "PASS", "0xBE=00 已恢复")
1906
+ else:
1907
+ err_class = (body or {}).get("error_class", f"exit {rc}")
1908
+ if err_class == "PERMISSION_DENIED":
1909
+ report("write.readback", "SKIP", "write_allowed 未开启 (双门保护), 跳过写回环")
1910
+ else:
1911
+ report("write.readback", "FAIL", err_class)
1912
+
1913
+ # 4. 汇总
1914
+ print("\n============================================================")
1915
+ for name, status, detail in results:
1916
+ print(f" [{status}] {name}" + (f" — {detail}" if detail else ""))
1917
+ failed = [r for r in results if r[1] == "FAIL"]
1918
+ skipped = [r for r in results if r[1] == "SKIP"]
1919
+ overall = "FAIL" if failed else "PASS"
1920
+ print("============================================================")
1921
+ print(f" Self-Test Result: {overall} "
1922
+ f"({len(results) - len(failed) - len(skipped)} pass, {len(failed)} fail, {len(skipped)} skip)")
1923
+ print("============================================================")
1924
+ return 1 if failed else 0
1925
+
1926
+
1833
1927
  def handle_cli_doctor() -> int:
1834
1928
  """Handle `firmwareloop doctor` command."""
1835
1929
  print("[*] Running FirmwareLoop environment diagnostics...")
@@ -2036,7 +2130,7 @@ def set_ndtdbg_dlldir(dll_path: str) -> str:
2036
2130
  def handle_cli_setup() -> int:
2037
2131
  """Handle `firmwareloop setup` command: simultaneously configure Antigravity CLI, Claude Code CLI, Qoder IDE, and CodeBuddy IDE."""
2038
2132
  print("============================================================")
2039
- print(" FirmwareLoop Multi-Agent Global Setup Helper (v0.3.0)")
2133
+ print(" FirmwareLoop Multi-Agent Global Setup Helper (v0.4.0)")
2040
2134
  print("============================================================")
2041
2135
  print("")
2042
2136
 
@@ -2161,7 +2255,7 @@ def handle_cli_setup() -> int:
2161
2255
  def handle_cli_init() -> int:
2162
2256
  """Handle `firmwareloop init` command."""
2163
2257
  print("============================================================")
2164
- print(" FirmwareLoop Multi-Agent Project Initializer (v0.3.0)")
2258
+ print(" FirmwareLoop Multi-Agent Project Initializer (v0.4.0)")
2165
2259
  print("============================================================")
2166
2260
  cwd = os.getcwd()
2167
2261
  print(f"[*] Initializing multi-agent guidelines & bench config in:\n {cwd}\n")
@@ -2182,7 +2276,7 @@ def handle_cli_init() -> int:
2182
2276
 
2183
2277
 
2184
2278
  def print_cli_help() -> None:
2185
- print("""FirmwareLoop (fwloop) — AI Agent Firmware Engineering & Lab Automation Platform (v0.3.0)
2279
+ print("""FirmwareLoop (fwloop) — AI Agent Firmware Engineering & Lab Automation Platform (v0.4.0)
2186
2280
 
2187
2281
  Usage:
2188
2282
  fwloop [command] (or: firmwareloop [command])
@@ -2191,6 +2285,7 @@ Commands:
2191
2285
  init Initialize multi-agent rules (AGENTS.md, CLAUDE.md, GEMINI.md) & lab.yaml in current project
2192
2286
  update Check and update FirmwareLoop to the latest version
2193
2287
  doctor Run environment & toolchain diagnostics
2288
+ selftest [target] Hardware self-test regression (default: ndtdbg; BACKLOG acceptance)
2194
2289
  setup Register AI Agent MCP globally & generate machine-level config (%APPDATA%\\FirmwareLoop\\lab.yaml)
2195
2290
  ndtdebugtool DIR Configure NdtBox: point to the NdtDebugTool folder root (auto-resolves its lib/)
2196
2291
  dlldir DIR Alias of ndtdebugtool (legacy name, pass the lib/ directory directly)
@@ -2212,6 +2307,8 @@ def main() -> None:
2212
2307
  sys.exit(handle_cli_update())
2213
2308
  elif cmd in ["doctor", "check"]:
2214
2309
  sys.exit(handle_cli_doctor())
2310
+ elif cmd == "selftest":
2311
+ sys.exit(handle_cli_selftest(args[1] if len(args) > 1 else "ndtdbg"))
2215
2312
  elif cmd in ["setup", "register"]:
2216
2313
  sys.exit(handle_cli_setup())
2217
2314
  elif cmd in ["ndtdebugtool", "dlldir"]:
@@ -2222,7 +2319,7 @@ def main() -> None:
2222
2319
  sys.exit(2)
2223
2320
  sys.exit(handle_cli_ndtdebugtool(args[1]))
2224
2321
  elif cmd in ["version", "-v", "--version"]:
2225
- print("FirmwareLoop v0.3.0")
2322
+ print("FirmwareLoop v0.4.0")
2226
2323
  sys.exit(0)
2227
2324
  elif cmd in ["help", "-h", "--help"]:
2228
2325
  print_cli_help()