> The RP2040 is impossible to brick. It comes with a read-only bootloader that can either mount as a USB mass storage device (firmware updates can just be copypasted to the "storage device"), or use its own simple USB protocol.
Can anyone explain what this means? How is it both read-only and updateable? If the latter, how is it unbrickable?
He's saying that the bootloader is in ROM so it's unbrickable, but the application code that the bootloader jumps into can be updated over USB. Most mid-range and higher microcontrollers have a similar feature, but they almost always have a custom protocol that requires a specialized flashing program rather than showing up as a mass storage device.
To be frank, I don't get its appeal at all. Most hobbyist uCs were already unbrickable, and using mass storage mode for flashing is rather cumbersome and clunky to automate as soon as you're past hello worlds.
Hence they made the Pico Debug Probe [0]. It makes it super easy to reflash firmware to the Pico in a quick iterative loop.
However, the appeal of mounting as a mass storage device is not for iterative development (as you mentioned). Invariably something breaks, and the easiest way to get back on track is to reflash their default blank firmware using the mass storage interface.
I can use things like dfu-util or esptool for quick iterative loops without any additional hardware. Hence my point - mass storage is a downgrade over what other µCs on the market were already doing with their ROM bootloaders before RP2040.
Just to note: with the RP2040 you don't need additional hardware (debug probe) for quick iterative development, you can use picotool[1] (using -f allows you to flash and reboot without needing to get it to bootsel mode).
...and it doesn't use mass storage at all, blocking access to it in a clunky way to prevent simultaneous usage.
UMS seems like a nice idea when you first hear about it, but it doesn't really offer much once you look at it closer. The only proper argument for it is "no special software needed", but it a world where picotool is `apt install picotool` away that's not very advantageous anyway and only causes automount annoyances.
UMS shines where you have a device with a filesystem in its flash that you can access to actually manage the files stored there. Super useful for stuff like MicroPython. In contrast, pseudo-mass storage like on RP2040 doesn't seem very useful at all. It makes it appear more approachable, but only superficially.
The whole UF2 idea has to do with the educational background of RaspberryPi. The protocol was invented by Microsoft for use in some kind of similar educational board with the express purpose of not needing drivers, being reasonably crossplatform and crucially not needing any special permissions to access the device. The end result is that in some kind of educational setting you can use some kind of cloud/remote IDE on iPad, stick the RPi-Pico into the iPad and flash it, no blessing from Apple needed.
Oh. So it's just a result of locked-down walled gardens being so widespread that they influence the world around them. Depressing, but thank you for pointing it out anyway; on my phone I can just run picotool itself and it's easy to forget how dystopian it all got outside of the niche I'm in.
I've never had great luck with the mass storage flashing. It works fine, but boy is it slow. I bought a J-Link a few years ago and haven't looked back.
(It just takes a long time for the OS to recognize a USB device. And you have to press the reset button yourself in order to enter the bootloader. With something like J-Link, your build script can handle pressing the reset button and sending the code, saving you quite a bit of time between iterations.)
A debug probe is nice (quite possibly a must) if you're actively developing, but for deploying in a hobbyist environment, USB is hard to beat.
I make open source espresso machine hardware (github.com/variegated-coffee), and it's nice to be able to give users a wired way to update firmwares that doesn't require extra hardware.
I completely agree that it's inconvenient as a developer tool, a debug probe is much, much nicer.
I just think that despite all testing and care bugs are still possible, and the ROM bootloader is a backup that's always there. Plop a tiny switch on the PCB, and even if I screw up an OTA update customers will still be able to flash with no special tools (if the device has a USB port, that is).
I also use it as a recovery state for panics, makes the device impossible to brick by a panic loop.
> I just think that despite all testing and care bugs are still possible, and the ROM bootloader is a backup that's always there.
That's orthogonal to mass storage mode. ROM bootloaders were standard in this class of microcontrollers for years, but they usually don't use UMS. One could argue that UMS is perhaps better than some custom incompatible solutions, but then that's what DFU is there for - a standard way to flash things over USB.
Interesting, I've got the exact opposite experience.
Small to medium production runs are always a bit of a pain, because you have to do a lot of coordination with the factory when it comes to tooling. You have to ship a custom programmer, get them to install the drivers on whatever OS they are using, and then find a way to write custom code to interact with the programmer and deal with all the possible error conditions.
The RP2040? A simple script which detects the presence of a RPI-labelled flash drive, copies a file, and repeats. Written in half an hour. Drivers? Not an issue. Hardware? Everyone has a USB cable lying around already. Error conditions? It either succeeds, or it doesn't - the OS handles the rest.
The bootloader is read-only. What the bootloader loads isn't. If the thing you're trying to boot into is faulty, it doesn't matter because you can just replace the thing the bootloader is trying to load.
If the bootloader itself was faulty, the device would be bricked.
When the bootloader is not read-only, you can upload another bootloader.
This is great in a different way because custom bootloaders allow for more flexibility.
For example, you may want to keep two copies of your firmware on the chip: One that you're uploading, and one you can fall back to if the most recent one has problems. This protects you against failure during firmware upload or post-deployment failure, because you only overwrite one of the two. So if the device switches off while flashing it, and you boot back up, a custom bootloader can just default to the older copy.
But... what if you update the bootloader and it fails?
Then you can't use the bootloader to upload new firmware. Bricked.
To unbrick a bootloader you need to overwrite the bootloader using alternative methods that don't involve the bootloader, which usually involves attaching wires to the print. This is highly inconvenient in a production setting: Maybe your hardware is encased, embedded in a bigger thing, or located on a pole on a mountain top in a different country.
So a read-only bootloader is a safe choice, and you can make other workarounds wrt. flexibility.
You can have several bootloader stages, and in fact that's how the RP2040 works [1]!
Stage 1 bootloader is the one in ROM and it normally just reads stage 2 from the flash chip. Stage 2 then initialises the flash properly, and you can have further stages like [2] to implement the trial-rollback procedure.
Stage 1 is a safety net, even if the trial-rollback procedure goes terribly wrong the device can still be unbricked over USB.
I used to work on a product where we did exactly that, and the devices literally ran on mountain tops. Our development and testing process was very rigorous and would be unrecognizable to most developers today, however. We certainly weren't shipping new code to those devices after every sprint.
If you anticipate the need to update the bootloader, you would use a multistage bootloader approach where the first is never altered (as the bootloader should never be altered) and its main function is to select which updatable second stage bootloader to load from multiple options (multiple so that even if one is interrupted mid-update by the application, there is a valid fallback).
My gut says if you're worried about this in the bootloader, it might be doing too much.
Particularly neat approach to both reducing the attack surface of the bootloader and improving the reliability of the actual OTA update process is to have only the bootloader flash the active application/second-stage flash partition. The idea is that the normal application code somehow acquires the new version, verifies it and writes it into separate flash partition and then reboots, bootloader sees that record and, does minimal check for correctness and flashes that to right location. That way the bootloader does not have to know anything about how to get the new firmware image and does not process any untrusted input.
When I actually have these conversations with security guys, it's because they've either missed their window on contributing to part selection (in one case because that team hadn't been hired yet!) or no one consulted them in the first place. In both cases the solution is to write some guidelines and get the EEs to use them during part selection in the future.
The bootloader is read-only, the firmware it boots is updateable.
The bootloader allows you to update the device with new firmware. MCU are different than computers. And since you can't overwrite the bootloader, you can't brick the MCU. You can always just reset it.
fwiw; I've never bricked an MCU buy flashing something weird onto it. The hobbyist MCUs sold are typically quite easy to re-flash with new firmware.
Looks like there are docs that states RP2040's USB code is on an internal mask ROM, which can't be overwritten if true. The RP2040 don't have a user code storage at all, and it resides in external SPI Flash, so those can be written over without having to have an all-Flash architecture.
I've never seen other uC accidentally blowing out bootloaders, though. They have clever tricks that prevents write access on a firmware area while also allowing such firmware area updates.
I suspect the author might have heard about some horror stories like AVR's intentional in-circuit programming disabling feature accidentally triggering due to configuration errors upstream to developers or sporadic errors in data transfer, which "just" needs requires +12V input to unlock. Presumably the 2040 won't have such gotchas that scares hobbyists.
I think it's saying that firmware updates are not persistent. You have to apply them every time at boot time. So if it boots once, it will boot every time. If you ever get bad firmware, you just rollback or roll further forward in your boot media.
Unbrickable for the RP2040 itself, but most SPI flash chips (including ones on the RP Pico) have permanently lockable regions. You can lock them open though.
Can anyone explain what this means? How is it both read-only and updateable? If the latter, how is it unbrickable?