tooling: Add make daplink-firmware and make daplink-deploy targets.#387
tooling: Add make daplink-firmware and make daplink-deploy targets.#387
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a DAPLink firmware build/flash workflow to the repo’s tooling so contributors can rebuild and deploy the STM32F103 “interface chip” firmware from source, similar to the existing MicroPython firmware targets.
Changes:
- Introduce
daplink-*Makefile targets to clone/build/update/deploy/clean DAPLink firmware artifacts. - Add DAPLink build configuration variables in
env.mk. - Update developer docs and devcontainer packages (
ccache,ninja-build) to support the DAPLink build toolchain.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| Makefile | Adds daplink-firmware, daplink-update, daplink-deploy*, daplink-clean targets and clone/build logic. |
| env.mk | Adds DAPLINK_* variables and moves BUILD_DIR earlier for shared use. |
| CONTRIBUTING.md | Documents new prerequisites and the new DAPLink firmware workflow/targets. |
| .devcontainer/Dockerfile | Installs ccache and ninja-build required for DAPLink progen builds. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| daplink-deploy: daplink-deploy-usb ## Flash DAPLink firmware (default: usb mass-storage) | ||
|
|
||
| .PHONY: daplink-deploy-usb | ||
| daplink-deploy-usb: ## Flash DAPLink firmware via DAPLink USB mass-storage (routine update) |
There was a problem hiding this comment.
daplink-deploy/daplink-deploy-usb have no prerequisites, so on a fresh checkout make daplink-deploy won’t even clone DAPLink (and will fail with a missing .bin path). For parity with micropython-deploy-usb (which depends on $(MPY_DIR)), consider making the deploy targets depend on $(DAPLINK_DIR) and/or the built artifact (e.g., daplink-firmware) so make daplink-deploy works end-to-end.
| daplink-deploy-usb: ## Flash DAPLink firmware via DAPLink USB mass-storage (routine update) | |
| daplink-deploy-usb: daplink-firmware ## Flash DAPLink firmware via DAPLink USB mass-storage (routine update) |
There was a problem hiding this comment.
Fixed: daplink-deploy-usb now depends on $(DAPLINK_DIR) (parity with micropython-deploy-usb which depends on $(MPY_DIR)). On a fresh checkout, make daplink-deploy will clone the DAPLink repo first. The script then handles the missing-firmware case with a clear error message pointing to make daplink-firmware.
| daplink-deploy-usb: ## Flash DAPLink firmware via DAPLink USB mass-storage (routine update) | ||
| @$(PYTHON) scripts/deploy_usb.py $(DAPLINK_BUILD_DIR)/$(DAPLINK_TARGET)_crc.bin |
There was a problem hiding this comment.
daplink-deploy-usb calls scripts/deploy_usb.py, which is written for MicroPython deploys (hardcoded volume label STeaMi, and on missing firmware it prints “Run 'make micropython-firmware' first.”). When used for DAPLink, failures will surface misleading instructions. Consider parameterizing the script (label + “run make … first” hint) or adding a DAPLink-specific USB deploy script.
There was a problem hiding this comment.
Fixed: scripts/deploy_usb.py is now generic. It accepts --label (default STeaMi, MAINTENANCE for daplink) and --build-target (default micropython-firmware, can be daplink-firmware for daplink) so the missing-firmware error message points to the right make target depending on the context.
dba854a to
35a319d
Compare
35a319d to
cddeceb
Compare
…build. The DAPLink build failed on systems without a `python` symlink (Debian/Ubuntu ship only `python3`) because the generated Makefile invokes `tools/pre_build_script.py` via its `#!/usr/bin/env python` shebang, which silently skips `version_git.h` generation. It also failed on modern toolchains (arm-none-eabi-gcc >= 11) because the firmware overflows the m_text region; DAPLink's docs pin gcc-arm-none-eabi to 10.3-2021.10. Prepend the DAPLink venv to PATH so `python` resolves, and download the pinned toolchain into .build/ on first build, using it only for daplink-firmware.
…ses. Mirror the existing micropython-firmware release job: build the DAPLink interface firmware after each semantic-release publish and upload the CRC-signed .bin / .hex (the artifacts users flash via MAINTENANCE mode).
…uilds. Caches the pinned gcc-arm-none-eabi 10.3-2021.10 toolchain (~150 MB) and the DAPLink Python virtualenv (~250 MB) between release runs. The toolchain key is fixed (the version is pinned), and the venv key is derived from requirements.txt so it invalidates when DAPLink upstream bumps a dependency.
Three issues raised on PR #387: 1. Toolchain download was hard-coded to x86_64-linux. Detect uname and pick the matching ARM-published archive (Linux x86_64, Linux aarch64, Intel macOS). Fail with a clear message — and a pointer to the dev container — on Apple Silicon and Windows, where 10.3-2021.10 is not published. 2. Deprecated `deploy-pyocd` / `deploy-openocd` advertised non-existent `daplink-deploy-pyocd` / `daplink-deploy-openocd` targets. Suggest only the `micropython-` variant until the SWD-based DAPLink targets land (tracked in #388). 3. The DAPLink venv was created once and never refreshed, so a `daplink-update` that bumped requirements.txt would silently reuse stale dependencies. Replace the manual check with a sentinel file that depends on requirements.txt, so pip install re-runs whenever upstream bumps a dep. Also document the platform constraint in CONTRIBUTING.md.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Sentinel: re-runs pip install whenever DAPLink's requirements.txt changes | ||
| # (e.g. after `make daplink-update`). | ||
| $(DAPLINK_DIR)/venv/.installed: $(DAPLINK_DIR)/requirements.txt | ||
| @echo "Setting up DAPLink Python virtualenv..." | ||
| @if [ ! -x "$(DAPLINK_DIR)/venv/bin/python" ]; then \ | ||
| $(PYTHON) -m venv $(DAPLINK_DIR)/venv; \ | ||
| fi | ||
| $(DAPLINK_DIR)/venv/bin/pip install -r $(DAPLINK_DIR)/requirements.txt | ||
| @touch $@ |
There was a problem hiding this comment.
$(DAPLINK_DIR)/venv/.installed depends on $(DAPLINK_DIR)/requirements.txt, but there’s no rule that produces requirements.txt and it won’t exist until after $(DAPLINK_DIR) is cloned. With parallel builds (make -j) or different prerequisite evaluation order on a fresh checkout, this can fail with “No rule to make target '.../requirements.txt'”. Add an explicit (preferably order-only) dependency on $(DAPLINK_DIR) for the .installed sentinel (and/or for $(DAPLINK_DIR)/requirements.txt) so the clone always happens before venv setup.
There was a problem hiding this comment.
Fixed in e8e001f: added an order-only prerequisite | $(DAPLINK_DIR) on the .installed sentinel so the clone runs before make checks requirements.txt, even on a fresh checkout or under make -j.
On a fresh checkout, $(DAPLINK_DIR)/venv/.installed depended on requirements.txt without any rule to produce it before the clone, so make would fail with "No rule to make target requirements.txt" (especially under parallel builds). Add an order-only prerequisite on $(DAPLINK_DIR) so the clone always runs first and the file exists when make resolves the sentinel.
|
🎉 This PR is included in version 0.16.7 🎉 The release is available on:
Your semantic-release bot 📦🚀 |
Rename the firmware job to micropython-firmware so it does not clash with the daplink-firmware job introduced in #387.
Rename the firmware job to micropython-firmware so it does not clash with the daplink-firmware job introduced in #387.
Closes #377
Summary
Add Makefile targets to build and flash the DAPLink interface firmware from source. The DAPLink firmware runs on the STM32F103 interface chip and provides the I2C bridge, mass-storage, and CMSIS-DAP debug interface.
DAPLink has two parts
0x08000000) — installed once at the factory, rarely updated. Provides the MAINTENANCE mode used to update the interface firmware. Updating the bootloader requires an external SWD probe and is not covered by these targets.0x08002000) — the routine update target. This is what these targets manage.A future
daplink-deploy-bootloadertarget could be added if needed, withpyocd/openocdflash via external probe.New targets
make daplink-firmwarestm32f103xb_steami32_ifmake daplink-updatemake daplink-deploymake daplink-deploy-usbmake daplink-cleanMaintenance mode
To flash the DAPLink interface firmware, the board must be in maintenance mode:
MAINTENANCEUSB volume appears (instead of the usualSTeaMivolume)make daplink-deploy-usbcopies the firmware to that volumeImplementation
Source repo
steamicc/DAPLink (branch
release_letssteam).Build
make daplink-firmwareclones the repo into.build/DAPLink/, creates a Python virtualenv inside it, installsrequirements.txt, then runs:The output
stm32f103xb_steami32_if_crc.binlands inprojectfiles/make_gcc_arm/stm32f103xb_steami32_if/build/.deploy_usb.py refactoring
scripts/deploy_usb.pyis now generic over volume label. It accepts--label(defaultSTeaMi) and provides a contextual error message when theMAINTENANCEvolume is not found, instructing the user to enter maintenance mode.Devcontainer
Added
ccacheandninja-buildto the Dockerfile (required by progen for the DAPLink build).Documentation
Test plan
make helpshows all 5 daplink-* targetsmake test— 349 mock tests passscripts/deploy_usb.py --label MAINTENANCEshows the maintenance mode error messagemake daplink-firmwarebuilds successfully (requires ccache/ninja-build)make daplink-deploy-usbflashes correctly on hardware in MAINTENANCE mode