Feature Request
Is your feature request related to a problem? Please describe
ArduPilot does not serve DroneCAN firmware from the flight-controller SD card. Nodes can pull an image only if some other node on the bus is the file server.
Putting that server on the flight controller enables three things:
- Fleet provisioning. Node images are written to the SD card in the same process that programs the flight-controller MCU. Vehicles leave the line with node firmware matched to flight-controller firmware, so DroneCAN message interfaces stay compatible. No CAN adapter at the vehicle.
- One GCS workflow on both stacks. QGroundControl is MAVLink-native. MAVFTP already writes files to the SD card; if the flight controller then serves those files over CAN, the same GCS path updates nodes on ArduPilot and on PX4. See qgroundcontrol#14987 for the GCS-side design.
- Cross-stack compatibility. PX4 already implements this server. The APDescriptor / board ID / image CRC matching is shared, so the same images and SD layout work on both autopilots.
MAVFTP to the SD card already works (GCS_FTP). Dropping a .bin there does nothing for nodes, because AP_DroneCAN never answers uavcan.protocol.file.Read / GetInfo and never sends BeginFirmwareUpdate.
AP_Periph is already the updatee. The app handles BeginFirmwareUpdate and reboots; the bootloader pulls the image with pipelined file.Read, checks board ID and CRC (AP_CheckFirmware), and reports progress on NodeStatus (MODE_SOFTWARE_UPDATE, vendor_specific_status_code = kilobytes written). That side does not need work.
ArduPilot already forwards raw CAN for Mission Planner (CAN_FRAME / CAN_FILTER_MODIFY). That path stays. This issue is the shared, MAVLink-native path.
Describe the solution you'd like
Implement the DroneCAN firmware-update server on the flight controller, the same role PX4 already fills:
- Serve
uavcan.protocol.file.Read and uavcan.protocol.file.GetInfo from a dedicated directory on the SD card. Root the server at that directory; do not expose the rest of the filesystem. GetInfo is required for PX4 canbootloader clients. AP_Periph bootloader only calls Read.
- Send
uavcan.protocol.file.BeginFirmwareUpdate when a node's GetNodeInfo does not match a stored image. AP_Periph already reports APJ_BOARD_ID as hardware major/minor and the 64-bit image CRC. The unsigned APDescriptor signature (0x40a2e4f1…) is shared with PX4, so the same .bin / .uavcan.bin files work on both stacks.
- Use a staging directory plus a live directory (PX4:
ufw_staging/ → ufw/<board_id>.bin) so MAVFTP can finish writing before anything is served or flashed.
Do not start an update while armed.
Trigger policy is an open question. Automatic-on-CRC-mismatch (PX4; typically at boot) is what fleet provisioning needs. An explicit MAVLink command is what a GCS "update this node" button needs. Both can exist.
Progress display in a GCS uses UAVCAN_NODE_STATUS (SOFTWARE_UPDATE + vendor_specific_status_code). That MAVLink bridge is qgroundcontrol#14987, not this issue.
Describe alternatives you've considered
- Mission Planner / DroneCAN GUI Tool over
CAN_FRAME. The existing ArduPilot path for a DroneCAN-native GCS. PX4 cannot adopt it without a large driver change, and it requires a DroneCAN stack in the GCS.
- USB / SLCAN / SWD to the node. Requires physical access.
Platform
Additional context
PX4 implementation: src/drivers/uavcan/uavcan_servers.cpp. Docs: DroneCAN firmware update.
ArduPilot already has DNA (AP_DroneCAN_DNA_Server) and MAVFTP. Missing: file server and trigger.
Boards without an SD card cannot host images; gate the feature off there.
Flash and RAM cost is non-trivial. Keep it compile-time optional.
Related GCS work (node list, health, parameters; firmware upload called out as a follow-on): qgroundcontrol#14987. Design note: DroneCAN node management over MAVLink.
Feature Request
Is your feature request related to a problem? Please describe
ArduPilot does not serve DroneCAN firmware from the flight-controller SD card. Nodes can pull an image only if some other node on the bus is the file server.
Putting that server on the flight controller enables three things:
MAVFTP to the SD card already works (
GCS_FTP). Dropping a.binthere does nothing for nodes, becauseAP_DroneCANnever answersuavcan.protocol.file.Read/GetInfoand never sendsBeginFirmwareUpdate.AP_Periph is already the updatee. The app handles
BeginFirmwareUpdateand reboots; the bootloader pulls the image with pipelinedfile.Read, checks board ID and CRC (AP_CheckFirmware), and reports progress onNodeStatus(MODE_SOFTWARE_UPDATE,vendor_specific_status_code= kilobytes written). That side does not need work.ArduPilot already forwards raw CAN for Mission Planner (
CAN_FRAME/CAN_FILTER_MODIFY). That path stays. This issue is the shared, MAVLink-native path.Describe the solution you'd like
Implement the DroneCAN firmware-update server on the flight controller, the same role PX4 already fills:
uavcan.protocol.file.Readanduavcan.protocol.file.GetInfofrom a dedicated directory on the SD card. Root the server at that directory; do not expose the rest of the filesystem.GetInfois required for PX4 canbootloader clients. AP_Periph bootloader only callsRead.uavcan.protocol.file.BeginFirmwareUpdatewhen a node'sGetNodeInfodoes not match a stored image. AP_Periph already reportsAPJ_BOARD_IDas hardware major/minor and the 64-bit image CRC. The unsigned APDescriptor signature (0x40a2e4f1…) is shared with PX4, so the same.bin/.uavcan.binfiles work on both stacks.ufw_staging/→ufw/<board_id>.bin) so MAVFTP can finish writing before anything is served or flashed.Do not start an update while armed.
Trigger policy is an open question. Automatic-on-CRC-mismatch (PX4; typically at boot) is what fleet provisioning needs. An explicit MAVLink command is what a GCS "update this node" button needs. Both can exist.
Progress display in a GCS uses
UAVCAN_NODE_STATUS(SOFTWARE_UPDATE+vendor_specific_status_code). That MAVLink bridge is qgroundcontrol#14987, not this issue.Describe alternatives you've considered
CAN_FRAME. The existing ArduPilot path for a DroneCAN-native GCS. PX4 cannot adopt it without a large driver change, and it requires a DroneCAN stack in the GCS.Platform
Additional context
PX4 implementation:
src/drivers/uavcan/uavcan_servers.cpp. Docs: DroneCAN firmware update.ArduPilot already has DNA (
AP_DroneCAN_DNA_Server) and MAVFTP. Missing: file server and trigger.Boards without an SD card cannot host images; gate the feature off there.
Flash and RAM cost is non-trivial. Keep it compile-time optional.
Related GCS work (node list, health, parameters; firmware upload called out as a follow-on): qgroundcontrol#14987. Design note: DroneCAN node management over MAVLink.