Skip to content

Commit

Permalink
Add min_chip_rev argument (#525)
Browse files Browse the repository at this point in the history
* Verify the minimum supported chip revision when flashing

* Allow specifying a minimum chip revision when saving an image

* feat: Use value parser

* docs: Update chip revision docstring

* feat: Update default value of mon_chip_rev

---------

Co-authored-by: Jesse Braham <jesse@beta7.io>
  • Loading branch information
SergioGasquez and jessebraham committed Dec 21, 2023
1 parent 2665054 commit 77fd5b4
Show file tree
Hide file tree
Showing 16 changed files with 101 additions and 1 deletion.
3 changes: 3 additions & 0 deletions cargo-espflash/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ fn flash(args: FlashArgs, config: &Config) -> Result<()> {
let cargo_config = CargoConfig::load(&metadata.workspace_root, &metadata.package_root);

let mut flasher = connect(&args.connect_args, config)?;
flasher.verify_minimum_revision(args.flash_args.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.
Expand Down Expand Up @@ -329,6 +330,7 @@ fn flash(args: FlashArgs, config: &Config) -> Result<()> {
args.build_args.flash_config_args.flash_size,
args.build_args.flash_config_args.flash_freq,
args.flash_args.partition_table_offset,
args.flash_args.min_chip_rev,
)?;
}

Expand Down Expand Up @@ -556,6 +558,7 @@ fn save_image(args: SaveImageArgs) -> Result<()> {

save_elf_as_image(
args.save_image_args.chip,
args.save_image_args.min_chip_rev,
&elf_data,
args.save_image_args.file,
args.format.or(metadata.format),
Expand Down
3 changes: 3 additions & 0 deletions espflash/src/bin/espflash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ pub fn erase_parts(args: ErasePartsArgs, config: &Config) -> Result<()> {

fn flash(args: FlashArgs, config: &Config) -> Result<()> {
let mut flasher = connect(&args.connect_args, config)?;
flasher.verify_minimum_revision(args.flash_args.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.
Expand Down Expand Up @@ -253,6 +254,7 @@ fn flash(args: FlashArgs, config: &Config) -> Result<()> {
args.flash_config_args.flash_size,
args.flash_config_args.flash_freq,
args.flash_args.partition_table_offset,
args.flash_args.min_chip_rev,
)?;
}

Expand Down Expand Up @@ -301,6 +303,7 @@ fn save_image(args: SaveImageArgs) -> Result<()> {

save_elf_as_image(
args.save_image_args.chip,
args.save_image_args.min_chip_rev,
&elf_data,
args.save_image_args.file,
args.format,
Expand Down
41 changes: 41 additions & 0 deletions espflash/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ pub struct FlashArgs {
/// Logging format.
#[arg(long, short = 'L', default_value = "serial", requires = "monitor")]
pub log_format: LogFormat,
/// Minimum chip revision supported by image, in format: major.minor
#[arg(long, default_value = "0.0", value_parser = parse_chip_rev)]
pub min_chip_rev: u16,
/// Open a serial monitor after flashing
#[arg(short = 'M', long)]
pub monitor: bool,
Expand Down Expand Up @@ -193,6 +196,9 @@ pub struct SaveImageArgs {
pub chip: Chip,
/// File name to save the generated image to
pub file: PathBuf,
/// Minimum chip revision supported by image, in format: major.minor
#[arg(long, default_value = "0.0", value_parser = parse_chip_rev)]
pub min_chip_rev: u16,
/// Boolean flag to merge binaries into single binary
#[arg(long)]
pub merge: bool,
Expand Down Expand Up @@ -285,6 +291,36 @@ pub fn completions(args: &CompletionsArgs, app: &mut clap::Command, bin_name: &s
Ok(())
}

/// Parses chip revision from string to major * 100 + minor format
pub fn parse_chip_rev(chip_rev: &str) -> Result<u16> {
let mut split = chip_rev.split('.');

let parse_or_error = |value: Option<&str>| {
value
.ok_or_else(|| Error::ParseChipRevError {
chip_rev: chip_rev.to_string(),
})
.and_then(|v| {
v.parse::<u16>().map_err(|_| Error::ParseChipRevError {
chip_rev: chip_rev.to_string(),
})
})
.into_diagnostic()
};

let major = parse_or_error(split.next())?;
let minor = parse_or_error(split.next())?;

if split.next().is_some() {
return Err(Error::ParseChipRevError {
chip_rev: chip_rev.to_string(),
})
.into_diagnostic();
}

Ok(major * 100 + minor)
}

/// Print information about a chip
pub fn print_board_info(flasher: &mut Flasher) -> Result<()> {
let info = flasher.device_info()?;
Expand Down Expand Up @@ -342,6 +378,7 @@ pub fn serial_monitor(args: MonitorArgs, config: &Config) -> Result<()> {
/// Convert the provided firmware image from ELF to binary
pub fn save_elf_as_image(
chip: Chip,
min_rev_full: u16,
elf_data: &[u8],
image_path: PathBuf,
image_format: Option<ImageFormatKind>,
Expand Down Expand Up @@ -397,6 +434,7 @@ pub fn save_elf_as_image(
target_app_partition,
image_format,
None,
min_rev_full,
flash_mode,
flash_size,
flash_freq,
Expand Down Expand Up @@ -439,6 +477,7 @@ pub fn save_elf_as_image(
None,
image_format,
None,
min_rev_full,
flash_mode,
flash_size,
flash_freq,
Expand Down Expand Up @@ -557,6 +596,7 @@ pub fn flash_elf_image(
flash_size: Option<FlashSize>,
flash_freq: Option<FlashFrequency>,
partition_table_offset: Option<u32>,
min_rev_full: u16,
) -> Result<()> {
// If the '--bootloader' option is provided, load the binary file at the
// specified path.
Expand All @@ -581,6 +621,7 @@ pub fn flash_elf_image(
flash_size,
flash_freq,
partition_table_offset,
min_rev_full,
Some(&mut EspflashProgress::default()),
)?;
info!("Flashing has completed!");
Expand Down
15 changes: 15 additions & 0 deletions espflash/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,21 @@ pub enum Error {
frequency: FlashFrequency,
},

#[error(
"Minimum supported revision is {major}.{minor}, connected device's revision is {found_major}.{found_minor}"
)]
#[diagnostic(code(espflash::unsupported_chip_revision))]
UnsupportedChipRevision {
major: u16,
minor: u16,
found_major: u16,
found_minor: u16,
},

#[error("Failed to parse chip revision: {chip_rev}. Chip revision must be in the format `major.minor`")]
#[diagnostic(code(espflash::cli::parse_chip_rev_error))]
ParseChipRevError { chip_rev: String },

#[error("Error while connecting to device")]
#[diagnostic(transparent)]
Connection(#[source] ConnectionError),
Expand Down
19 changes: 19 additions & 0 deletions espflash/src/flasher/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,7 @@ impl Flasher {
flash_size: Option<FlashSize>,
flash_freq: Option<FlashFrequency>,
partition_table_offset: Option<u32>,
min_rev_full: u16,
mut progress: Option<&mut dyn ProgressCallbacks>,
) -> Result<(), Error> {
let image = ElfFirmwareImage::try_from(elf_data)?;
Expand All @@ -835,6 +836,7 @@ impl Flasher {
target_app_partition,
image_format,
chip_revision,
min_rev_full,
flash_mode,
flash_size.or(Some(self.flash_size)),
flash_freq,
Expand Down Expand Up @@ -897,6 +899,7 @@ impl Flasher {
flash_size: Option<FlashSize>,
flash_freq: Option<FlashFrequency>,
partition_table_offset: Option<u32>,
min_rev_full: u16,
progress: Option<&mut dyn ProgressCallbacks>,
) -> Result<(), Error> {
self.load_elf_to_flash_with_format(
Expand All @@ -909,6 +912,7 @@ impl Flasher {
flash_size,
flash_freq,
partition_table_offset,
min_rev_full,
progress,
)
}
Expand Down Expand Up @@ -976,6 +980,21 @@ impl Flasher {
Ok(())
}

pub fn verify_minimum_revision(&mut self, minimum: u16) -> Result<(), Error> {
let (major, minor) = self.chip.into_target().chip_revision(self.connection())?;
let revision = (major * 100 + minor) as u16;
if revision < minimum {
return Err(Error::UnsupportedChipRevision {
major: minimum / 100,
minor: minimum % 100,
found_major: revision / 100,
found_minor: revision % 100,
});
}

Ok(())
}

pub fn into_interface(self) -> Interface {
self.connection.into_interface()
}
Expand Down
3 changes: 3 additions & 0 deletions espflash/src/image_format/idf_bootloader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ impl<'a> IdfBootloaderFormat<'a> {
pub fn new(
image: &'a dyn FirmwareImage<'a>,
chip: Chip,
min_rev_full: u16,
params: Esp32Params,
partition_table: Option<PartitionTable>,
target_app_partition: Option<String>,
Expand Down Expand Up @@ -80,6 +81,7 @@ impl<'a> IdfBootloaderFormat<'a> {

header.wp_pin = WP_PIN_DISABLED;
header.chip_id = params.chip_id;
header.min_chip_rev_full = min_rev_full;
header.append_digest = 1;

let mut data = bytes_of(&header).to_vec();
Expand Down Expand Up @@ -364,6 +366,7 @@ pub mod tests {
let flash_image = IdfBootloaderFormat::new(
&image,
Chip::Esp32,
0,
PARAMS,
None,
None,
Expand Down
2 changes: 1 addition & 1 deletion espflash/src/image_format/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ struct ImageHeader {
gd_wp_drv: u8,
chip_id: u16,
min_rev: u8,
/// Minimal chip revision supported by image, in format: major * 100 + minor
/// Minimum chip revision supported by image, in format: major * 100 + minor
min_chip_rev_full: u16,
/// Maximal chip revision supported by image, in format: major * 100 + minor
max_chip_rev_full: u16,
Expand Down
2 changes: 2 additions & 0 deletions espflash/src/targets/esp32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ impl Target for Esp32 {
target_app_partition: Option<String>,
image_format: Option<ImageFormatKind>,
_chip_revision: Option<(u32, u32)>,
min_rev_full: u16,
flash_mode: Option<FlashMode>,
flash_size: Option<FlashSize>,
flash_freq: Option<FlashFrequency>,
Expand All @@ -169,6 +170,7 @@ impl Target for Esp32 {
ImageFormatKind::EspBootloader => Ok(Box::new(IdfBootloaderFormat::new(
image,
Chip::Esp32,
min_rev_full,
PARAMS,
partition_table,
target_app_partition,
Expand Down
2 changes: 2 additions & 0 deletions espflash/src/targets/esp32c2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ impl Target for Esp32c2 {
target_app_partition: Option<String>,
image_format: Option<ImageFormatKind>,
_chip_revision: Option<(u32, u32)>,
min_rev_full: u16,
flash_mode: Option<FlashMode>,
flash_size: Option<FlashSize>,
flash_freq: Option<FlashFrequency>,
Expand All @@ -103,6 +104,7 @@ impl Target for Esp32c2 {
ImageFormatKind::EspBootloader => Ok(Box::new(IdfBootloaderFormat::new(
image,
Chip::Esp32c2,
min_rev_full,
PARAMS,
partition_table,
target_app_partition,
Expand Down
2 changes: 2 additions & 0 deletions espflash/src/targets/esp32c3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ impl Target for Esp32c3 {
target_app_partition: Option<String>,
image_format: Option<ImageFormatKind>,
chip_revision: Option<(u32, u32)>,
min_rev_full: u16,
flash_mode: Option<FlashMode>,
flash_size: Option<FlashSize>,
flash_freq: Option<FlashFrequency>,
Expand All @@ -90,6 +91,7 @@ impl Target for Esp32c3 {
(ImageFormatKind::EspBootloader, _) => Ok(Box::new(IdfBootloaderFormat::new(
image,
Chip::Esp32c3,
min_rev_full,
PARAMS,
partition_table,
target_app_partition,
Expand Down
2 changes: 2 additions & 0 deletions espflash/src/targets/esp32c6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ impl Target for Esp32c6 {
target_app_partition: Option<String>,
image_format: Option<ImageFormatKind>,
_chip_revision: Option<(u32, u32)>,
min_rev_full: u16,
flash_mode: Option<FlashMode>,
flash_size: Option<FlashSize>,
flash_freq: Option<FlashFrequency>,
Expand All @@ -87,6 +88,7 @@ impl Target for Esp32c6 {
ImageFormatKind::EspBootloader => Ok(Box::new(IdfBootloaderFormat::new(
image,
Chip::Esp32c6,
min_rev_full,
PARAMS,
partition_table,
target_app_partition,
Expand Down
2 changes: 2 additions & 0 deletions espflash/src/targets/esp32h2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ impl Target for Esp32h2 {
target_app_partition: Option<String>,
image_format: Option<ImageFormatKind>,
_chip_revision: Option<(u32, u32)>,
min_rev_full: u16,
flash_mode: Option<FlashMode>,
flash_size: Option<FlashSize>,
flash_freq: Option<FlashFrequency>,
Expand All @@ -95,6 +96,7 @@ impl Target for Esp32h2 {
ImageFormatKind::EspBootloader => Ok(Box::new(IdfBootloaderFormat::new(
image,
Chip::Esp32h2,
min_rev_full,
PARAMS,
partition_table,
target_app_partition,
Expand Down
2 changes: 2 additions & 0 deletions espflash/src/targets/esp32s2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ impl Target for Esp32s2 {
target_app_partition: Option<String>,
image_format: Option<ImageFormatKind>,
_chip_revision: Option<(u32, u32)>,
min_rev_full: u16,
flash_mode: Option<FlashMode>,
flash_size: Option<FlashSize>,
flash_freq: Option<FlashFrequency>,
Expand All @@ -155,6 +156,7 @@ impl Target for Esp32s2 {
ImageFormatKind::EspBootloader => Ok(Box::new(IdfBootloaderFormat::new(
image,
Chip::Esp32s2,
min_rev_full,
PARAMS,
partition_table,
target_app_partition,
Expand Down
2 changes: 2 additions & 0 deletions espflash/src/targets/esp32s3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ impl Target for Esp32s3 {
target_app_partition: Option<String>,
image_format: Option<ImageFormatKind>,
_chip_revision: Option<(u32, u32)>,
min_rev_full: u16,
flash_mode: Option<FlashMode>,
flash_size: Option<FlashSize>,
flash_freq: Option<FlashFrequency>,
Expand All @@ -109,6 +110,7 @@ impl Target for Esp32s3 {
ImageFormatKind::EspBootloader => Ok(Box::new(IdfBootloaderFormat::new(
image,
Chip::Esp32s3,
min_rev_full,
PARAMS,
partition_table,
target_app_partition,
Expand Down
1 change: 1 addition & 0 deletions espflash/src/targets/esp8266.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ impl Target for Esp8266 {
_target_app_partition: Option<String>,
image_format: Option<ImageFormatKind>,
_chip_revision: Option<(u32, u32)>,
_min_rev_full: u16,
flash_mode: Option<FlashMode>,
flash_size: Option<FlashSize>,
flash_freq: Option<FlashFrequency>,
Expand Down
1 change: 1 addition & 0 deletions espflash/src/targets/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ pub trait Target: ReadEFuse {
target_app_partition: Option<String>,
image_format: Option<ImageFormatKind>,
chip_revision: Option<(u32, u32)>,
min_rev_full: u16,
flash_mode: Option<FlashMode>,
flash_size: Option<FlashSize>,
flash_freq: Option<FlashFrequency>,
Expand Down

0 comments on commit 77fd5b4

Please sign in to comment.