Skip to content

Commit

Permalink
Support loading flash settings from the config file (#627)
Browse files Browse the repository at this point in the history
* Support storing flash settings in the config file

Allow loading the flash frequency, size, and mode from the config file.

* Apply serde renames to the flash frequencies and sizes

Rename the FlashFrequency, FlashMode, and FlashSize enum variants to
more user-friendly names.

Note that will break attempting to deserialize these values that were
serialized by old versions of the code.  However, I did not see anywhere
currently using serialization for this field.  The serialization support
was added in #528, for probe-rs/probe-rs#1952,
but as best I can tell it doesn't look like this functionality ended up
being used in the probe-rs code.

* Document the `[flash]` config section in the crate README.md files
  • Loading branch information
simpkins committed May 3, 2024
1 parent 15991b5 commit 41eb732
Show file tree
Hide file tree
Showing 8 changed files with 164 additions and 177 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Added
- Support loading flash size, frequency, and mode from the config file (#627)

### Fixed
- Fixed help text for size parameter of read-flash subcommand
Expand Down
7 changes: 7 additions & 0 deletions cargo-espflash/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,13 @@ The configuration file allows you to define various parameters for your applicat
```toml
partition_table = "path/to/custom/partition-table.bin"
```
- Flash settings
```toml
[flash]
mode = "qio"
size = "8MB"
frequency = "80MHz"
```

You can have a local and/or a global configuration file:

Expand Down
97 changes: 21 additions & 76 deletions cargo-espflash/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ use clap::{Args, CommandFactory, Parser, Subcommand};
use espflash::{
cli::{
self, board_info, checksum_md5, completions, config::Config, connect, erase_flash,
erase_partitions, erase_region, flash_elf_image, monitor::monitor, partition_table,
print_board_info, read_flash, save_elf_as_image, serial_monitor, ChecksumMd5Args,
CompletionsArgs, ConnectArgs, EraseFlashArgs, EraseRegionArgs, EspflashProgress,
FlashConfigArgs, MonitorArgs, PartitionTableArgs, ReadFlashArgs,
erase_partitions, erase_region, flash_elf_image, make_flash_data, monitor::monitor,
partition_table, print_board_info, read_flash, save_elf_as_image, serial_monitor,
ChecksumMd5Args, CompletionsArgs, ConnectArgs, EraseFlashArgs, EraseRegionArgs,
EspflashProgress, FlashConfigArgs, MonitorArgs, PartitionTableArgs, ReadFlashArgs,
},
error::Error as EspflashError,
flasher::{parse_partition_table, FlashData, FlashSettings},
flasher::parse_partition_table,
logging::initialize_logger,
targets::{Chip, XtalFrequency},
update::check_for_update,
Expand Down Expand Up @@ -267,12 +267,14 @@ fn flash(args: FlashArgs, config: &Config) -> Result<()> {
args.flash_args.no_verify,
args.flash_args.no_skip,
)?;
flasher.verify_minimum_revision(args.flash_args.min_chip_rev)?;
flasher.verify_minimum_revision(args.flash_args.image.min_chip_rev)?;

// If the user has provided a flash size via a command-line argument, we'll
// If the user has provided a flash size via a command-line argument or config, we'll
// override the detected (or default) value with this.
if let Some(flash_size) = args.build_args.flash_config_args.flash_size {
flasher.set_flash_size(flash_size);
} else if let Some(flash_size) = config.flash.size {
flasher.set_flash_size(flash_size);
}

let chip = flasher.chip();
Expand All @@ -292,40 +294,12 @@ fn flash(args: FlashArgs, config: &Config) -> Result<()> {
if args.flash_args.ram {
flasher.load_elf_to_ram(&elf_data, Some(&mut EspflashProgress::default()))?;
} else {
let bootloader = args
.flash_args
.bootloader
.as_deref()
.or(config.bootloader.as_deref())
.or(build_ctx.bootloader_path.as_deref());

let partition_table = args
.flash_args
.partition_table
.as_deref()
.or(config.partition_table.as_deref())
.or(build_ctx.partition_table_path.as_deref());

if let Some(path) = &bootloader {
println!("Bootloader: {}", path.display());
}
if let Some(path) = &partition_table {
println!("Partition table: {}", path.display());
}

let flash_settings = FlashSettings::new(
args.build_args.flash_config_args.flash_mode,
args.build_args.flash_config_args.flash_size,
args.build_args.flash_config_args.flash_freq,
);

let flash_data = FlashData::new(
bootloader,
partition_table,
args.flash_args.partition_table_offset,
args.flash_args.target_app_partition,
flash_settings,
args.flash_args.min_chip_rev,
let flash_data = make_flash_data(
args.flash_args.image,
&args.build_args.flash_config_args,
config,
build_ctx.bootloader_path.as_deref(),
build_ctx.partition_table_path.as_deref(),
)?;

if args.flash_args.erase_parts.is_some() || args.flash_args.erase_data_parts.is_some() {
Expand Down Expand Up @@ -532,47 +506,18 @@ fn save_image(args: SaveImageArgs, config: &Config) -> Result<()> {
let build_ctx = build(&args.build_args, &cargo_config, args.save_image_args.chip)?;
let elf_data = fs::read(build_ctx.artifact_path).into_diagnostic()?;

let bootloader = args
.save_image_args
.bootloader
.as_deref()
.or(config.bootloader.as_deref())
.or(build_ctx.bootloader_path.as_deref())
.map(|p| p.to_path_buf());

let partition_table = args
.save_image_args
.partition_table
.as_deref()
.or(config.partition_table.as_deref())
.or(build_ctx.partition_table_path.as_deref())
.map(|p| p.to_path_buf());

// Since we have no `Flasher` instance and as such cannot print the board
// information, we will print whatever information we _do_ have.
println!("Chip type: {}", args.save_image_args.chip);
println!("Merge: {}", args.save_image_args.merge);
println!("Skip padding: {}", args.save_image_args.skip_padding);
if let Some(path) = &args.save_image_args.bootloader {
println!("Bootloader: {}", path.display());
}
if let Some(path) = &args.save_image_args.partition_table {
println!("Partition table: {}", path.display());
}

let flash_settings = FlashSettings::new(
args.build_args.flash_config_args.flash_mode,
args.build_args.flash_config_args.flash_size,
args.build_args.flash_config_args.flash_freq,
);

let flash_data = FlashData::new(
bootloader.as_deref(),
partition_table.as_deref(),
args.save_image_args.partition_table_offset,
args.save_image_args.target_app_partition,
flash_settings,
args.save_image_args.min_chip_rev,
let flash_data = make_flash_data(
args.save_image_args.image,
&args.build_args.flash_config_args,
config,
build_ctx.bootloader_path.as_deref(),
build_ctx.partition_table_path.as_deref(),
)?;

let xtal_freq = args
Expand Down
7 changes: 7 additions & 0 deletions espflash/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,13 @@ The configuration file allows you to define various parameters for your applicat
```toml
partition_table = "path/to/custom/partition-table.bin"
```
- Flash settings
```toml
[flash]
mode = "qio"
size = "8MB"
frequency = "80MHz"
```

You can have a local and/or a global configuration file:

Expand Down
90 changes: 22 additions & 68 deletions espflash/src/bin/espflash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ use clap::{Args, CommandFactory, Parser, Subcommand};
use espflash::{
cli::{
self, board_info, checksum_md5, completions, config::Config, connect, erase_flash,
erase_partitions, erase_region, flash_elf_image, monitor::monitor, parse_uint32,
partition_table, print_board_info, read_flash, save_elf_as_image, serial_monitor,
ChecksumMd5Args, CompletionsArgs, ConnectArgs, EraseFlashArgs, EraseRegionArgs,
EspflashProgress, FlashConfigArgs, MonitorArgs, PartitionTableArgs, ReadFlashArgs,
erase_partitions, erase_region, flash_elf_image, make_flash_data, monitor::monitor,
parse_uint32, partition_table, print_board_info, read_flash, save_elf_as_image,
serial_monitor, ChecksumMd5Args, CompletionsArgs, ConnectArgs, EraseFlashArgs,
EraseRegionArgs, EspflashProgress, FlashConfigArgs, MonitorArgs, PartitionTableArgs,
ReadFlashArgs,
},
error::Error,
flasher::{parse_partition_table, FlashData, FlashSettings},
flasher::parse_partition_table,
logging::initialize_logger,
targets::{Chip, XtalFrequency},
update::check_for_update,
Expand Down Expand Up @@ -161,7 +162,7 @@ fn main() -> Result<()> {
// displayed.
check_for_update(env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));

// Load any user configuraiton, if present.
// Load any user configuration, if present.
let config = Config::load()?;

// Execute the correct action based on the provided subcommand and its
Expand Down Expand Up @@ -212,12 +213,14 @@ fn flash(args: FlashArgs, config: &Config) -> Result<()> {
args.flash_args.no_verify,
args.flash_args.no_skip,
)?;
flasher.verify_minimum_revision(args.flash_args.min_chip_rev)?;
flasher.verify_minimum_revision(args.flash_args.image.min_chip_rev)?;

// If the user has provided a flash size via a command-line argument, we'll
// override the detected (or default) value with this.
if let Some(flash_size) = args.flash_config_args.flash_size {
flasher.set_flash_size(flash_size);
} else if let Some(flash_size) = config.flash.size {
flasher.set_flash_size(flash_size);
}

print_board_info(&mut flasher)?;
Expand All @@ -232,37 +235,12 @@ fn flash(args: FlashArgs, config: &Config) -> Result<()> {
if args.flash_args.ram {
flasher.load_elf_to_ram(&elf_data, Some(&mut EspflashProgress::default()))?;
} else {
let bootloader = args
.flash_args
.bootloader
.as_deref()
.or(config.bootloader.as_deref());
let partition_table = args
.flash_args
.partition_table
.as_deref()
.or(config.partition_table.as_deref());

if let Some(path) = bootloader {
println!("Bootloader: {}", path.display());
}
if let Some(path) = partition_table {
println!("Partition table: {}", path.display());
}

let flash_settings = FlashSettings::new(
args.flash_config_args.flash_mode,
args.flash_config_args.flash_size,
args.flash_config_args.flash_freq,
);

let flash_data = FlashData::new(
bootloader,
partition_table,
args.flash_args.partition_table_offset,
args.flash_args.target_app_partition,
flash_settings,
args.flash_args.min_chip_rev,
let flash_data = make_flash_data(
args.flash_args.image,
&args.flash_config_args,
config,
None,
None,
)?;

if args.flash_args.erase_parts.is_some() || args.flash_args.erase_data_parts.is_some() {
Expand Down Expand Up @@ -306,42 +284,18 @@ fn save_image(args: SaveImageArgs, config: &Config) -> Result<()> {
.into_diagnostic()
.wrap_err_with(|| format!("Failed to open image {}", args.image.display()))?;

let bootloader = args
.save_image_args
.bootloader
.as_deref()
.or(config.bootloader.as_deref());
let partition_table = args
.save_image_args
.partition_table
.as_deref()
.or(config.partition_table.as_deref());

// Since we have no `Flasher` instance and as such cannot print the board
// information, we will print whatever information we _do_ have.
println!("Chip type: {}", args.save_image_args.chip);
println!("Merge: {}", args.save_image_args.merge);
println!("Skip padding: {}", args.save_image_args.skip_padding);
if let Some(path) = &bootloader {
println!("Bootloader: {}", path.display());
}
if let Some(path) = &partition_table {
println!("Partition table: {}", path.display());
}

let flash_settings = FlashSettings::new(
args.flash_config_args.flash_mode,
args.flash_config_args.flash_size,
args.flash_config_args.flash_freq,
);

let flash_data = FlashData::new(
bootloader,
partition_table,
args.save_image_args.partition_table_offset,
args.save_image_args.target_app_partition,
flash_settings,
args.save_image_args.min_chip_rev,
let flash_data = make_flash_data(
args.save_image_args.image,
&args.flash_config_args,
config,
None,
None,
)?;

let xtal_freq = args
Expand Down
4 changes: 4 additions & 0 deletions espflash/src/cli/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use serde::{Deserialize, Serialize};
use serialport::UsbPortInfo;

use crate::error::Error;
use crate::flasher::FlashSettings;

/// A configured, known serial connection
#[derive(Debug, Deserialize, Serialize, Default, Clone)]
Expand Down Expand Up @@ -89,6 +90,9 @@ pub struct Config {
/// Preferred USB devices
#[serde(default)]
pub usb_device: Vec<UsbDevice>,
/// Flash settings
#[serde(default)]
pub flash: FlashSettings,
/// Path of the file to save the configuration to
#[serde(skip)]
save_path: PathBuf,
Expand Down

0 comments on commit 41eb732

Please sign in to comment.