GithubHelp home page GithubHelp logo

usbd-dfu's Introduction

usbd-dfu

Crates.io Docs.rs

Implements DFU protocol version 1.1a for a usb-device device.

About

DFU protocol aims to provide a standard how USB device's firmware can be upgraded. Often, in this case firmware of the device consists of two parts: a large main firmware, and a smaller bootloader. When device is powered on, bootloader starts and either runs main firmware, or enters "firmware update" mode.

Protocol implementation tries to follows DFU 1.1a protocol as specified by AN3156 by STMicroelectronics and USB Device Firmware Upgrade Specification, Revision 1.1.

This library is a protocol implementation only, actual code that programs, erases, or reads memory or flash in not a of the library and is expected to be provided by library user.

Supported operations

  • Read (device to host) - upload command
  • Write (host to device) - download command
  • Erase
  • Erase All

Not supported operations

  • Read Unprotect - erase everything and remove read protection.

Limitations

  • Maximum USB transfer size is limited to what usb-device supports for control enpoint transfers, which is 128 bytes by default.

  • iString field in DFU_GETSTATUS is always 0. Vendor-specific string error descriptions are not supported.

DFU utilities

There are many implementations of tools to flash USB device supporting DFU protocol, for example:

Example

The example below tries to focus on DFUClass, parts related to a target controller initialization and configuration (USB, interrupts, GPIO, etc.) are not in the scope of the example.

Check examples for more information.

Also see documentation for usb-device crate, crates that supports target microcontroller and provide a corresponding HAL.

use usb_device::prelude::*;
use usbd_dfu::*;

// DFUClass will use MyMem to actually read, erase or program the memory.
// Here, a set of constant parameters must be set. These parameters
// either change how DFUClass behaves, or define host's expectations.

struct MyMem {
    buffer: [u8; 64],
    flash_memory: [u8; 1024],
}

impl DFUMemIO for MyMem {
    const MEM_INFO_STRING: &'static str = "@Flash/0x00000000/1*1Kg";
    const INITIAL_ADDRESS_POINTER: u32 = 0x0;
    const PROGRAM_TIME_MS: u32 = 8;
    const ERASE_TIME_MS: u32 = 50;
    const FULL_ERASE_TIME_MS: u32 = 50;
    const TRANSFER_SIZE: u16 = 64;

    fn read(&mut self, address: u32, length: usize) -> Result<&[u8], DFUMemError> {
        // TODO: check address value
        let offset = address as usize;
        Ok(&self.flash_memory[offset..offset+length])
    }

    fn erase(&mut self, address: u32) -> Result<(), DFUMemError> {
        // TODO: check address value
        self.flash_memory.fill(0xff);
        // TODO: verify that block is erased successfully
        Ok(())
    }

    fn erase_all(&mut self) -> Result<(), DFUMemError> {
        // There is only one block, erase it.
        self.erase(0)
    }

    fn store_write_buffer(&mut self, src:&[u8]) -> Result<(), ()>{
        self.buffer[..src.len()].copy_from_slice(src);
        Ok(())
    }

    fn program(&mut self, address: u32, length: usize) -> Result<(), DFUMemError>{
        // TODO: check address value
        let offset = address as usize;

        // Write buffer to a memory
        self.flash_memory[offset..offset+length].copy_from_slice(&self.buffer[..length]);

        // TODO: verify that memory is programmed correctly
        Ok(())
    }

    fn manifestation(&mut self) -> Result<(), DFUManifestationError> {
        // Nothing to do to activate FW
        Ok(())
    }
}

let mut my_mem = MyMem {
    buffer: [0u8; 64],
    flash_memory: [0u8; 1024],
};

// Create USB device for a target device:
// let usb_bus_alloc = UsbBus::new(peripheral);
// let usb_dev = UsbDeviceBuilder::new().build();

// Create DFUClass
let mut dfu = DFUClass::new(&usb_bus_alloc, my_mem);

// usb_dev.poll() must be called periodically, usually from USB interrupt handlers.
// When USB input/output is done, handlers in MyMem may be called.
usb_dev.poll(&mut [&mut dfu]);

Example bootloader implementation

See usbd-dfu-example for a functioning example.

usbd-dfu's People

Contributors

vitalyvb avatar mattico avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.