Claude-skill-registry flash-firmware-dfu

Flash INAV firmware to flight controllers using DFU (Device Firmware Update)

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
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"
manifest: skills/data/flash-firmware-dfu/SKILL.md
source content

Flashing 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:

  1. Send
    ####\r\n
    to enter CLI mode
  2. Read from serial and wait for "CLI" string in response (timeout: 2 seconds)
  3. Only after receiving CLI prompt: send
    dfu\r\n
  4. 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
    dfu
    command is sent too early
  • 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:

  • b'\x00'
    or empty = normal reboot
  • b'\x01'
    = reboot to DFU mode

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:

  • -d 0483:df11
    - Target device ID (STM32 DFU)
  • --alt 0
    - Alternative setting (default flash memory)
  • -s 0x08000000
    - Start address (STM32 flash base)
  • :force
    - Force write even if non-blank
  • :leave
    - Exit DFU mode and run firmware after flashing
  • -D <file>
    - Binary file to flash

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

ProblemSolution
No DFU capable USB device found
Ensure board is in DFU mode, try different USB cable/port
Permission denied
Add udev rules or use
sudo
Cannot open DFU device
Check that no other program is accessing the device
Flash succeeds but board doesn't bootWrong 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)

  1. Open INAV Configurator
  2. Click "Firmware Flasher"
  3. Select "Load Firmware [Local]"
  4. Browse to your
    .hex
    file
  5. 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

See mwptools documentation

Safety Notes

  • ALWAYS verify you're flashing the correct target for your hardware
  • Backup your settings using CLI
    dump
    command before flashing
  • 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:

  • dfu
    - Reboot to DFU bootloader mode
  • tasks
    - Show task execution times
  • status
    - Show flight controller status
  • version
    - Show firmware version
  • Any other CLI command - just pass it as an argument

How it works:

  1. Opens serial connection to flight controller
  2. Enters CLI mode by sending
    ####\r\n
  3. Waits for "CLI" prompt (with timeout)
  4. Sends your command
  5. Reads and displays the response (except for
    dfu
    which disconnects)

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