atsamd-rs / atsamd

Target atsamd microcontrollers using Rust
https://matrix.to/#/#atsamd-rs:matrix.org
Apache License 2.0
559 stars 200 forks source link

UF2 Support #18

Closed sajattack closed 4 years ago

sajattack commented 6 years ago

The most common way for Adafruit to flash programs to their devices is through a protocol called UF2. This protocol is part of the bootloader Adafruit ships on their boards, and it makes flashing firmware as easy as dragging and dropping a file to an emulated Mass Storage Device. I've written a UF2 converter in rust here. The question is how do you want to incorporate it into the workflow? One suggestion I've received is to write a script that runs the linker, does the objcopy and invokes my converter and use that script as the linker field of a .cargo/config file.

wez commented 6 years ago

Could it feasibly be integrated into bobbin? https://github.com/bobbin-rs/bobbin-cli/ That way you could do bobbin load to have it build, convert and copy the firmware onto the mass storage device, or bobbin run to do the same and then attach to the serial console.

One challenge with UF2 at the moment is that once the bootloader is done, the mass storage device goes away. Some work is needed in the broader rust ecosystem to get USB support to a point where the firmware side of UF2 could be done in rust also. Until we get to that point, the load portion of the flow will need to prompt the user to press the reset button to get into the bootloader.

sajattack commented 6 years ago

It looks like that would require changes to bobbin. It would be easier to use make or something that lets you run arbitrary shell commands.

sajattack commented 5 years ago

@wez I spoke with @tannewt and he said UF2 is bootloader only. There is no firmware side as you say.

sajattack commented 5 years ago

I ran my first test of UF2 and it was a success. blinky

wez commented 5 years ago

re: firmware, I'm envisioning a really easy future world where you can initiate flashing completely from the host system. I use this for example in some keyboard firmware where I press some hotkeys to jump into the bootloader ready for flashing, rather than hunting around for a way to press the little reset button.

I think something similar would be nice for UF2, but it's really more about triggering the bootloader than it is about anything else.

What I think would be nice to have is:

sajattack commented 5 years ago

Could we write something with the existing USB Serial implementation that accepts a command to jump to bootloader?

wez commented 5 years ago

The arduino firmwares typically look for an open/close of the USB CDC device as a hint to jump into the bootloader (you'll see various scripts and things use stty to trigger this condition). The usb_device stuff that we have today could be made to do this, but if you look at the example there's quite a lot of code that needs to live somewhere and be made configurable enough and driven by the end user app that this will need some thought on how to make it integrate nicely.

jcsoo commented 5 years ago

Hi, I'm the author of bobbin-cli. I've been away from embedded for a little while, but UF2 support has been on my TODO list since I first ran across the specification. Is there still interest in this?

fionawhim commented 5 years ago

What would the win be for UF2 rather than BOSSA? Would bobbin work without needing to separately install BOSSA?

I agree that the nicest thing for convenience would be support for the CDC open/close trick (which I think BOSSA supports via the --arduino-erase flag).

sajattack commented 5 years ago

Yeah, bobbin wouldn't need BOSSA.

jcsoo commented 5 years ago

I don't know all of the details of the CDC open/close trick, but that seems like it would be good for devices that already are presenting a serial interface. For those that aren't, there might be some easier ways of requesting reboot to bootloader. This could be a custom vendor-class endpoint that just waits for a magic packet, but maybe there are simpler options that don't require an endpoint: a specific control message, alternate setting, or device configuration?

jacobrosenthal commented 4 years ago

I implemented uf2 over hidapi over here https://github.com/jacobrosenthal/uf2-rs

and cargo-uf2 here https://github.com/jacobrosenthal/cargo-uf2

and am build and uploading with just cargo uf2 --release --example timer

havent released anything yet between picking names, waiting on deps, and seeing if yaketti wants it inside of cargo-flash instead/as well

jacobrosenthal commented 4 years ago

Heads up Ive decided to rename my uf2 to hf2, as technically that's what the hid over flash protocol is actually called https://github.com/jacobrosenthal/hf2-rs

Its all published on crates.io finally, and has been pretty pretty rock solid for me over the past month. A lot of the adafruit bsps we have here ship the uf2 bootloader stock so once some of you check it out I think it would be a worth addition to the examples

Ive got a cargo subcommand available atcargo install cargo-hf2 and then just cargo hf2 --release --example timer to program an example from the boards here

or a hf2 binary cargo install hf2-cli if youve got a bin and don't want to use cargohf2 flash -f neopixel_rainbow.bin -a 0x4000