Skip to content

Implement mpremote rm -r :/ fallback for UF2 erase on non-rp2 ports (execute after firmware flash)#41

Merged
Josverl merged 6 commits into
mainfrom
copilot/fix-32
Sep 2, 2025
Merged

Implement mpremote rm -r :/ fallback for UF2 erase on non-rp2 ports (execute after firmware flash)#41
Josverl merged 6 commits into
mainfrom
copilot/fix-32

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Aug 29, 2025

This PR implements mpremote rm -r :/ as a fallback erase method for UF2 ports that don't have a clear method to erase the flash, specifically addressing SAMD and other non-rp2 UF2 ports. The erase command is executed after firmware flashing and board restart to ensure the board is accessible via mpremote.

Problem

Previously, when using --erase with UF2 ports other than rp2 (such as SAMD), the tool would only display a warning and skip the erase operation:

WARNING: Erase not (yet) supported on .UF2, for port samd, skipping erase.

This left users without any erase functionality for SAMD and other UF2 ports, while rp2 ports had proper erase support via universal_flash_nuke.uf2.

Solution

The implementation adds a fallback erase mechanism that uses mpremote rm -r :/ to erase the filesystem on non-rp2 UF2 ports. Critically, the erase command executes after the firmware is flashed and the board has restarted, ensuring the board is accessible via mpremote.

# For non-rp2 UF2 ports (like SAMD), erase filesystem after flash and restart
if erase_filesystem_after_flash:
    log.info(f"Erasing {mcu.port} filesystem using mpremote rm -r :/")
    try:
        rc, result = mcu.run_command(["rm", "-r", ":/"], timeout=30)
        if rc == 0:
            log.info(f"Successfully erased filesystem on {mcu.port}")
        else:
            log.warning(f"Failed to erase filesystem on {mcu.port}: {result}")
    except Exception as e:
        log.warning(f"Failed to erase filesystem on {mcu.port}: {e}")

Execution Flow

RP2 Ports (unchanged):

  1. Flash universal_flash_nuke.uf2 to erase (before firmware)
  2. Flash firmware
  3. Wait for restart

Non-RP2 Ports (SAMD, NRF, etc.):

  1. Flash firmware
  2. Wait for restart
  3. Execute mpremote rm -r :/ to erase filesystem (board is now accessible)

Behavior Changes

Port Type Before After
RP2 ✓ Uses universal_flash_nuke.uf2 ✓ Uses universal_flash_nuke.uf2 (unchanged)
SAMD ✗ Warning: "Erase not supported" ✓ Uses mpremote rm -r :/ after flashing
NRF ✗ Warning: "Erase not supported" ✓ Uses mpremote rm -r :/ after flashing
Other UF2 ✗ Warning: "Erase not supported" ✓ Uses mpremote rm -r :/ after flashing

Key Features

  • Correct Timing: Erase command executes when board is accessible via mpremote
  • Backward Compatible: RP2 ports continue using the existing flash nuke method
  • Graceful Fallback: Failed erase attempts are logged but don't prevent firmware flashing
  • Proper Logging: Clear messages inform users about the erase method and timing
  • Error Handling: Exceptions are caught and logged as warnings

Testing

Added comprehensive tests to verify:

  • SAMD ports correctly use the mpremote rm -r :/ fallback after flashing
  • Failed erase operations are handled gracefully
  • RP2 ports continue using the existing method
  • Erase command is not called when erase=False

This change provides erase functionality for SAMD and other UF2 ports where no clear erase method previously existed, giving users a consistent experience across all UF2 port types while ensuring the command executes at the correct time when the board is accessible.

Fixes #32.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: Josverl <981654+Josverl@users.noreply.github.com>
Copilot AI changed the title [WIP] use mpremote rm -r :/ to --erase Implement mpremote rm -r :/ fallback for UF2 erase on non-rp2 ports Aug 29, 2025
Copilot AI requested a review from Josverl August 29, 2025 19:30
@codecov
Copy link
Copy Markdown

codecov Bot commented Aug 29, 2025

Codecov Report

❌ Patch coverage is 76.19048% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.95%. Comparing base (b88d263) to head (cfb03d4).
⚠️ Report is 8 commits behind head on main.

Files with missing lines Patch % Lines
mpflash/mpremoteboard/runner.py 72.72% 3 Missing ⚠️
mpflash/flash/uf2/__init__.py 80.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #41      +/-   ##
==========================================
+ Coverage   67.43%   67.95%   +0.51%     
==========================================
  Files          52       52              
  Lines        2598     2612      +14     
  Branches      401      403       +2     
==========================================
+ Hits         1752     1775      +23     
+ Misses        720      712       -8     
+ Partials      126      125       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Josverl
Copy link
Copy Markdown
Owner

Josverl commented Sep 1, 2025

@copilot
When I test this on actual hardware I get the following error:

