Skip to content

Commit a55179f

Browse files
Unify configuration methods (#551)
* feat: Support local config file and add config parameters * refactor: Avoid cloning and clippy lints * feat: Verify partition table and bootloader extensions * fix: Update save_path * feat: Replace cargo metadata for config file * style: Improve redability * docs: Update changelog * feat: Update local config path * feat: Remove format param from cargo metadata * feat: Remove port param * docs: Update usage section * docs: Update config documentation
1 parent 5852e2c commit a55179f

File tree

10 files changed

+171
-137
lines changed

10 files changed

+171
-137
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3737
### Changed
3838
- Created `FlashData`, `FlashDataBuilder` and `FlashSettings` structs to reduce number of input arguments in some functions (#512, #566)
3939
- `espflash` will now exit with an error if `defmt` is selected but not usable (#524)
40+
- Unify configuration methods (#551)
4041

4142
### Removed
4243

cargo-espflash/README.md

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@ Supports the **ESP32**, **ESP32-C2/C3/C6**, **ESP32-H2**, **ESP32-P4**, **ESP32-
1717
- [Permissions on Linux](#permissions-on-linux)
1818
- [Windows Subsystem for Linux](#windows-subsystem-for-linux)
1919
- [Bootloader and Partition Table](#bootloader-and-partition-table)
20-
- [Package Metadata](#package-metadata)
2120
- [Configuration File](#configuration-file)
22-
- [Configuration Examples](#configuration-examples)
21+
- [Configuration precedence](#configuration-precedence)
2322
- [Logging Format](#logging-format)
2423
- [License](#license)
2524
- [Contribution](#contribution)
@@ -83,7 +82,9 @@ Commands:
8382
flash Flash an application in ELF format to a target device
8483
monitor Open the serial monitor without flashing the connected target device
8584
partition-table Convert partition tables between CSV and binary format
85+
read-flash Read SPI flash content
8686
save-image Generate a binary application image and save it to a local disk
87+
checksum-md5 Calculate the MD5 checksum of the given region
8788
help Print this message or the help of the given subcommand(s)
8889
8990
Options:
@@ -113,43 +114,46 @@ If the `--bootloader` and/or `--partition-table` options are provided then these
113114

114115
[esp-idf-sys]: https://github.com/esp-rs/esp-idf-sys
115116

116-
## Package Metadata
117-
118-
You're able to specify paths to bootloader and partition table files and image format in your package's Cargo metadata for per-project configuration:
119-
120-
```toml
121-
[package.metadata.espflash]
122-
bootloader = "bootloader.bin" # Must be a binary file
123-
partition_table = "partitions.csv" # Supports CSV and binary formats
124-
format = "direct-boot" # Can be 'esp-bootloader' or 'direct-boot'
125-
```
126-
127117
## Configuration File
128118

129-
It's possible to specify a serial port and/or USB VID/PID values by setting them in a configuration file. The location of this file differs based on your operating system:
130-
131-
| Operating System | Configuration Path |
132-
| :--------------- | :---------------------------------------------------------------- |
133-
| Linux | `$HOME/.config/espflash/espflash.toml` |
134-
| macOS | `$HOME/Library/Application Support/rs.esp.espflash/espflash.toml` |
135-
| Windows | `%APPDATA%\esp\espflash\espflash.toml` |
136-
137-
### Configuration Examples
138-
139-
You can either configure the serial port name like so:
140-
141-
```
142-
[connection]
143-
serial = "/dev/ttyUSB0"
144-
```
145-
146-
Or specify one or more USB `vid`/`pid` couple:
147-
148-
```
149-
[[usb_device]]
150-
vid = "303a"
151-
pid = "1001"
152-
```
119+
The configuration file allows you to define various parameters for your application:
120+
- Serial port:
121+
- By name:
122+
```toml
123+
[connection]
124+
serial = "/dev/ttyUSB0"
125+
```
126+
- By USB VID/PID values:
127+
```toml
128+
[[usb_device]]
129+
vid = "303a"
130+
pid = "1001"
131+
```
132+
- Baudrate:
133+
```toml
134+
baudrate = 460800
135+
```
136+
- Bootloader:
137+
```toml
138+
bootloader = "path/to/custom/bootloader.bin"
139+
```
140+
- Partition table
141+
```toml
142+
partition_table = "path/to/custom/partition-table.bin"
143+
```
144+
145+
You can have a local and/or a global configuration file:
146+
- For local configurations, store the file under the current working directory with the name `espflash.toml`
147+
- Global file location differs based on your operating system:
148+
- Linux: `$HOME/.config/espflash/espflash.toml`
149+
- macOS: `$HOME/Library/Application Support/rs.esp.espflash/espflash.toml`
150+
- Windows: `%APPDATA%\esp\espflash\espflash.toml`
151+
152+
### Configuration precedence
153+
154+
1. Environment variables: If `ESPFLASH_PORT` or `ESPFLASH_BAUD` are set, the will be used instead of the config file value.
155+
2. Local configuration file
156+
3. Global configuration file
153157

154158
## Logging Format
155159

cargo-espflash/src/error.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,6 @@ use thiserror::Error;
1010
#[derive(Debug, Diagnostic, Error)]
1111
#[non_exhaustive]
1212
pub enum Error {
13-
#[error("Specified bootloader path is not a .bin file")]
14-
#[diagnostic(code(cargo_espflash::invalid_bootloader_path))]
15-
InvalidBootloaderPath,
16-
17-
#[error("Specified partition table path is not a .bin or .csv file")]
18-
#[diagnostic(code(cargo_espflash::invalid_partition_table_path))]
19-
InvalidPartitionTablePath,
20-
2113
#[error("The current workspace is invalid, and could not be loaded")]
2214
#[diagnostic(
2315
code(cargo_espflash::invalid_workspace),

cargo-espflash/src/main.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ fn main() -> Result<()> {
222222
Commands::Monitor(args) => serial_monitor(args, &config),
223223
Commands::PartitionTable(args) => partition_table(args),
224224
Commands::ReadFlash(args) => read_flash(args, &config),
225-
Commands::SaveImage(args) => save_image(args),
225+
Commands::SaveImage(args) => save_image(args, &config),
226226
Commands::ChecksumMd5(args) => checksum_md5(&args, &config),
227227
}
228228
}
@@ -239,14 +239,10 @@ pub fn erase_parts(args: ErasePartsArgs, config: &Config) -> Result<()> {
239239
return Err(EspflashError::StubRequired).into_diagnostic();
240240
}
241241

242-
let metadata_partition_table = PackageMetadata::load(&args.package)
243-
.ok()
244-
.and_then(|m| m.partition_table);
245-
246242
let partition_table = args
247243
.partition_table
248244
.as_deref()
249-
.or(metadata_partition_table.as_deref());
245+
.or(config.partition_table.as_deref());
250246

251247
let mut flash = connect(&args.connect_args, config, false, false)?;
252248
let partition_table = match partition_table {
@@ -303,14 +299,14 @@ fn flash(args: FlashArgs, config: &Config) -> Result<()> {
303299
.flash_args
304300
.bootloader
305301
.as_deref()
306-
.or(metadata.bootloader.as_deref())
302+
.or(config.bootloader.as_deref())
307303
.or(build_ctx.bootloader_path.as_deref());
308304

309305
let partition_table = args
310306
.flash_args
311307
.partition_table
312308
.as_deref()
313-
.or(metadata.partition_table.as_deref())
309+
.or(config.partition_table.as_deref())
314310
.or(build_ctx.partition_table_path.as_deref());
315311

316312
if let Some(path) = &bootloader {
@@ -330,7 +326,7 @@ fn flash(args: FlashArgs, config: &Config) -> Result<()> {
330326
bootloader,
331327
partition_table,
332328
args.flash_args.partition_table_offset,
333-
args.flash_args.format.or(metadata.format),
329+
args.flash_args.format,
334330
args.flash_args.target_app_partition,
335331
flash_settings,
336332
args.flash_args.min_chip_rev,
@@ -534,7 +530,7 @@ fn build(
534530
Ok(build_ctx)
535531
}
536532

537-
fn save_image(args: SaveImageArgs) -> Result<()> {
533+
fn save_image(args: SaveImageArgs, config: &Config) -> Result<()> {
538534
let metadata = PackageMetadata::load(&args.build_args.package)?;
539535
let cargo_config = CargoConfig::load(&metadata.workspace_root, &metadata.package_root);
540536

@@ -545,15 +541,15 @@ fn save_image(args: SaveImageArgs) -> Result<()> {
545541
.save_image_args
546542
.bootloader
547543
.as_deref()
548-
.or(metadata.bootloader.as_deref())
544+
.or(config.bootloader.as_deref())
549545
.or(build_ctx.bootloader_path.as_deref())
550546
.map(|p| p.to_path_buf());
551547

552548
let partition_table = args
553549
.save_image_args
554550
.partition_table
555551
.as_deref()
556-
.or(metadata.partition_table.as_deref())
552+
.or(config.partition_table.as_deref())
557553
.or(build_ctx.partition_table_path.as_deref())
558554
.map(|p| p.to_path_buf());
559555

@@ -582,7 +578,7 @@ fn save_image(args: SaveImageArgs) -> Result<()> {
582578
bootloader.as_deref(),
583579
partition_table.as_deref(),
584580
args.save_image_args.partition_table_offset,
585-
args.format.or(metadata.format),
581+
args.format,
586582
args.save_image_args.target_app_partition,
587583
flash_settings,
588584
args.save_image_args.min_chip_rev,
Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
use std::{ffi::OsStr, path::PathBuf, str::FromStr};
1+
use std::path::PathBuf;
22

33
use cargo::{
44
core::{Package, Workspace},
55
util::Config,
66
};
7-
use espflash::image_format::ImageFormatKind;
87
use miette::{IntoDiagnostic, Result};
98
use serde::Deserialize;
109

@@ -14,9 +13,6 @@ use crate::error::Error;
1413
pub struct PackageMetadata {
1514
pub workspace_root: PathBuf,
1615
pub package_root: PathBuf,
17-
pub bootloader: Option<PathBuf>,
18-
pub format: Option<ImageFormatKind>,
19-
pub partition_table: Option<PathBuf>,
2016
}
2117

2218
impl PackageMetadata {
@@ -37,19 +33,6 @@ impl PackageMetadata {
3733
let package = Self::load_package(&workspace, package_name)?;
3834
let metadata = Self::load_metadata(&workspace, &package)?;
3935

40-
if let Some(table) = &metadata.partition_table {
41-
match table.extension() {
42-
Some(ext) if ext == "bin" || ext == "csv" => {}
43-
_ => return Err(Error::InvalidPartitionTablePath.into()),
44-
}
45-
}
46-
47-
if let Some(bootloader) = &metadata.bootloader {
48-
if bootloader.extension() != Some(OsStr::new("bin")) {
49-
return Err(Error::InvalidBootloaderPath.into());
50-
}
51-
}
52-
5336
Ok(metadata)
5437
}
5538

@@ -72,35 +55,11 @@ impl PackageMetadata {
7255
}
7356

7457
fn load_metadata(workspace: &Workspace, package: &Package) -> Result<PackageMetadata> {
75-
let mut espflash_meta = PackageMetadata {
58+
let espflash_meta = PackageMetadata {
7659
workspace_root: workspace.root_manifest().parent().unwrap().to_path_buf(),
7760
package_root: package.root().to_path_buf(),
78-
79-
..PackageMetadata::default()
8061
};
8162

82-
match package.manifest().custom_metadata() {
83-
Some(meta) if meta.is_table() => match meta.as_table().unwrap().get("espflash") {
84-
Some(meta) if meta.is_table() => {
85-
let meta = meta.as_table().unwrap();
86-
87-
espflash_meta.bootloader = meta
88-
.get("bootloader")
89-
.map(|bl| package.root().join(bl.as_str().unwrap()));
90-
91-
espflash_meta.format = meta
92-
.get("format")
93-
.map(|fmt| ImageFormatKind::from_str(fmt.as_str().unwrap()).unwrap());
94-
95-
espflash_meta.partition_table = meta
96-
.get("partition_table")
97-
.map(|pt| package.root().join(pt.as_str().unwrap()));
98-
}
99-
_ => {}
100-
},
101-
_ => {}
102-
}
103-
10463
Ok(espflash_meta)
10564
}
10665
}

espflash/README.md

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Supports the **ESP32**, **ESP32-C2/C3/C6**, **ESP32-H2**, **ESP32-P4**,**ESP32-S
2020
- [Cargo Runner](#cargo-runner)
2121
- [Using `espflash` as a Library](#using-espflash-as-a-library)
2222
- [Configuration File](#configuration-file)
23-
- [Configuration Examples](#configuration-examples)
23+
- [Configuration precedence](#configuration-precedence)
2424
- [Logging Format](#logging-format)
2525
- [License](#license)
2626
- [Contribution](#contribution)
@@ -78,8 +78,10 @@ Commands:
7878
flash Flash an application in ELF format to a connected target device
7979
monitor Open the serial monitor without flashing the connected target device
8080
partition-table Convert partition tables between CSV and binary format
81+
read-flash Read SPI flash content
8182
save-image Generate a binary application image and save it to a local disk
8283
write-bin Write a binary file to a specific address in a target device's flash
84+
checksum-md5 Calculate the MD5 checksum of the given region
8385
help Print this message or the help of the given subcommand(s)
8486
8587
Options:
@@ -133,30 +135,44 @@ espflash = { version = "2.1", default-features = false, features = ["raspberry"]
133135

134136
## Configuration File
135137

136-
It's possible to specify a serial port and/or USB VID/PID values by setting them in a configuration file. The location of this file differs based on your operating system:
137-
138-
| Operating System | Configuration Path |
139-
| :--------------- | :---------------------------------------------------------------- |
140-
| Linux | `$HOME/.config/espflash/espflash.toml` |
141-
| macOS | `$HOME/Library/Application Support/rs.esp.espflash/espflash.toml` |
142-
| Windows | `%APPDATA%\esp\espflash\espflash.toml` |
143-
144-
### Configuration Examples
145-
146-
You can either configure the serial port name like so:
147-
148-
```
149-
[connection]
150-
serial = "/dev/ttyUSB0"
151-
```
152-
153-
Or specify one or more USB `vid`/`pid` couple:
154-
155-
```
156-
[[usb_device]]
157-
vid = "303a"
158-
pid = "1001"
159-
```
138+
The configuration file allows you to define various parameters for your application:
139+
- Serial port:
140+
- By name:
141+
```toml
142+
[connection]
143+
serial = "/dev/ttyUSB0"
144+
```
145+
- By USB VID/PID values:
146+
```toml
147+
[[usb_device]]
148+
vid = "303a"
149+
pid = "1001"
150+
```
151+
- Baudrate:
152+
```toml
153+
baudrate = 460800
154+
```
155+
- Bootloader:
156+
```toml
157+
bootloader = "path/to/custom/bootloader.bin"
158+
```
159+
- Partition table
160+
```toml
161+
partition_table = "path/to/custom/partition-table.bin"
162+
```
163+
164+
You can have a local and/or a global configuration file:
165+
- For local configurations, store the file under the current working directory with the name `espflash.toml`
166+
- Global file location differs based on your operating system:
167+
- Linux: `$HOME/.config/espflash/espflash.toml`
168+
- macOS: `$HOME/Library/Application Support/rs.esp.espflash/espflash.toml`
169+
- Windows: `%APPDATA%\esp\espflash\espflash.toml`
170+
171+
### Configuration precedence
172+
173+
1. Environment variables: If `ESPFLASH_PORT` or `ESPFLASH_BAUD` are set, the will be used instead of the config file value.
174+
2. Local configuration file
175+
3. Global configuration file
160176

161177
## Logging Format
162178

0 commit comments

Comments
 (0)