Skip to content

Commit 3489012

Browse files
committed
Merge remote-tracking branch 'origin/master' into tfcollins/lint
2 parents f3d734c + 852f5cd commit 3489012

4 files changed

Lines changed: 235 additions & 2 deletions

File tree

.github/workflows/depends.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ jobs:
4040

4141
build_windows:
4242
name: Build libad9361-iio for Windows
43-
runs-on: windows-2019
43+
runs-on: windows-2022
4444

4545
steps:
4646
- name: Setup MSBuild
4747
uses: microsoft/setup-msbuild@v2
4848
with:
49-
vs-version: '[16.0,17.0)' # VS 2019
49+
vs-version: '[17.0,18.0)' # VS 2022 (windows-2019 image was retired)
5050

5151
- name: Install dependencies
5252
run: |

.github/workflows/hw-matlab.yml

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
name: Hardware Tests (labgrid)
2+
3+
# Bespoke MATLAB hardware-CI workflow. labgrid (adi-labgrid-plugins) boots
4+
# the board for a coordinator place, hands MATLAB the booted board's libIIO
5+
# URI via the IIO_URI env var, and runs runHWTests against it.
6+
#
7+
# Two job stages:
8+
# discover — on a coordinator-adjacent runner, intersect live coordinator
9+
# places with test/hw_ci/board_map.yaml -> matrix of places.
10+
# hw — one shard per place, pinned to its hw-<place> self-hosted
11+
# runner (which must have MATLAB + libiio installed), boots the
12+
# board and runs MATLAB.
13+
#
14+
# Requires a coordinator reachable at vars.ADI_LG_COORDINATOR and self-hosted
15+
# runners labeled [self-hosted, hw-coordinator] and [self-hosted, hw-<place>]
16+
# per the adi-labgrid-plugins HW-CI runner contract.
17+
18+
on:
19+
workflow_dispatch:
20+
schedule:
21+
- cron: "0 8 * * *"
22+
pull_request:
23+
types: [labeled, opened, synchronize, reopened]
24+
25+
# A pinned reference to adi-labgrid-plugins. Bump alongside the coordinator.
26+
env:
27+
ADI_LG_PLUGINS_REF: "v2"
28+
VENV_DIR: "${{ github.workspace }}/.hw-ci-venv"
29+
MATLAB_BIN: "/opt/MATLAB/R2025b/bin/matlab"
30+
31+
# Minimal default token permissions; the publish job widens its own below.
32+
permissions:
33+
contents: read
34+
35+
jobs:
36+
discover:
37+
# Only on PRs that opt in with the `hw-test` label; always on dispatch/cron.
38+
if: >-
39+
github.event_name != 'pull_request' ||
40+
contains(github.event.pull_request.labels.*.name, 'hw-test')
41+
runs-on: [self-hosted, hw-coordinator]
42+
outputs:
43+
matrix: ${{ steps.discover.outputs.matrix }}
44+
count: ${{ steps.discover.outputs.count }}
45+
steps:
46+
- uses: actions/checkout@v4
47+
48+
- name: Setup venv (adi-labgrid-plugins)
49+
uses: tfcollins/labgrid-plugins/.github/actions/setup-uv-venv@v2
50+
with:
51+
venv_dir: ${{ env.VENV_DIR }}
52+
install_cmd: >-
53+
uv pip install --python "$VENV_DIR/bin/python"
54+
"adi-labgrid-plugins @ git+https://github.com/tfcollins/labgrid-plugins.git@${{ env.ADI_LG_PLUGINS_REF }}"
55+
56+
- name: Discover places
57+
id: discover
58+
env:
59+
LG_COORDINATOR: ${{ vars.ADI_LG_COORDINATOR }}
60+
run: |
61+
"$VENV_DIR/bin/adi-lg-matlab" discover \
62+
--coord "$LG_COORDINATOR" \
63+
--board-map test/hw_ci/board_map.yaml \
64+
--github-output
65+
66+
hw:
67+
needs: discover
68+
if: ${{ needs.discover.outputs.count != '0' }}
69+
strategy:
70+
fail-fast: false
71+
matrix:
72+
include: ${{ fromJSON(needs.discover.outputs.matrix).include }}
73+
runs-on: [self-hosted, "hw-${{ matrix.place }}"]
74+
timeout-minutes: 60
75+
steps:
76+
- uses: actions/checkout@v4
77+
78+
- name: Setup venv (adi-labgrid-plugins)
79+
uses: tfcollins/labgrid-plugins/.github/actions/setup-uv-venv@v2
80+
with:
81+
venv_dir: ${{ env.VENV_DIR }}
82+
install_cmd: >-
83+
uv pip install --python "$VENV_DIR/bin/python"
84+
"adi-labgrid-plugins @ git+https://github.com/tfcollins/labgrid-plugins.git@${{ env.ADI_LG_PLUGINS_REF }}"
85+
86+
- name: Acquire place
87+
uses: tfcollins/labgrid-plugins/.github/actions/acquire-place@v2
88+
with:
89+
coordinator: ${{ vars.ADI_LG_COORDINATOR }}
90+
place: ${{ matrix.place }}
91+
labgrid_client: ${{ env.VENV_DIR }}/bin/labgrid-client
92+
93+
- name: Boot board + run MATLAB HW tests
94+
env:
95+
LG_COORDINATOR: ${{ vars.ADI_LG_COORDINATOR }}
96+
run: |
97+
# Place is already acquired by the composite action above, so do
98+
# NOT pass --acquire here (avoids double-acquire).
99+
"$VENV_DIR/bin/adi-lg-matlab" run \
100+
--coord "$LG_COORDINATOR" \
101+
--place "${{ matrix.place }}" \
102+
--board-map test/hw_ci/board_map.yaml \
103+
--repo-dir "$GITHUB_WORKSPACE" \
104+
--matlab "$MATLAB_BIN" \
105+
--junit "junit-${{ matrix.place }}.xml"
106+
107+
- name: Release place
108+
if: always()
109+
run: |
110+
"$VENV_DIR/bin/labgrid-client" -x "${{ vars.ADI_LG_COORDINATOR }}" \
111+
-p "${{ matrix.place }}" release || true
112+
113+
- name: Upload JUnit + MATLAB logs
114+
if: always()
115+
uses: actions/upload-artifact@v4
116+
with:
117+
name: hw-results-${{ matrix.place }}
118+
path: |
119+
junit-${{ matrix.place }}.xml
120+
${{ matrix.matlab_board }}_HWTestResults.xml
121+
failures.txt
122+
if-no-files-found: ignore
123+
124+
publish:
125+
needs: hw
126+
# Run only when the hw matrix actually ran (i.e. the hw-test path was
127+
# taken). When hw is skipped, there is nothing to publish — skip too,
128+
# so this job never sits pending on a PR that has no HW runner.
129+
if: ${{ always() && needs.hw.result != 'skipped' }}
130+
runs-on: [self-hosted, hw-coordinator]
131+
# The test-result action posts a check run and a PR comment.
132+
permissions:
133+
contents: read
134+
checks: write
135+
pull-requests: write
136+
steps:
137+
- uses: actions/download-artifact@v4
138+
with:
139+
path: hw-results
140+
- name: Publish test summary
141+
uses: EnricoMi/publish-unit-test-result-action@v2
142+
with:
143+
junit_files: "hw-results/**/junit-*.xml"

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,36 @@ rgetz@pinky:~/TransceiverToolbox$ make -C CI/scripts/ build
3636

