Skip to content
Merged
20 changes: 14 additions & 6 deletions bin/lsusbt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
#
# It also maps each serial back to the TinyUSB HIL board it belongs to, using the
# uids recorded in a boards JSON (default: $HOME/code/tinyusb/test/hil/tinyusb.json).
# A serial matching a board's `uid` is that board acting as a USB device; one
# matching a `flasher.uid` is that board's flasher/debugger. Matches append
# A serial matching a board's `uid` (for a registered board, its registry key or any
# alias) is that board acting as a USB device; one matching its `flasher.uid`
# (agentrc's board registry gives it) is that board's flasher/debugger. Matches append
# `<board> device` or `<board> flasher`.
#
# By default only the lines that resolved to a board are printed, plus root hubs and
Expand Down Expand Up @@ -67,17 +68,24 @@ strip() {
"
}

# Build norm(uid) -> "<board> device|flasher" from the boards JSON.
# Build norm(uid) -> "<board> device|flasher" from the boards JSON, each board's flasher
# from agentrc's board registry (skills/hil/scripts/hil_boards.py).
# A JSON that exists but cannot be read is an error: without its labels the default
# filtered view shows only hubs, which reads as "no boards connected".
declare -A LABEL
if [ -f "$JSON" ]; then
command -v jq >/dev/null 2>&1 || { echo "lsusbt: jq is needed to read $JSON" >&2; exit 1; }
labels=$(jq -r '
hil=$(dirname "$(readlink -f "$0")")/../skills/hil
resolved=$(python3 "$hil/scripts/hil_boards.py" roster "$JSON") ||
{ echo "lsusbt: cannot resolve boards from $JSON" >&2; exit 1; }
# A registered board's device serial may be its registry key or any alias, matched as hil_boards.lookup() does.
labels=$(jq -r --slurpfile reg "$hil/boards.json" '
[$reg[0].boards | to_entries[] | [.key] + (.value.aliases // [])] as $ids |
.boards[] | .name as $n |
(if .uid then [.uid, $n + " device"] | @tsv else empty end),
(if .uid then (.uid as $u | (first($ids[] | select(any(.[]; . == $u))) // [$u])[]
| [., $n + " device"] | @tsv) else empty end),
(if .flasher.uid then [.flasher.uid, $n + " flasher"] | @tsv else empty end)
' "$JSON") || { echo "lsusbt: cannot parse boards from $JSON" >&2; exit 1; }
' <<< "$resolved") || { echo "lsusbt: cannot parse boards from $JSON" >&2; exit 1; }
while IFS=$'\t' read -r uid label; do
[ -n "$uid" ] && LABEL["$(norm "$uid")"]=$label
done <<< "$labels"
Expand Down
19 changes: 19 additions & 0 deletions skills/hil/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,24 @@ Below it only what the table cannot show: held boards with their holders, and
each blocked board with its token or record and that its recovery is a separate
dispatch.

## Board registry

Each rig board is wired to one probe, so how it is flashed is a farm fact, kept once
for every project in `boards.json` beside this page and keyed by the board's `uid`:
its `flasher` and optional `flasher_recover` (the shapes below), its `aliases` (the
other serials the board reports, matched exactly; each firmware forms its own) and a
`name` label. A project roster names the board by `uid` and keeps its own name, lock
name, tests and project fields, never the registry's.

`scripts/hil_boards.py` is the one reader: every consumer that needs a board's
flasher resolves the roster entry through it (`resolve`, `resolve_roster`, or
`hil_boards.py roster FILE`). A registered board's entry that carries a flasher of
its own is refused as a duplicate; an unregistered one (a bench board on a dev PC)
keeps its own, unless its probe is a registered board's; an unregistered entry
without one is refused. A reader that needs only names and lock names reads the
roster raw. A board joins the farm, or its wiring changes, by an agentrc commit to
`boards.json`, then the project's agentrc pin.

## Flashers

A runner that flashes or resets through this skill's `scripts/hil_flash.py`
Expand Down Expand Up @@ -315,6 +333,7 @@ recovery stay the contract's.

| Script | Gives |
|---|---|
| `hil_boards.py` | each board's flasher from the board registry by uid (Board registry above) |
| `hil_load.py` | the one path loader: one module per file per process, a second path under one name refused |
| `hil_process.py` | `run_cmd`, a bounded command; `run_tracked` and `recheck`, a command whose end is proven |
| `hil_farm_check.py` | the farm check engine a project's launcher drives with its profile (Farm check above) |
Expand Down
165 changes: 165 additions & 0 deletions skills/hil/boards.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
{
"boards": {
"FFFF1A00FFFFFFFF1031454E0F000280": {
"name": "frdm_k64f",
"flasher": {"name": "jlink", "uid": "000621000000", "args": "-device MK64FN1M0xxx12"},
"flasher_recover": {"name": "openocd", "args": "-f interface/jlink.cfg -c \"transport select swd\" -f target/k60.cfg -c \"adapter speed 4000\""}
},
"010105186C60A110": {
"name": "ek_tm4c123gxl",
"flasher": {"name": "lm4flash", "uid": "0E205D19", "args": "-v"},
"flasher_recover": {"name": "openocd", "args": "-f interface/ti-icdi.cfg -c \"transport select jtag\" -c \"set WORKAREASIZE 0x8000\" -c \"set CHIPNAME tm4c123gh6pm\" -f target/ti/stellaris.cfg -c \"reset_config none\" -c \"tm4c123gh6pm.cpu configure -event reset-assert-post {sleep 100}\""}
},
"6055F9F98715": {
"name": "espressif_p4_function_ev",
"flasher": {"name": "esptool", "uid": "4ea4f48f6bc3ee11bbb9d00f9e1b1c54", "args": "-b 1500000", "note": "use --force for ESP32-P4 v0.1"}
},
"84F703C084E4": {
"name": "espressif_s3_devkitm",
"flasher": {"name": "esptool", "uid": "3ea619acd1cdeb11a0a0b806e93fd3f1", "args": "-b 1500000"}
},
"2D4F0E6E23EB6724": {
"name": "nrf52840dk",
"flasher": {"name": "jlink", "uid": "683944004", "args": "-device nrf52840_xxaa"},
"flasher_recover": {"name": "openocd", "args": "-f interface/jlink.cfg -c \"transport select swd\" -c \"adapter speed 4000\" -f target/nrf52.cfg"}
},
"0C81464124010B20FF0A08CC2C": {
"name": "max32666fthr",
"aliases": ["0C81464124010B20FF0A08CC2C000000"],
"flasher": {"name": "openocd", "uid": "E6614C311B597D32", "vid_pid": "0x2e8a 0x000c", "args": "-f interface/cmsis-dap.cfg -f target/max32665.cfg", "verify": true}
},
"9995AD485337433231202020FF100A34": {
"name": "metro_m4_express",
"flasher": {"name": "jlink", "uid": "000063728691", "args": "-device ATSAMD51J19"},
"flasher_recover": {"name": "openocd", "args": "-f interface/jlink.cfg -c \"transport select swd\" -c \"adapter speed 4000\" -f target/atsame5x.cfg"}
},
"17121919": {
"name": "lpcxpresso11u37",
"flasher": {"name": "jlink", "uid": "000724441579", "args": "-device LPC11U37/401"},
"flasher_recover": {"name": "openocd", "args": "-f interface/jlink.cfg -c \"transport select swd\" -f target/lpc11xx.cfg -c \"adapter speed 4000\"", "verify": false}
},
"22150C0C1508595343E1857B060000F5": {
"name": "ea4088_quickstart",
"flasher": {"name": "jlink", "uid": "611000000", "args": "-device LPC4088"},
"flasher_recover": {"name": "openocd", "args": "-f interface/jlink.cfg -c \"transport select swd\" -f target/lpc40xx.cfg -c \"adapter speed 4000\"", "verify": false}
},
"E059C3E208F9B955B3BA4C5CC7F3D13D": {
"name": "lpcxpresso55s69",
"flasher": {"name": "jlink", "uid": "000727648789", "args": "-device LPC55S69_M33_0"},
"flasher_recover": {"name": "openocd", "args": "-f interface/jlink.cfg -c \"transport select swd\" -c \"adapter speed 1000\" -c \"swd newdap lpc55s69 cpu -expected-id 0x6ba02477\" -c \"dap create lpc55s69.dap -chain-position lpc55s69.cpu\" -c \"target create lpc55s69.cpu cortex_m -dap lpc55s69.dap -ap-num 0\" -c \"cortex_m reset_config sysresetreq\""}
},
"152E163038303131393346E46F26574B": {
"name": "ra4m1_ek",
"flasher": {"name": "jlink", "uid": "000831174392", "args": "-device R7FA4M1AB"},
"flasher_recover": {"name": "openocd", "args": "-f interface/jlink.cfg -c \"transport select swd\" -c \"adapter speed 1000\" -c \"swd newdap ra4m1 cpu -expected-id 0\" -c \"dap create ra4m1.dap -chain-position ra4m1.cpu\" -c \"target create ra4m1.cpu cortex_m -dap ra4m1.dap\" -c \"cortex_m reset_config sysresetreq\""}
},
"8419032D32363657364EF4622D294B4E": {
"name": "ra6m5_ek",
"flasher": {"name": "jlink", "uid": "000831915224", "args": "-device R7FA6M5BH"},
"flasher_recover": {"name": "openocd", "args": "-f interface/jlink.cfg -c \"transport select swd\" -c \"adapter speed 1000\" -c \"swd newdap ra6m5 cpu -expected-id 0\" -c \"dap create ra6m5.dap -chain-position ra6m5.cpu\" -c \"target create ra6m5.cpu cortex_m -dap ra6m5.dap\" -c \"cortex_m reset_config sysresetreq\""}
},
"E6614C311B764A37": {
"name": "raspberry_pi_pico",
"flasher": {"name": "openocd", "uid": "E6614103E72C1D2F", "vid_pid": "0x2e8a 0x000c", "args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"", "verify": true}
},
"E6614864D35DAE36": {
"name": "raspberry_pi_pico_w",
"flasher": {"name": "openocd", "uid": "E6633861A3819D38", "vid_pid": "0x2e8a 0x000c", "args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"", "verify": true}
},
"560AE75E1C7152C9": {
"name": "raspberry_pi_pico2",
"flasher": {"name": "openocd", "uid": "E6633861A3978538", "vid_pid": "0x2e8a 0x000c", "args": "-f interface/cmsis-dap.cfg -f target/rp2350.cfg -c \"adapter speed 5000\"", "verify": true}
},
"2B0DC7A45781189E": {
"name": "adafruit_fruit_jam",
"flasher": {"name": "openocd", "uid": "E663AC91D3359B38", "vid_pid": "0x2e8a 0x000c", "args": "-f interface/cmsis-dap.cfg -f target/rp2350.cfg -c \"adapter speed 5000\"", "verify": true}
},
"3A001A001357364230353532": {
"name": "stm32f072disco",
"flasher": {"name": "jlink", "uid": "779541626", "args": "-device stm32f072rb"},
"flasher_recover": {"name": "openocd", "args": "-f interface/jlink.cfg -c \"transport select swd\" -f target/stm32f0x.cfg -c \"stm32f0x.cpu configure -event reset-init {}\""}
},
"30001A000647313332353735": {
"name": "stm32f407disco",
"flasher": {"name": "jlink", "uid": "000773661813", "args": "-device stm32f407vg"},
"flasher_recover": {"name": "openocd", "args": "-f interface/jlink.cfg -c \"transport select swd\" -f target/stm32f4x.cfg -c \"stm32f4x.cpu configure -event reset-init {}\""}
},
"460029001951373031313335": {
"name": "stm32f723disco",
"flasher": {"name": "jlink", "uid": "000776606156", "args": "-device stm32f723ie"},
"flasher_recover": {"name": "openocd", "args": "-f interface/jlink.cfg -c \"transport select swd\" -f target/stm32f7x.cfg -c \"stm32f7x.cpu configure -event reset-init {}\""}
},
"110018000951383432343236": {
"name": "stm32h743nucleo",
"flasher": {"name": "stlink", "uid": "004C00343137510F39383538", "verify": true},
"flasher_recover": {"name": "openocd", "args": "-f interface/stlink.cfg -f target/stm32h7x.cfg"}
},
"4D0038000450434E37343120": {
"name": "stm32g0b1nucleo",
"flasher": {"name": "stlink", "uid": "066FFF495087534867063844", "verify": true},
"flasher_recover": {"name": "openocd", "args": "-f interface/stlink.cfg -f target/stm32g0x.cfg"}
},
"3C0050001150334258343920": {
"name": "stm32l476disco",
"flasher": {"name": "jlink", "uid": "777632258", "args": "-device STM32L476VG"},
"flasher_recover": {"name": "openocd", "args": "-f interface/jlink.cfg -c \"transport select swd\" -f target/stm32l4x.cfg -c \"stm32l4x.cpu configure -event reset-init {}\""}
},
"300044000D5036394E373620": {
"name": "stm32u083nucleo",
"flasher": {"name": "stlink", "uid": "0668FF575457657187061314"},
"flasher_recover": {"name": "openocd", "args": "-f interface/stlink.cfg -f target/stm32u0x.cfg"}
},
"CDAB277B0FBC03E339E339E3": {
"name": "nanoch32v203",
"flasher": {"name": "openocd", "uid": "A76D8F062C2A", "vid_pid": "0x1a86 0x8010", "args": "-f target/wch-riscv.cfg"}
},
"CDAB3E8749BC54EF0F410025": {
"name": "ch32v103r_r1_1v0",
"flasher": {"name": "openocd", "uid": "BC4954081051", "vid_pid": "0x1a86 0x8010", "args": "-f target/wch-riscv.cfg", "verify": false}
},
"DE6B3E263B3857CAFFFFFFFF": {
"name": "ch32v307v_r1_1v0",
"flasher": {"name": "openocd", "uid": "BC5DA47360D0", "vid_pid": "0x1a86 0x8010", "args": "-f target/wch-riscv.cfg"}
},
"D443627B5450": {
"name": "ch582m_evt",
"flasher": {"name": "openocd", "uid": "57468F06DC03", "vid_pid": "0x1a86 0x8010", "args": "-f target/wch-riscv.cfg", "verify": false}
},
"BAE96FB95AFA6DBB8F00005002001200": {
"name": "mimxrt1064_evk",
"flasher": {"name": "jlink", "uid": "000725299165", "args": "-device MIMXRT1064xxx6A"},
"flasher_recover": {"name": "openocd", "args": "-f interface/jlink.cfg -c \"transport select swd\" -c \"adapter speed 1000\" -c \"swd newdap rt1064 cpu -expected-id 0\" -c \"dap create rt1064.dap -chain-position rt1064.cpu\" -c \"target create rt1064.cpu cortex_m -dap rt1064.dap\" -c \"cortex_m reset_config sysresetreq\""}
},
"899C3DE5B0F4D5CA": {
"name": "nrf54lm20dk",
"flasher": {"name": "jlink", "uid": "1051856258", "args": "-device NRF54LM20A_M33"},
"flasher_recover": {"name": "openocd", "args": "-f interface/jlink.cfg -c \"transport select swd\" -f target/nordic/nrf54l.cfg -c \"adapter speed 4000\""}
},
"78E60E166B5F88BE": {
"name": "nrf5340dk",
"flasher": {"name": "jlink", "uid": "1050076405", "args": "-device nrf5340_xxaa_app"},
"flasher_recover": {"name": "openocd", "args": "-f interface/jlink.cfg -c \"transport select swd\" -f target/nordic/nrf53.cfg -c \"adapter speed 4000\""}
},
"797D142D36345030364E1737922E4B4E": {
"name": "ra8m1_ek",
"flasher": {"name": "jlink", "uid": "001083115236", "args": "-device R7FA8M1AH"}
},
"21002F000F51363531383437": {
"name": "stm32f769disco",
"flasher": {"name": "jlink", "uid": "000778170924", "args": "-device stm32f769ni"}
},
"41003B000E504E5457323020": {
"name": "stm32l412nucleo",
"flasher": {"name": "stlink", "uid": "0673FF575051717867034946"}
},
"210041000C51343237303334": {
"name": "stm32f746disco",
"flasher": {"name": "stlink", "uid": "0670FF515448787067122222"}
},
"0C60020145401EAA0E4B6C64C40700F5": {
"name": "lpcxpresso43s67",
"flasher": {"name": "jlink", "uid": "728973776", "args": "-device LPC43S67_M4"},
"flasher_recover": {"name": "openocd", "args": "-f interface/jlink.cfg -c \"transport select swd\" -f target/lpc4357.cfg -c \"adapter speed 4000\"", "verify": false}
}
}
}
Loading