AP_HAL_ChibiOS: add reboot to USB mass storage mode - #34087
Conversation
|
Does this have any effect on our secure-bootloader feature? I wonder if we need to add anything to our security page, perhaps a note on how to disable this. |
I don't think it impacts that, it only gives access to the microSD, and only over USB, so you need physical access and this doesn't give you a way to change the firmware |
how much faster? |
it depends how fast you're getting now. This method should give around 800kbyte/s read, and often mavlink log download is significantly slower than that. |
5ccce79 to
749e357
Compare
|
Should this be accepted over all MAVLink links? Maybe it should only be accepted from a USB endpoint. It would be nice if ejecting the mass storage could be made to reboot back to "normal" mode. |
I did consider that, but one of the uses of the mass storage support is doing things like a filesystem check, format, partition etc of the microsd. To do those things you need to unmount the drive. For users that have aircraft where the microsd is extremely difficult to remove (I have some aircraft like that) this will be a big help if the microsd becomes corrupted. I know we can format the microsd, but it is nice to be able to do a chkdisk or re-format as exfat for example. |
we could, but it would limit some use cases, for example you may want to do this when its plugged into a companion computer on the aircraft, and the command could be coming in over a different link. I know you could arrange for the command to come via the companion computer, but it seems like a needless complication for the user. |
Previous review (2026-08-17)Automated review note - AI-generated (Claude), independently cross-checked by a second model and re-verified against the diff. Please sanity-check before acting. Reviewed at head Verdict: REQUEST CHANGES
Full report, including what was checked and found clean: https://uav.tridgell.net/DevCallReviews/DevCallTopic/devcall_pr_reviews.html |
749e357 to
756d1cb
Compare
The bootloader maybe accessible over more than just USB, the main flight code has no way of knowing which ports could be used for flashing. But in this case it can be 100% sure only the USB port can be used for USB mass storage. As you say maybe there is no benefit to adding the protection, the worst I can think is that you have to power cycle to get back to "normal" mode if your entered mass storage by mistake. I guess we might be able to think of some complicated security bypass, but it would only be on USB. |
Previous review (2026-08-17)Automated review note - AI-generated (Claude), independently cross-checked by a second model and re-verified against the diff. Please sanity-check before acting. Reviewed at head Verdict: COMMENT
Full report, including what was checked and found clean: https://uav.tridgell.net/DevCallReviews/DevCallTopic/devcall_pr_reviews.html |
756d1cb to
e64b232
Compare
I really think it is unnecessary, and I think it would need a new HAL virtual on the UART driver which will cost us flash for something that is a non-issue. |
Previous review (2026-08-22)Automated review note — AI-generated (Claude), validated against the live diff. Please sanity-check before acting. Full report: https://uav.tridgell.net/DevCallReviews/followups/2026_08_22_1100/devcall_pr_reviews.html Re-reviewed at head There is zero ArduPilot source change in this delta. The only patch-text difference is one NewThe same treatment is still owed to The MSD worker stack is now fully consumed by the measured read path. Minor, performance only: ResolvedThe SD retry count (3→9 via Still open
Checked and cleanBuffer sizing is right — |
d18209b to
4add2a2
Compare
Previous review (2026-08-23)Automated review note — AI-generated (Claude), validated against the live diff. Please sanity-check before acting. Full report: https://uav.tridgell.net/DevCallReviews/followups/2026_08_24_0643/devcall_pr_reviews.html Re-reviewed at head CI is red, and one of the two failures is exactly the item I raised in the last two rounds — it is now a hard gate rather than advice. Verdict: REQUEST CHANGES, on two counts, both cheap. The PR's own delta since Blocking 1 —
|
4add2a2 to
36c7ec0
Compare
Previous review (2026-08-24)Automated review note — AI-generated (Claude), validated against the live diff. Please sanity-check before acting. Full report: https://uav.tridgell.net/DevCallReviews/DevCallTopic/devcall_pr_reviews.html Re-reviewed at head Both blockers from the previous round are fixed, and I confirmed each myself rather than taking it on trust. Verdict is still REQUEST CHANGES, but on a new and much narrower item. Resolved
BUG — MSD is default-enabled on MatekH7A3-Wing, where the reboot request provably cannot survive the rebootEvery link verified in source at this head:
So the request is written into a discarded backup register and read back as zero: the board boots normally and nothing is said. Scope is exactly one board. NOTE — the enablement predicate is implemented twice and the two disagree on ~19 boards
NOTE — the F405 hardware test predates the stack bump
Also, for the record so nobody re-raises it: the PR removes the old Still open, unchanged, none blocking
One finding from the independent pass I'm not carrying: that the lowercase CI at this head: 40 passing, 58 pending, 0 failing — neither previously-red check has reported yet. |
Previous review (2026-08-24)Automated review note — AI-generated (Claude), validated against the live diff. Please sanity-check before acting. Re-reviewed at head Previous findings:
New:
Not carried from the cold pass: a claim about |
Previous review (2026-08-24)Automated review note — AI-generated (Claude), validated against the live diff. Please sanity-check before acting. Re-reviewed at head
CI: 38 pass / 60 pending at this head; python-cleanliness green; the delta is Python-only. |
95b16c2 to
0381590
Compare
Previous review (at head 0381590)Automated review note — AI-generated (Claude), validated against the live diff. Please sanity-check before acting. Re-reviewed at head The 46-line delta extracts the USB mass-storage gate from Still open, non-blocking and unchanged by the refactor: |
| #undef AP_REBOOT_MASS_STORAGE_ENABLED | ||
| #define AP_REBOOT_MASS_STORAGE_ENABLED 0 | ||
| #elif !defined(AP_REBOOT_MASS_STORAGE_ENABLED) | ||
| #if defined(STM32H7) && HAL_PROGRAM_SIZE_LIMIT_KB >= 2048 |
There was a problem hiding this comment.
make it only prog size limit, not MCU
| #define HAL_PROGRAM_SIZE_LIMIT_KB (BOARD_FLASH_SIZE+EXT_FLASH_SIZE_MB*1024) | ||
| #endif | ||
|
|
||
| #if defined(HAL_BOOTLOADER_BUILD) || defined(HAL_BUILD_AP_PERIPH) |
There was a problem hiding this comment.
This stuff is supposed to go into defaults_periph.h and defaults_bootloader.h
| #undef AP_REBOOT_MASS_STORAGE_ENABLED | ||
| #define AP_REBOOT_MASS_STORAGE_ENABLED 0 | ||
| #elif !defined(AP_REBOOT_MASS_STORAGE_ENABLED) | ||
| #if defined(STM32H7) && HAL_PROGRAM_SIZE_LIMIT_KB >= 2048 |
There was a problem hiding this comment.
| #if defined(STM32H7) && HAL_PROGRAM_SIZE_LIMIT_KB >= 2048 | |
| #if HAL_PROGRAM_SIZE_LIMIT_KB >= 2048 |
| fastboot_enabled = self.intdefines.get( | ||
| 'AP_FASTBOOT_ENABLED', int(mcu_defines.get('AP_FASTBOOT_ENABLED', 1))) == 1 | ||
| default_mass_storage = (self.is_normal_fw() and | ||
| self.mcu_series.startswith('STM32H7') and |
| program_size_limit >= 2048 and fastboot_enabled) | ||
| mass_storage_option = self.mass_storage_option | ||
| if mass_storage_option < 0: | ||
| mass_storage_option = self.intdefines.get('AP_REBOOT_MASS_STORAGE_ENABLED', -1) |
There was a problem hiding this comment.
User None as a flag value rather than -1
| enable_mass_storage = (getattr(cfg.options, 'enable_MASS_STORAGE', False) or | ||
| getattr(cfg.options, 'enable_mass_storage', False)) | ||
| disable_mass_storage = (getattr(cfg.options, 'disable_MASS_STORAGE', False) or | ||
| getattr(cfg.options, 'disable_mass_storage', False)) | ||
| if enable_mass_storage: | ||
| cfg.env.MASS_STORAGE_OPTION = 1 | ||
| elif disable_mass_storage: | ||
| cfg.env.MASS_STORAGE_OPTION = 0 | ||
| else: | ||
| cfg.env.MASS_STORAGE_OPTION = -1 | ||
|
|
There was a problem hiding this comment.
Let's see if we can get rid of this.
0381590 to
0dfa856
Compare
|
@/tmp/claude-1000/-home-tridge-project-Maintainer/f692e5eb-5446-4757-99e0-f4c13fdfa9f0/scratchpad/tr4-1787741949/dep_34087.md |
peterbarker
left a comment
There was a problem hiding this comment.
Good to go past the one patch removal
Use the ChibiOS USB MSD implementation with chunked multi-block SCSI transfers, pipelining and improved media error handling.
Add an early boot service that exports the microSD block device over USB mass storage before the filesystem and normal flight application start. The service retains exclusive ownership until a power cycle and continues servicing the watchdog. Enable the service on supported boards, provide explicit build control, increase the MSD worker stacks for the SD wait path, scope the ChibiOS fixed-width serial warning suppression to the MSD object, and reject explicit enable requests on unsupported boards.
0dfa856 to
9a03d44
Compare
|
Automated review note — AI-generated (Claude), validated against the live diff. Please sanity-check before acting. Full report: https://uav.tridgell.net/DevCallReviews/followups/2026_08_26_2116/devcall_pr_reviews.html Re-reviewed at head Verdict on the previous round: 0 of 3 prior findings resolved (all narrow, non-blocking) — but the structural blocker is now fixed. The push is a rebase that drops the Verdict: COMMENT — no blockers. The three carried-over edge cases remain (re-raised, non-blocking):
New code (gating compile-out, armed-refusal ordering, the dropped submodule bump) reviewed — no new findings. Codex additionally flagged two |
Summary
Adds a reboot-to-USB-mass-storage mode that exports the flight controller's microSD card as a USB block device. This provides much faster access to logs and other files than MAVLink file transfer. It should be particularly good for uploading and checking terrain data.
The mode runs as an early application service, before the normal scheduler and filesystem users start. It remains in mass-storage mode until power is removed, preventing the flight firmware and USB host from accessing the filesystem concurrently. What the user sees is their normal USB interfaces to the flight controller disappear and an ArduPilot mass storage device appears and should auto-mount. To get back to the normal flight controller mode you need to power cycle.
Depends on ArduPilot/ChibiOS#110 and ArduPilot/mavlink#517
Classification & Testing (check all that apply and add your own)
Hardware testing performed:
--enable-MASS_STORAGE, uploaded and tested from a disarmed Copter. The 15.9 GB card remained stable as a USB disk. A 32 MiB transfer measured approximately 692 kB/s write and 869 kB/s read, with a successful byte-for-byte comparison. A final 8 MiB write test measured 726 kB/s and also passed comparison.95b16c24exercised the custom-builddefine AP_REBOOT_MASS_STORAGE_ENABLED 1path. The firmware built, uploaded and verified byte-for-byte; reboot action 5 entered mass-storage mode and enumerated the 14.8 GiB FAT card. An existing 2 MiB file read at 851 kB/s. After a clean unmount and full USB power cycle, the one-shot request was consumed and the board did not re-enter mass-storage mode; an explicit bootloader handoff restored a normal Copter heartbeat on95b16c24.Description
Builds on:
The reboot request uses
REBOOT_SHUTDOWN_ACTION_REBOOT_TO_MASS_STORAGE(param1=5) withMAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN. It is rejected while the vehicle is armed, including when the normal forced-reboot magic value is supplied.The request is stored in the existing persistent watchdog data using a spare bit alongside the armed flag. After reboot, the flag is consumed once and startup enters the early USB mass-storage service instead of the normal flight application. The service initializes the microSD block device directly and continually services the watchdog.
The ChibiOS changes add multi-block SCSI transfers and double-buffer pipelining so SD-card I/O can overlap USB transfers. Both read and write paths track outstanding operations and drain them on error.
The feature requires an STM32F4, F7 or H7 board with USB and microSD support. It is enabled by default on normal STM32H7 builds whose
HAL_PROGRAM_SIZE_LIMIT_KBis at least 2048. It can be selected explicitly for other compatible builds with:It can be removed from a build with
--disable-MASS_STORAGE.To test with MAVProxy, first disarm the vehicle and run:
The USB connection will re-enumerate as a mass-storage disk containing the microSD filesystem. Safely unmount/eject the disk on the host and fully power-cycle the flight controller to return to normal operation.
We will need MissionPlanner and qgroundcontrol updates for this feature as well
AI assistance
Codex was used to inspect review feedback, implement and test follow-up fixes, and obtain an independent Claude review. The human author remains responsible for the contribution.