A probe-rs flash loader for Espressif chips.
To build the flash loader:
$ cargo $(CHIP_NAME) # builds the flashing stub
$ target-gen elf target/$(RUST_TARGET)/release/esp-flashloader output/$(CHIP_NAME).yaml --update --name $(CHIP_NAME)-flashloader
Example for the updating the esp32c3
flash algorithm.
$ cargo esp32c3
$ target-gen elf target/riscv32imc-unknown-none-elf/release/esp-flashloader output/esp32c3.yaml --update --name esp32c3-flashloader
name | supported |
---|---|
esp32 | Y |
esp32s2 | Y |
esp32s3 | Y |
esp32c2 | Y |
esp32c3 | Y |
esp32c6 | Y |
esp32h2 | Y |
- Add a feature for the chip inside
Cargo.toml
- Add a build alias to
.cargo/config.toml
- Add the ROM API linker script inside the
ld
directory. - Inside the ROM API linker script, add a memory section detailing where the program will be loaded.
It's important to note that the algorithm cannot be loaded at the start of RAM, because probe-rs has a header it loads prior to the algo hence the 64K offset. IRAM origin and length can be obtained from esp-hal. Eg: ESP32-C3 memory map
MEMORY { /* Start 64k into the RAM region */ IRAM : ORIGIN = 0x40390000, LENGTH = 0x10000 }
- Add the following snippet to the
main()
function insidebuild.rs
, adapting it for the new chip name.#[cfg(feature = "esp32c3")] let chip = "esp32c3";
- Define
spiconfig
for your the target inflash.rs
- Add your device to the table in
main.rs
and calculate addresses. - Define your target's
STATE_ADDR
#[cfg(feature = "esp32c3")] const STATE_ADDR: usize = 0x3FCC_0000;
- Follow the instructions above for building
- It may fail with:
rust-lld: error: undefined symbol: <symbol>
- In this case, you need to add the missing method in the ROM API linker script.
- Eg. ESP32-C2 is missing
esp_rom_spiflash_attach
:- Search the symbol in esp-idf
- Add it to the ROM API linker script:
PROVIDE(esp_rom_spiflash_attach = spi_flash_attach);
- Eg. ESP32-C2 is missing
- In this case, you need to add the missing method in the ROM API linker script.
- Use
target-gen
without theupdate
flag to generate a new yaml algorithm. - Update the resulting yaml file
- Update
name
- Update variants
name
,type
,core_access_options
andmemory_map
- The first
!Nvm
block represents the raw flash starting at 0 and up to the maximum supported external flash (check TRM for this, usually in "System and Memory/Features") - Next
!Ram
block corresponds to instruction bus for internal SRAM, see Internal Memory Address Mapping of TRM - Next
!Ram
block corresponds to data bus for internal SRAM, see Internal Memory Address Mapping of TRM - Next
!Nvm
corresponds to instruction bus for external memory, see External Memory Address Mapping of TRM - Next
!Nvm
corresponds to data bus for external memory, see External Memory Address Mapping of TRM
- The first
- Add
load_address
underflash_algorithms
and assign the IRAMORIGIN
value (step 4). - Add
data_load_address
underflash_algorithms
and assign an appropriate value residing in DRAM. - Add
transfer_encoding: Miniz
underload_address
- Upstream the new updates to probe-rs.