Claude-skill-registry flash-firmware-dfu
Flash INAV firmware to flight controllers using DFU (Device Firmware Update)
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/flash-firmware-dfu" ~/.claude/skills/majiayu000-claude-skill-registry-flash-firmware-dfu && rm -rf "$T"
skills/data/flash-firmware-dfu/SKILL.mdFlashing INAV Firmware via DFU
IMPORTANT: Use the fc-flasher Agent
When this skill is invoked, you MUST immediately use the Task tool with
.subagent_type=fc-flasher
The
fc-flasher agent handles:
- Automatic settings backup and restore
- MSP reboot to DFU mode
- Hex to bin conversion
- DFU flashing
- Verification
Example:
User: "Flash inav_9.0.0_MATEKF405.hex" Assistant: [Immediately calls Task tool with subagent_type=fc-flasher and the hex file path]
Do NOT use manual DFU steps unless the fc-flasher agent fails or you're troubleshooting.
Manual DFU Flashing (Troubleshooting Only)
The information below is for troubleshooting when the automated agent doesn't work.
Prerequisites
Install dfu-util:
# Ubuntu/Debian sudo apt install dfu-util # Fedora sudo dnf install dfu-util # Arch sudo pacman -S dfu-util # Or download from source # http://sourceforge.net/p/dfu-util
You'll also need objcopy (part of binutils, usually pre-installed):
# If needed, install gcc-arm-none-eabi or binutils sudo apt install binutils-arm-none-eabi # Ubuntu/Debian
Step 1: Put Flight Controller into DFU Mode
Choose ONE of the following methods:
Method A: Hardware Button
Press and hold the DFU/BOOT button on the board while plugging in USB.
Method B: Serial Command (Recommended: Use Helper Script)
Using the helper script (RECOMMENDED):
# Python version (requires pyserial) .claude/skills/flash-firmware-dfu/reboot-to-dfu.py /dev/ttyACM0 # Install pyserial if needed: pip3 install pyserial
Manual method (not recommended - race condition):
The correct sequence requires waiting for the actual CLI prompt, not just a fixed delay:
- Send
to enter CLI mode####\r\n - Read from serial and wait for "CLI" string in response (timeout: 2 seconds)
- Only after receiving CLI prompt: send
dfu\r\n - Disconnect
Why simple echo + sleep doesn't work:
# DON'T DO THIS - race condition! echo -ne '####\r\n' > /dev/ttyACM0 sleep 0.25 # Wrong! Doesn't wait for actual CLI prompt echo -ne 'dfu\r\n' > /dev/ttyACM0
This fails because:
- It blindly sleeps without checking if CLI is ready
- If the FC takes >250ms to respond, the
command is sent too earlydfu - The helper scripts properly wait for the "CLI" prompt before sending
dfu
Method C: CLI Command
Connect with INAV Configurator or serial terminal and type:
dfu
Method D: MSP Reboot Command (INAV 9.x+)
Using MSP to reboot to DFU (most reliable programmatic method):
# Using mspapi2 from mspapi2 import MSPSerial serial = MSPSerial("/dev/ttyACM0", 115200) serial.open() # Send MSP_REBOOT (68) with DFU parameter (1) code, payload = serial.request(68, b'\x01') serial.close() # Wait for reboot import time time.sleep(2)
This is the most reliable programmatic method because it:
- Doesn't require CLI prompt timing
- Works through the MSP protocol
- Is supported by configurator and tools
- Provides proper backwards compatibility
Parameter values:
or empty = normal rebootb'\x00'
= reboot to DFU modeb'\x01'
Step 2: Verify DFU Mode
Check that the device is in DFU mode:
dfu-util -l
You should see a device with ID
0483:df11.
Step 3: Convert HEX to BIN
DFU requires binary format, so convert the
.hex file:
cd inav/build objcopy -I ihex inav_x.y.z_TARGETNAME.hex -O binary inav_x.y.z_TARGETNAME.bin
Example:
objcopy -I ihex inav_8.0.0_MATEKF405.hex -O binary inav_8.0.0_MATEKF405.bin
Step 4: Flash the Firmware
dfu-util -d 0483:df11 --alt 0 -s 0x08000000:force:leave -D inav_x.y.z_TARGETNAME.bin
Example:
dfu-util -d 0483:df11 --alt 0 -s 0x08000000:force:leave -D inav_8.0.0_MATEKF405.bin
Command Breakdown:
- Target device ID (STM32 DFU)-d 0483:df11
- Alternative setting (default flash memory)--alt 0
- Start address (STM32 flash base)-s 0x08000000
- Force write even if non-blank:force
- Exit DFU mode and run firmware after flashing:leave
- Binary file to flash-D <file>
Step 5: Verify
After flashing completes, the flight controller should automatically reboot and run the new firmware.
Connect with INAV Configurator to verify the version.
Complete Example Workflow
# 1. Build the firmware cd inav/build make MATEKF405 # 2. Put flight controller in DFU mode # Option A: Hardware button (press BOOT button while plugging USB) # Option B: Serial command (use helper script) ../.claude/skills/flash-firmware-dfu/reboot-to-dfu.py /dev/ttyACM0 # 3. Verify DFU mode dfu-util -l # 4. Convert hex to bin objcopy -I ihex inav_8.0.0_MATEKF405.hex -O binary inav_8.0.0_MATEKF405.bin # 5. Flash dfu-util -d 0483:df11 --alt 0 -s 0x08000000:force:leave -D inav_8.0.0_MATEKF405.bin
Automated Script
For repeated flashing during development:
#!/bin/bash # flash-firmware.sh TARGET="MATEKF405" SERIAL_PORT="/dev/ttyACM0" HEX_FILE="inav_*.${TARGET}.hex" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # Put FC into DFU mode using helper script echo "Entering DFU mode..." if ! $SCRIPT_DIR/.claude/skills/flash-firmware-dfu/reboot-to-dfu.py $SERIAL_PORT; then echo "ERROR: Failed to enter DFU mode!" exit 1 fi # Note: Helper script already waits and verifies DFU mode # Convert to bin echo "Converting hex to bin..." objcopy -I ihex $HEX_FILE -O binary ${HEX_FILE%.hex}.bin # Flash echo "Flashing firmware..." dfu-util -d 0483:df11 --alt 0 -s 0x08000000:force:leave -D ${HEX_FILE%.hex}.bin echo "Flash complete!"
Usage:
chmod +x flash-firmware.sh ./flash-firmware.sh
Troubleshooting
| Problem | Solution |
|---|---|
| Ensure board is in DFU mode, try different USB cable/port |
| Add udev rules or use |
| Check that no other program is accessing the device |
| Flash succeeds but board doesn't boot | Wrong target or corrupted file - reflash |
| Hardware doesn't work after flashing (gyro not detected, etc.) | May be target configuration issue - use target-developer agent |
udev Rules (Avoid sudo)
Create
/etc/udev/rules.d/45-stm32dfu.rules:
# STM32 DFU Bootloader SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", MODE="0664", GROUP="plugdev"
Then reload:
sudo udevadm control --reload-rules sudo udevadm trigger
Add your user to the plugdev group:
sudo usermod -a -G plugdev $USER
Log out and back in for group changes to take effect.
Alternative Methods
INAV Configurator (GUI)
- Open INAV Configurator
- Click "Firmware Flasher"
- Select "Load Firmware [Local]"
- Browse to your
file.hex - Click "Flash Firmware"
msp-tool (Command Line)
# Install msp-tool go install github.com/fiam/msp-tool@latest # Flash msp-tool flash --port /dev/ttyACM0 inav_x.y.z_TARGETNAME.hex
flash.sh
Safety Notes
- ALWAYS verify you're flashing the correct target for your hardware
- Backup your settings using CLI
command before flashingdump - Double-check file paths and target names
- Keep a known-good firmware hex file as backup
CLI Command Tools
This skill includes Python scripts for sending commands to the flight controller via CLI:
fc-cli.py - Modular CLI Command Tool
Send any CLI command to the flight controller:
# Show task execution times (useful for performance analysis) .claude/skills/flash-firmware-dfu/fc-cli.py tasks # Show firmware version .claude/skills/flash-firmware-dfu/fc-cli.py version # Show flight controller status .claude/skills/flash-firmware-dfu/fc-cli.py status # Reboot to DFU mode .claude/skills/flash-firmware-dfu/fc-cli.py dfu # Send any custom CLI command .claude/skills/flash-firmware-dfu/fc-cli.py "get gyro_lpf1_static_hz" # Specify custom serial port .claude/skills/flash-firmware-dfu/fc-cli.py tasks /dev/ttyUSB0
Available built-in commands:
- Reboot to DFU bootloader modedfu
- Show task execution timestasks
- Show flight controller statusstatus
- Show firmware versionversion- Any other CLI command - just pass it as an argument
How it works:
- Opens serial connection to flight controller
- Enters CLI mode by sending
####\r\n - Waits for "CLI" prompt (with timeout)
- Sends your command
- Reads and displays the response (except for
which disconnects)dfu
Adding new commands: Edit
fc-cli.py and add to the COMMANDS dictionary:
COMMANDS = { 'mycommand': { 'handler': lambda cli: cmd_generic(cli, 'mycommand'), 'description': 'Description of my command', 'read_response': True, }, }
reboot-to-dfu.py - Simple DFU Reboot
Simple standalone script that only reboots to DFU mode (equivalent to
fc-cli.py dfu):
.claude/skills/flash-firmware-dfu/reboot-to-dfu.py [port]
Use
fc-cli.py for new work - it's more flexible.
USB Debugging
When USB MSC (mass storage) or CDC (serial) modes have issues, see:
claude/developer/docs/debugging/usb-msc-debugging.md
Quick commands:
lsusb -v | grep -A20 "STM" dmesg | tail -50 cat /sys/bus/usb/devices/*/product
Related Skills and Agents
Skills:
- build-inav-target - Build firmware before flashing
- build-sitl - Test changes in SITL before flashing hardware
- msp-protocol - MSP protocol reference
Agents:
- fc-flasher - Automated flashing with settings preservation (RECOMMENDED)
- inav-builder - Build firmware for targets
- target-developer - Fix target configuration issues if hardware doesn't work after flashing
References
- Full documentation:
inav/docs/development/Building in Linux.md - USB debugging:
claude/developer/docs/debugging/usb-msc-debugging.md