2. May 2023

How to build single flashable binary for ESP32 with esptool.py

Build of ESP-IDF project produces several files, like bootloader, application binary or partition table.

Having several files makes it harder to ship the application outside of build computer.

Solution to the problem is merging binaries into single flashable file.

Build your project with idf.py as always:

cd project
idf.py build

Merge binaries into single file. At the end of build process the tool will display command for flashing. This can be used to compose command like this:

esptool.py --chip ESP32 merge_bin -o merged-flash.bin --flash_mode dio ^
  --flash_size ^
  2MB 0x0 build\bootloader\bootloader.bin ^
  0x8000 build\partition_table\partition-table.bin ^
  0x10000 build\my_app.bin

Luckily there is a simpler way, because all those arguments are stored in build/flash_args file:

Example for Bash

(cd build; esptool.py --chip esp32 merge_bin -o merged-flash.bin @flash_args)

Example for PowerShell

cd build
esptool.py --chip esp32 merge_bin -o merged-flash.bin "@flash_args"

24. March 2021

How to download binary file in Rust by reqwest

reqwest in Rust allows you to download file. The question is how to store the file on the filesystem. There are several examples on the internet where authors are calling .text() which will result in a corrupted file on the filesystem because text() is decoding UTF-8 characters.

Here is an example of how to download a binary file and store content in a file on the local file system.

File download.rs:

use std::io::Cursor;
type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;

async fn fetch_url(url: String, file_name: String) -> Result<()> {
    let response = reqwest::get(url).await?;
    let mut file = std::fs::File::create(file_name)?;
    let mut content =  Cursor::new(response.bytes().await?);
    std::io::copy(&mut content, &mut file)?;
    Ok(())
}

#[tokio::main]
async fn main() {
    fetch_url("https://georgik.rocks/wp-content/uploads/sianim.gif".to_string(), "siriel.gif".to_string()).await.unwrap();
}

File Cargo.toml:

[package]
name = "download"
version = "0.1.0"
authors = ["Georgik.Rocks"]
edition = "2018"

[dependencies]
reqwest = "*"
tokio = { version = "1", features = ["full"] }

[[bin]]
name = "download"
path = "download.rs"

To build the example type following:

cargo run