Skip to content

Commit e6a7698

Browse files
authored
Add GitHub Actions workflow for testing JLinkRemoteServer with STM32F… (#8)
Closed #5
1 parent e66d01b commit e6a7698

File tree

8 files changed

+15800
-29
lines changed

8 files changed

+15800
-29
lines changed

.github/workflows/fw.bin

242 KB
Binary file not shown.

.github/workflows/fw.hex

Lines changed: 15485 additions & 0 deletions
Large diffs are not rendered by default.

.github/workflows/test-flash.yml

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
name: Test Flash
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
workflow_dispatch:
8+
9+
env:
10+
VNET_BASE: 192.168.3
11+
VNET_MASK: 24
12+
13+
jobs:
14+
test-flash:
15+
runs-on: self-hosted
16+
17+
steps:
18+
- name: Cleanup before start
19+
if: always()
20+
run: |
21+
pkill -9 -f JLinkRemoteServer || true
22+
docker rm -f jlink100 jlink101 jlink102 2>/dev/null || true
23+
docker network rm jlink-net 2>/dev/null || true
24+
sleep 2
25+
26+
- uses: actions/checkout@v4
27+
28+
- name: Install package
29+
run: |
30+
python3 -m venv .venv
31+
. .venv/bin/activate
32+
pip install -e ".[dev]"
33+
34+
- name: Detect devices and save serials
35+
run: |
36+
. .venv/bin/activate
37+
bmlab-scan | tee scan.txt
38+
count=$(grep -c "Target: *STM32F103RE" scan.txt)
39+
awk '/JLink Programmer/ {serial=""} /Serial:/ {serial=$2} /Target: *STM32F103RE/ && serial {print serial}' scan.txt | sort | uniq > serials.txt
40+
41+
if [ "$count" -ne 3 ]; then
42+
echo "Test failed: expected 3 STM32F103RE, found $count"
43+
cat scan.txt
44+
exit 1
45+
fi
46+
47+
- name: Test 1 — Flash single device by serial
48+
run: |
49+
. .venv/bin/activate
50+
serial=$(sed -n '1p' serials.txt)
51+
bmlab-flash .github/workflows/fw.bin --serial $serial --mcu STM32F103RE | tee flash-serial1.txt
52+
53+
if ! grep -q "Success" flash-serial1.txt; then
54+
echo "Test 1 failed: flash not successful"
55+
cat flash-serial1.txt
56+
exit 1
57+
fi
58+
59+
- name: Test 2 — Flash without mcu (auto-detect target)
60+
run: |
61+
. .venv/bin/activate
62+
serial=$(sed -n '1p' serials.txt)
63+
bmlab-flash .github/workflows/fw.bin --serial $serial | tee flash-serial2.txt
64+
65+
if ! grep -q "Success" flash-serial2.txt; then
66+
echo "Test 2 failed: flash not successful"
67+
cat flash-serial2.txt
68+
exit 1
69+
fi
70+
71+
- name: Test 2.1 — Flash without mcu (auto-detect target)
72+
run: |
73+
. .venv/bin/activate
74+
serial=$(sed -n '1p' serials.txt)
75+
bmlab-flash .github/workflows/fw.hex --serial $serial | tee flash-serial2.txt
76+
77+
if ! grep -q "Success" flash-serial2.txt; then
78+
echo "Test 2.1 failed: flash not successful"
79+
cat flash-serial2.txt
80+
exit 1
81+
fi
82+
83+
- name: Test 3 — Flash multiple by serial
84+
run: |
85+
. .venv/bin/activate
86+
serial1=$(sed -n '1p' serials.txt)
87+
serial2=$(sed -n '2p' serials.txt)
88+
serial3=$(sed -n '3p' serials.txt)
89+
90+
bmlab-flash .github/workflows/fw.bin --serial $serial1 $serial2 $serial3 --mcu STM32F103RE | tee flash-serial3.txt
91+
92+
if ! grep -q "Success" flash-serial3.txt; then
93+
echo "Test 3 failed: flash not successful"
94+
cat flash-serial3.txt
95+
exit 1
96+
fi
97+
98+
- name: Build JLinkRemoteServer Docker image
99+
run: |
100+
docker build -t my-jlink-image -f .github/workflows/jlinkRemoteServerEmu.dockerfile .
101+
102+
- name: Setup JLinkRemoteServer Docker containers
103+
run: |
104+
docker network rm jlink-net 2>/dev/null || true
105+
docker network create --driver bridge --subnet=$VNET_BASE.0/$VNET_MASK --gateway=$VNET_BASE.1 jlink-net
106+
107+
serial1=$(sed -n '1p' serials.txt)
108+
serial2=$(sed -n '2p' serials.txt)
109+
serial3=$(sed -n '3p' serials.txt)
110+
111+
docker run -d --rm \
112+
--device=/dev/bus/usb:/dev/bus/usb \
113+
--name jlink100 \
114+
--network jlink-net \
115+
--ip $VNET_BASE.100 \
116+
my-jlink-image \
117+
-select usb=$serial1 -device STM32F103RE -endian little -speed 4000 -if swd
118+
sleep 3
119+
120+
docker run -d --rm \
121+
--device=/dev/bus/usb:/dev/bus/usb \
122+
--name jlink101 \
123+
--network jlink-net \
124+
--ip $VNET_BASE.101 \
125+
my-jlink-image \
126+
-select usb=$serial2 -device STM32F103RE -endian little -speed 4000 -if swd
127+
sleep 3
128+
129+
docker run -d --rm \
130+
--device=/dev/bus/usb:/dev/bus/usb \
131+
--name jlink102 \
132+
--network jlink-net \
133+
--ip $VNET_BASE.102 \
134+
my-jlink-image \
135+
-select usb=$serial3 -device STM32F103RE -endian little -speed 4000 -if swd
136+
sleep 3
137+
138+
- name: Test 4 — Flash three devices in parallel
139+
run: |
140+
. .venv/bin/activate
141+
bmlab-flash .github/workflows/fw.bin --ip $VNET_BASE.100 $VNET_BASE.101 $VNET_BASE.102 --mcu STM32F103RE | tee flash4.txt
142+
143+
success_count=$(grep -c "Success" flash4.txt || echo 0)
144+
145+
if [ "$success_count" -ne 3 ]; then
146+
echo "Test 4 failed: expected 3 successful flashes, found $success_count"
147+
cat flash4.txt
148+
exit 1
149+
fi
150+
151+
for ip in 100 101 102; do
152+
if ! grep -q "$VNET_BASE\.$ip" flash4.txt; then
153+
echo "Test 4 failed: no result for $VNET_BASE.$ip"
154+
cat flash4.txt
155+
exit 1
156+
fi
157+
done
158+
159+
- name: Cleanup after tests
160+
if: always()
161+
run: |
162+
docker rm -f jlink100 jlink101 jlink102 || true
163+
docker network rm jlink-net || true
164+
pkill -9 -f JLinkRemoteServer || true
165+
sleep 2
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Test Builds
1+
name: Test Scan
22

33
on:
44
push:
@@ -9,8 +9,9 @@ on:
99
env:
1010
VNET_BASE: 192.168.3
1111
VNET_MASK: 24
12+
1213
jobs:
13-
test-build:
14+
test-scan:
1415
runs-on: self-hosted
1516

1617
steps:

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,5 @@ Thumbs.db
4848
*.hex
4949
*.bin
5050
*.elf
51+
!fw.bin
52+
!fw.hex

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,33 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.1.8] - 2026-01-07
9+
10+
### Added
11+
- **Parallel device flashing** - Multiple devices can now be flashed simultaneously
12+
- `--ip` parameter now accepts multiple IP addresses for parallel network flashing
13+
- `--serial` parameter now accepts multiple serial numbers for sequential USB flashing
14+
- Uses `ProcessPoolExecutor` for true parallel execution (separate processes per device)
15+
- Each device gets isolated pylink state, preventing conflicts
16+
- Real-time progress reporting with ✓/✗ indicators per device
17+
- Summary report showing success/failure counts
18+
- Example: `bmlab-flash firmware.bin --ip 192.168.1.100 192.168.1.101 192.168.1.102`
19+
- Example: `bmlab-flash firmware.bin --serial 123456 789012 345678`
20+
21+
### Changed
22+
- **Smart execution strategy based on connection type**:
23+
- Network devices (--ip): Parallel flashing using ProcessPoolExecutor
24+
- USB devices (--serial): Sequential flashing to avoid USB driver conflicts
25+
- Auto-detection still works for single device scenarios
26+
- **Unified device output format** - Same format for single or multiple devices
27+
- Added 500ms delay after each flash operation for proper device release
28+
29+
### Added (Testing)
30+
- New CI workflow `test-flash.yml` for testing parallel flashing functionality
31+
- Tests for single device flashing (USB serial and network IP)
32+
- Tests for multiple device flashing (2 and 3 devices in parallel)
33+
- Tests for auto-detection and MCU parameter handling
34+
835
## [0.1.7] - 2026-01-06
936

1037
### Fixed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "bmlab-toolkit"
7-
version = "0.1.7"
7+
version = "0.1.8"
88
description = "CI/CD toolkit for flashing and testing embedded devices"
99
readme = "README.md"
1010
requires-python = ">=3.8"

0 commit comments

Comments
 (0)