3737
Then simply add the `hdl` folder to your MATLAB path `addpath(genpath('hdl'))`
3838

39+
## Hardware Testing with labgrid
40+
41+
The MATLAB hardware tests (`runHWTests`) connect to a board over a libIIO URI
42+
and honor the `IIO_URI` environment variable. They assume the board is already
43+
powered, booted, and reachable.
44+
45+
[adi-labgrid-plugins](https://github.com/analogdevicesinc/adi-labgrid-plugins)
46+
can provision that board automatically — power it, boot the FPGA/SoC, and hand
47+
MATLAB the booted board's URI — both locally and in GitHub Actions, via the
48+
`adi-lg-matlab` launcher.
49+
50+
The mapping from a labgrid place (tagged with `carrier` / `daughter-board`) to
51+
the MATLAB board reference name that `runHWTests` expects lives in
52+
[`test/hw_ci/board_map.yaml`](test/hw_ci/board_map.yaml).
53+
54+
Run locally against a coordinator place:
55+
56+
```bash
57+
pip install "adi-labgrid-plugins @ git+https://github.com/tfcollins/labgrid-plugins.git@v2"
58+
59+
adi-lg-matlab run \
60+
--coord $LG_COORDINATOR --place mini2 \
61+
--board-map test/hw_ci/board_map.yaml \
62+
--repo-dir . --matlab /opt/MATLAB/R2025b/bin/matlab \
63+
--junit junit-mini2.xml --acquire
64+
```
65+
66+
This boots the board, sets `IIO_URI`, runs `runHWTests`, copies the JUnit
67+
results, and releases the place. The GitHub Actions equivalent is
68+
[`.github/workflows/hw-matlab.yml`](.github/workflows/hw-matlab.yml). See the
69+
[MATLAB Hardware CI guide](https://adi-labgrid-plugins.readthedocs.io/en/latest/user-guide/matlab-hw-ci.html)
70+
for details.
71+

test/hw_ci/board_map.yaml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# TransceiverToolbox board map for labgrid HW-CI (adi-lg-matlab).
2+
#
3+
# Maps a labgrid coordinator place's tags -> the MATLAB board reference
4+
# name that `runHWTests(board)` understands (the values in the `switch`
5+
# in test/runHWTests.m). adi-lg-matlab uses this to translate a booted
6+
# place into the right `board` argument.
7+
#
8+
# Matching rules (see adi_lg_plugins.matlab_ci.board_map):
9+
# * `daughter-board` is required and matched against the place's
10+
# `daughter-board` tag.
11+
# * `carrier` / `hdl-config`, when present, must also match the place's
12+
# tags; the MOST specific matching row wins. A row without `carrier`
13+
# is a carrier-agnostic fallback.
14+
#
15+
# The `daughter-board` / `carrier` values below must match the tags the
16+
# lab admin set on each place, e.g.:
17+
# labgrid-client -p mini2 set-tags carrier=zcu102 daughter-board=adrv9002 \
18+
# boot-strategy=BootFPGASoC
19+
#
20+
# NOTE: this duplicates knowledge in test/runHWTests.m's switch — keep the
21+
# two in sync when adding boards.
22+
23+
boards:
24+
# --- AD9361 (FMComms2/3) ---
25+
- {carrier: zcu102, daughter-board: ad9361, matlab_board: zynqmp-zcu102-rev10-ad9361-fmcomms2-3}
26+
- {carrier: zc706, daughter-board: ad9361, matlab_board: zynq-zc706-adv7511-ad9361-fmcomms2-3}
27+
- {carrier: zc702, daughter-board: ad9361, matlab_board: zynq-zc702-adv7511-ad9361-fmcomms2-3}
28+
- {carrier: zed, daughter-board: ad9361, matlab_board: zynq-zed-adv7511-ad9361-fmcomms2-3}
29+
30+
# --- AD9364 (FMComms4) ---
31+
- {carrier: zcu102, daughter-board: ad9364, matlab_board: zynqmp-zcu102-rev10-ad9364-fmcomms4}
32+
- {carrier: zc706, daughter-board: ad9364, matlab_board: zynq-zc706-adv7511-ad9364-fmcomms4}
33+
- {carrier: zed, daughter-board: ad9364, matlab_board: zynq-zed-adv7511-ad9364-fmcomms4}
34+
35+
# --- FMComms5 (dual AD9361) ---
36+
- {carrier: zcu102, daughter-board: fmcomms5, matlab_board: zynqmp-zcu102-rev10-ad9361-fmcomms5}
37+
- {carrier: zc706, daughter-board: fmcomms5, matlab_board: zynq-zc706-adv7511-ad9361-fmcomms5}
38+
39+
# --- AD9371 / ADRV9371 ---
40+
- {carrier: zcu102, daughter-board: adrv9371, matlab_board: zynqmp-zcu102-rev10-adrv9371}
41+
- {carrier: zc706, daughter-board: adrv9371, matlab_board: zynq-zc706-adv7511-adrv9371}
42+
43+
# --- ADRV9002 (CMOS default; hdl-config selects LVDS vs CMOS) ---
44+
- {carrier: zcu102, daughter-board: adrv9002, matlab_board: zynqmp-zcu102-rev10-adrv9002-vcmos}
45+
- {carrier: zcu102, daughter-board: adrv9002, hdl-config: lvds, matlab_board: zynqmp-zcu102-rev10-adrv9002-vlvds}
46+
- {carrier: zcu102, daughter-board: adrv9002, hdl-config: cmos, matlab_board: zynqmp-zcu102-rev10-adrv9002-vcmos}
47+
- {carrier: zed, daughter-board: adrv9002, matlab_board: zynq-zed-adv7511-adrv9002-vcmos}
48+
49+
# --- ADRV9009 ---
50+
- {carrier: zcu102, daughter-board: adrv9009, matlab_board: zynqmp-zcu102-rev10-adrv9009}
51+
- {carrier: zc706, daughter-board: adrv9009, matlab_board: zynq-zc706-adv7511-adrv9009}
52+
53+
# --- FMComms8 (dual ADRV9009) ---
54+
- {carrier: zcu102, daughter-board: fmcomms8, matlab_board: zynqmp-zcu102-rev10-adrv9009-fmcomms8}
55+
56+
# --- Pluto (self-contained) ---
57+
- {daughter-board: pluto, matlab_board: pluto}

0 commit comments

Comments
 (0)