mpflash flash --erase
2025-09-02 01:09:33.830 | DEBUG    | mpflash.db.core:<module>:17 - Connecting to database at sqlite:///C:/Users/josverl/Downloads/firmware/mpflash.db

01:09:35 | ℹ️ Flashing SEEED_WIO_TERMINAL v1.26.0 to 1 serial ports
01:09:35 | ℹ️ Target ports: COM40
01:09:35 | ℹ️ Updating SEEED_WIO_TERMINAL on COM40 to v1.26.0
01:09:35 | ℹ️ Entering bootloader on COM40 using methods ['touch1200', 'mpy', 'manual']
01:09:35 | ℹ️ Attempting bootloader on COM40 using 'Touch 1200Bd'
01:09:37 | ℹ️ Using mpremote rm -r :/ to erase samd filesystem                                                                                                                                                                                                                                             
01:09:38 | ⚠️ mpremote: failed to access COM40 (it may be in use by another program)

01:09:38 | ⚠️ Failed to erase filesystem on samd: []
01:09:38 | ℹ️ Board is in bootloader mode                                                                                                                                                                                                                                                                  
01:09:38 | ℹ️ Board ID: SAMD51P19A-WioTerminal-v0
01:09:38 | ℹ️ Copying SEEED_WIO_TERMINAL-v1.26.0.uf2 to E:\.
01:09:39 | ✅ Done copying, resetting the board.
01:09:41 | ℹ️ Flashed 1 boards                                                                                                                                                                                                                                                                             
                        Updated boards after flashing                                                                                                                                                                                                                                                      
┏━━━━━━┳━━━━━━━━━━━┳━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━┓
┃Serial┃Family     ┃Port┃Board                            ┃CPU       ┃Version┃
┡━━━━━━╇━━━━━━━━━━━╇━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━┩
│COM40 │micropython│samd│SEEED_WIO_TERMINAL               │SAMD51P19A│v1.26.0│
│      │           │    │Wio Terminal D51R with SAMD51P19A│          │       │
└──────┴───────────┴────┴─────────────────────────────────┴──────────┴───────┘

The conclusion is that the mpremote rm -r :/ command is issued at a time that the board is not reacable for mpremote as it is in flashing mode.
Update the code so in this case the erase command (mpremote rm -r ) is given only after the board has been updated and is reset

@Josverl
Copy link
Copy Markdown
Owner

Josverl commented Sep 1, 2025

@copilot,
Also the new tests fail with an error :

ERROR tests/flash/test_flash_uf2_A.py::test_flash_uf2_erase_fallback_samd - AttributeError: Mock object has no attribute 'truediv'
ERROR tests/flash/test_flash_uf2_A.py::test_flash_uf2_erase_fallback_failed - AttributeError: Mock object has no attribute 'truediv'

…lash and restart

Co-authored-by: Josverl <981654+Josverl@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Sep 1, 2025

@copilot
When I test this on actual hardware I get the following error:

...

Fixed! The issue was that mpremote rm -r :/ was being executed while the board was in bootloader mode and unreachable via mpremote. I've moved the erase command to execute after the firmware is flashed and the board has restarted, when it's accessible via mpremote.

Key changes in commit 59cd26d:

  • The erase command now runs after mcu.wait_for_restart()
  • RP2 ports continue using the existing flash nuke method (unchanged)
  • Added proper test coverage for the new timing
  • All UF2 tests are passing

The board should now be reachable when the erase command executes.

Copilot AI changed the title Implement mpremote rm -r :/ fallback for UF2 erase on non-rp2 ports Implement mpremote rm -r :/ fallback for UF2 erase on non-rp2 ports (execute after firmware flash) Sep 1, 2025
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Sep 1, 2025

@copilot,
Also the new tests fail with an error :

...

The test failures have been fixed in commit 59cd26d. The issue was in the mock_destination fixture where __truediv__ wasn't properly mocked as a method. Changed:

# Before (broken):
destination.__truediv__.return_value = info_file

# After (fixed):  
destination.__truediv__ = mock.Mock(return_value=info_file)

All UF2 tests are now passing, including the test_flash_uf2_erase_fallback_samd and test_flash_uf2_erase_fallback_failed tests that were previously failing.

Josverl and others added 3 commits September 2, 2025 09:51
update error handling and tag management in runner.py to ignore inability to erase root

Signed-off-by: Jos Verlinde <Jos_Verlinde@hotmail.com>
…unctionality

Signed-off-by: Jos Verlinde <Jos_Verlinde@hotmail.com>
Signed-off-by: Jos Verlinde <jos_verlinde@hotmail.com>
@Josverl Josverl marked this pull request as ready for review September 2, 2025 08:01
@Josverl Josverl merged commit 89aefc6 into main Sep 2, 2025
18 of 19 checks passed
@Josverl Josverl deleted the copilot/fix-32 branch September 2, 2025 08:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

use mpremote rm -r :/ to --erase

2 participants