Skip to main content

Crate picoboot

Crate picoboot 

Source
Expand description

§picoboot

A crate for connecting to and communicating with RP2040/RP2350 microcontrollers using the PICOBOOT USB interface.

Supports custom VID/PID targets and extensions to the PICOBOOT protocol.

§Getting Started

  1. Use Picoboot to find a PICOBOOT device.

  2. Use Picoboot::connect() to connect to the device and get a Connection

  3. Use the Connection to interact with the device, such as reading/writing/erasing flash memory.

§Example

use picoboot::{Picoboot, Access, Error};

#[tokio::main]
async fn main() -> Result<(), Error> {
    // Create connection to first RP2040/RP2350 found
    let mut picoboot = Picoboot::from_first(None).await?;
    let conn = picoboot.connect().await?;

    // Claim exclusive access, ejecting the BOOTSEL mass storage device and
    // exit XIP mode (only necessary on RP2040)
    conn.set_exclusive_access(Access::ExclusiveAndEject).await?;
    conn.exit_xip().await?;

    // Erase first 4096 bytes of flash (1 sector)
    conn.flash_erase_start(4096).await?;

    // Write 256 bytes of data to start of flash (1 page)
    conn.flash_write_start(&[0u8; 256]).await?;

    // Retrieve 256 bytes of data from start of flash
    let data = conn.flash_read_start(256).await?;

    Ok(())
}

§Crate Overview

  • High level APIs for common operations: reading/writing/erasing flash
  • Low level APIs for sending/receiving PICOBOOT commands
  • Support for both RP2040 and RP2350 targets
  • Support for custom VID/PID targets (RP2040/RP2350 that have been OTP programmed)
  • Supports async/await using tokio and smol runtimes
  • Native Rust USB implementation using nusb - no libusb dependency
  • Supports extensions to the PICOBOOT protocol using custom magics in the header, and the picobootx device side implementation.

§PICOBOOT Overview

The RP2040/RP2350 provide two mechanisms out of the box for flashing firmware when in BOOTSEL mode:

  • UF2 mass storage device interface - copy UF2 files to the mounted drive
  • PICOBOOT USB interface - send commands to the device to read/write/erase flash, and other operations

PICOBOOT is more flexible than the UF2 mass storage interface, especially for programmatic reading and writing of firmware images, as it:

  • does not require superuser access to mount/unmount drives
  • it enables platform independent code, as there are no filesystem access differences to handle
  • gives greater control over the device, including reading back flash contents, erasing individual flash sectors, and writing individual flash pages, reading RAM, resetting the device, etc

For more details on PICOBOOT, see the RP2040 and RP2350 datasheets.

§Feature Flags

Used to indicate the desired async runtime for nusb.

default = ["tokio", "logging"]
tokio = ["nusb/tokio"]
smol = ["nusb/smol"]
logging = ["deku/logging"]

Also reader to include the reader airfrog-rpc::io::Reader implementation.

§Acknowledgement

This crate was based on picoboot-rs by Hickok-Dickson and provides:

  • additional, simplified APIs
  • stronger typing
  • async/await support
  • native Rust USB using nusb
  • safer serialization/deserialization using deku

Re-exports§

pub use usb::Connection;
pub use usb::Picoboot;
pub use cmd::PicobootCmd;
pub use cmd::PicobootCmdId;
pub use cmd::PicobootXCmd;

Modules§

cmd
Command Module
usb
USB Module

Enums§

Access
Exclusive access modes for PICOBOOT EXCLUSIVE_ACCESS command.
Direction
Data transfer direction for PICOBOOT commands.
Error
picoboot error type.
RebootType
Reboot type for Picoboot::reboot
Speed
USB connection speed
Target
Target type for PicobootConnection

Constants§

FLASH_END_RP2040
RP2040 memory address for the end of flash storage
FLASH_END_RP2350
RP2350 memory address for the end of flash storage
FLASH_START
RP MCU memory address for the start of flash storage
PAGE_SIZE
RP MCU flash page size (for writing) - 256 bytes
PICOBOOT_MAGIC
RP MCU magic number for USB interfacing
PICOBOOT_PID_RP2040
RP2040 USB Product ID
PICOBOOT_PID_RP2350
RP2350 USB Product ID
PICOBOOT_VID
RP USB Vendor ID
ROM_END_RP2040
RP2040 memory address for the end of ROM storage
ROM_END_RP2350
RP2350 memory address for the end of ROM storage
ROM_START
RP MCU memory address for the start of ROM storage
SECTOR_SIZE
RP MCU flash sector size (for erasing) - 4096 bytes
SRAM_END_RP2040
RP2040 memory address for the end of SRAM storage
SRAM_END_RP2350
RP2350 memory address for the end of SRAM storage
SRAM_START_RP2040
RP MCU memory address for the start of SRAM storage
STACK_POINTER_RP2040
RP2040 memory address for the initial stack pointer
STACK_POINTER_RP2350
RP2350 memory address for the initial stack pointer
UF2_ABSOLUTE_FAMILY_ID
UF2_DATA_FAMILY_ID
UF2_FAMILY_ID_MAX
UF2_RP2040_FAMILY_ID
UF2 Family ID for RP2040
UF2_RP2350_ARM_NS_FAMILY_ID
UF2 Family ID for RP2350 (ARM, Non-Secure TrustZone)
UF2_RP2350_ARM_S_FAMILY_ID
UF2 Family ID for RP2350 (ARM, Secure TrustZone)
UF2_RP2350_RISCV_FAMILY_ID
UF2 Family ID for RP2350 (RISC-V)
XIP_SRAM_END_RP2040
RP2040 memory address for the end of XIP (execute-in-place) SRAM storage
XIP_SRAM_END_RP2350
RP2350 memory address for the end of XIP (execute-in-place) SRAM storage
XIP_SRAM_START_RP2040
RP2040 memory address for the start of XIP (execute-in-place) SRAM storage
XIP_SRAM_START_RP2350
RP2350 memory address for the start of XIP (execute-in-place) SRAM storage