From 872b4fbdc3c607b522211839a6b3b82e18310a1b Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 20 Aug 2026 14:30:59 +0700 Subject: docs: add hardware-in-the-loop rig reference Document the ci and hfp HIL rigs in enough detail to reproduce one: bill of materials with photos, BIOS/IOMMU and vfio-pci passthrough on the Proxmox host, the Renesas uPD720201 firmware install, the guest software and permissions, the one-hub-per-root-port USB topology rule and the per-box split of probe and DUT hubs, how CI drives the rigs, and the operational gotchas. The attached-board table is generated from test/hil/tinyusb.json and test/hil/hfp.json by tools/gen_doc.py into docs/reference/hil_boards.md, which the page includes. Sphinx excludes that partial so it is not also built as an orphan document. Also exclude docs/superpowers/ from the Sphinx build: it holds internal plans, specs and handoffs rather than published documentation, and since nothing references them from a toctree each emitted "document isn't included in any toctree" -- 26 warnings in total, so build_doc.py -W could never pass. It now does. --- tools/gen_doc.py | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++ tools/make_release.py | 1 + 2 files changed, 53 insertions(+) (limited to 'tools') diff --git a/tools/gen_doc.py b/tools/gen_doc.py index 3920531d5..41a60c0b6 100755 --- a/tools/gen_doc.py +++ b/tools/gen_doc.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +import json import re import pandas as pd from tabulate import tabulate @@ -109,9 +110,60 @@ Following boards are supported""" f.write(tabulate(df, headers="keys", tablefmt='rst')) +# ----------------------------------------- +# HIL rig rosters +# ----------------------------------------- +def hil_cell(text): + """A '|' in free-form roster text would silently split the markdown row.""" + return ' '.join((text or '').split()).replace('|', '\\|') + + +def hil_rows(boards): + rows = [] + for b in boards: + tests = b.get('tests', {}) + if 'only' in tests: + roles = sorted({t.split('/')[0] for t in tests['only']}) + else: + roles = [r for r in ('device', 'host', 'dual') if tests.get(r)] + rows.append([ + b['name'], + ', '.join(roles), + b.get('flasher', {}).get('name', ''), + hil_cell(', '.join(v['name'] for v in b.get('variant') or [])), + hil_cell(b.get('comment') or tests.get('comment')), + ]) + return rows + + +def gen_hil_boards_doc(): + tinyusb = json.loads((Path(TOP) / "test/hil/tinyusb.json").read_text()) + hfp = json.loads((Path(TOP) / "test/hil/hfp.json").read_text()) + sections = [ + ("ci rig", "test/hil/tinyusb.json", tinyusb.get('boards', [])), + ("hfp rig", "test/hil/hfp.json", hfp.get('boards', [])), + ] + headers = ['Board', 'Roles', 'Flasher', 'Variants', 'Note'] + + out = ["", ""] + for title, src, boards in sections: + if not boards: + continue + out.append(f"### {title}") + out.append("") + out.append(f"{len(boards)} boards, from `{src}`.") + out.append("") + out.append(tabulate(hil_rows(boards), headers=headers, tablefmt='github')) + out.append("") + + hil_md = Path(TOP) / "docs/reference/hil_boards.md" + hil_md.write_text('\n'.join(out)) + + # ----------------------------------------- # Main # ----------------------------------------- if __name__ == "__main__": gen_deps_doc() gen_boards_doc() + gen_hil_boards_doc() diff --git a/tools/make_release.py b/tools/make_release.py index 65226834f..ec4755f34 100755 --- a/tools/make_release.py +++ b/tools/make_release.py @@ -59,6 +59,7 @@ with open(f_sonar_properties, 'w') as f: # gen docs gen_doc.gen_deps_doc() gen_doc.gen_boards_doc() +gen_doc.gen_hil_boards_doc() # gen presets gen_presets.main() -- cgit v1.3.1