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)-flashloaderExample 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 
lddirectory. - 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 
spiconfigfor your the target inflash.rs - Add your device to the table in 
main.rsand 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-genwithout theupdateflag to generate a new yaml algorithm. - Update the resulting yaml file
 - Update 
name - Update variants 
name,type,core_access_optionsandmemory_map- The first 
!Nvmblock 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 
!Ramblock corresponds to instruction bus for internal SRAM, see Internal Memory Address Mapping of TRM - Next 
!Ramblock corresponds to data bus for internal SRAM, see Internal Memory Address Mapping of TRM - Next 
!Nvmcorresponds to instruction bus for external memory, see External Memory Address Mapping of TRM - Next 
!Nvmcorresponds to data bus for external memory, see External Memory Address Mapping of TRM 
 - The first 
 - Add 
load_addressunderflash_algorithmsand assign the IRAMORIGINvalue (step 4). - Add 
data_load_addressunderflash_algorithmsand assign an appropriate value residing in DRAM. - Add 
transfer_encoding: Minizunderload_address - Upstream the new updates to probe-rs.