Skip to main content

Crate embassy_boot_ch32

Crate embassy_boot_ch32 

Source
Expand description

embassy-boot support for WCH CH32 microcontrollers driven by ch32-hal.

This crate is the CH32 counterpart of embassy-boot-stm32: it re-exports the generic embassy_boot types and adds the two things a CH32 needs to actually boot an application:

  • CoarseFlash - presents the CH32 internal flash (which is erased in 256 byte pages) with a coarser erase granularity, which is required by the embassy-boot swap algorithm to keep the state partition reasonably small.
  • BootLoader::load - hands control over to the application running in the active partition. On QingKe cores the application re-initializes mtvec, the global pointer and the stack pointer itself during its startup code, so all the bootloader has to do is to mask interrupts and jump.

Note that the flash driver in ch32-hal is only implemented for the v3 flash IP used by the CH32V2 and CH32V3 lines (CH32V203, CH32V208, CH32V303, CH32V305, CH32V307, …). For the older parts (v0, v1, x0, l1) the driver compiles to unimplemented!() stubs, so a runtime bootloader cannot be built for them yet.

The partition geometry is expected to be described by the usual __bootloader_active_start/__bootloader_dfu_start/__bootloader_state_start (and matching _end) linker symbols, holding offsets from the start of internal flash, exactly like in the embassy-boot examples. See BootLoaderConfig::from_linkerfile_blocking and FirmwareUpdaterConfig::from_linkerfile_blocking() (the latter is only available for target_os = "none", so it is not linked here).

ⓘ
use core::cell::RefCell;

use ch32_hal::flash::{Blocking, Flash};
use embassy_boot_ch32::{BootLoader, BootLoaderConfig, CoarseFlash};
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
use embassy_sync::blocking_mutex::Mutex;

type BootFlash = CoarseFlash<Flash<'static, Blocking>, 8192>;

let flash: Mutex<NoopRawMutex, RefCell<BootFlash>> =
    Mutex::new(RefCell::new(CoarseFlash(Flash::new_blocking(p.FLASH))));

let config = BootLoaderConfig::from_linkerfile_blocking(&flash, &flash, &flash);
let loader = BootLoader::prepare::<_, _, _, 1024>(config);

unsafe { loader.load(embassy_boot_ch32::active_start()) }

The repository contains a complete example pair: a blocking bootloader and an embassy application, documented in its README (chip matrix, partition maps, serial console, USB DFU and CAN-bus transports). The examples are standalone workspaces, so they are not part of these docs and every link here points at GitHub.

Re-exports§

pub use embedded_storage;

Modules§

can
The wire protocol of the CAN-bus firmware update transport, as specified by [docs/can-update-protocol.md] in the repository.

Structs§

AlignedBuffer
Buffer aligned to 32 byte boundary, largest known alignment requirement for embassy-boot.
BlockingFirmwareState
Manages the state partition of the firmware update.
BlockingFirmwareUpdater
Blocking FirmwareUpdater is an application API for interacting with the BootLoader without the ability to ‘mess up’ the internal bootloader state
BootLoader
A bootloader for CH32 devices.
BootLoaderConfig
Bootloader flash configuration holding the three flashes used by the bootloader
CoarseFlash
A flash adapter that reports a coarser erase granularity than the underlying driver.
FirmwareState
Manages the state partition of the firmware update.
FirmwareUpdater
FirmwareUpdater is an application API for interacting with the BootLoader without the ability to ‘mess up’ the internal bootloader state
FirmwareUpdaterConfig
Firmware updater flash configuration holding the two flashes used by the updater

Enums§

BootError
Errors returned by bootloader
FirmwareUpdaterError
Errors returned by FirmwareUpdater
State
The state of the bootloader after running prepare.

Constants§

FLASH_BASE
Address of the beginning of the internal flash array as seen by the core.

Functions§

active_end
End offset (exclusive) of the active partition, see active_start.
active_size
Size of the active partition in bytes.
active_start
Offset of the active partition from FLASH_BASE, as described by the __bootloader_active_start linker symbol.
dfu_end
End offset (exclusive) of the dfu partition, see dfu_start.
dfu_size
Size of the dfu partition in bytes.
dfu_start
Offset of the dfu partition from FLASH_BASE, as described by the __bootloader_dfu_start linker symbol.
disable_interrupts
Masks all maskable interrupts.
state_end
End offset (exclusive) of the state partition, see state_start.
state_size
Size of the state partition in bytes.
state_start
Offset of the state partition from FLASH_BASE, as described by the __bootloader_state_start linker symbol.
system_reset
Requests a system reset through the PFIC and waits for it.