@@ -13,9 +13,9 @@ use std::{
13
13
path:: { Path , PathBuf } ,
14
14
} ;
15
15
16
- use clap:: Args ;
16
+ use clap:: { builder :: ArgPredicate , Args } ;
17
17
use comfy_table:: { modifiers, presets:: UTF8_FULL , Attribute , Cell , Color , Table } ;
18
- use esp_idf_part:: { DataType , PartitionTable , SubType , Type } ;
18
+ use esp_idf_part:: { DataType , Partition , PartitionTable } ;
19
19
use log:: { debug, info} ;
20
20
use miette:: { IntoDiagnostic , Result , WrapErr } ;
21
21
use serialport:: { SerialPortType , UsbPortInfo } ;
@@ -24,7 +24,6 @@ use strum::VariantNames;
24
24
use self :: { config:: Config , monitor:: monitor, serial:: get_serial_port_info} ;
25
25
use crate :: {
26
26
elf:: ElfFirmwareImage ,
27
- error:: { MissingPartitionTable , NoOtadataError } ,
28
27
flasher:: { FlashFrequency , FlashMode , FlashSize , Flasher } ,
29
28
image_format:: ImageFormatKind ,
30
29
interface:: Interface ,
@@ -74,7 +73,7 @@ pub struct ConnectArgs {
74
73
#[ cfg_attr( feature = "raspberry" , clap( long) ) ]
75
74
pub rts : Option < u8 > ,
76
75
/// Use RAM stub for loading
77
- #[ arg( long) ]
76
+ #[ arg( long, default_value_ifs ( [ ( "erase_parts" , ArgPredicate :: IsPresent , Some ( "true" ) ) , ( "erase_data_parts" , ArgPredicate :: IsPresent , Some ( "true" ) ) ] ) ) ]
78
77
pub use_stub : bool ,
79
78
}
80
79
@@ -99,11 +98,17 @@ pub struct FlashArgs {
99
98
/// Path to a binary (.bin) bootloader file
100
99
#[ arg( long, value_name = "FILE" ) ]
101
100
pub bootloader : Option < PathBuf > ,
102
- /// Erase the OTA data partition
103
- /// This is useful when using multiple OTA partitions and still wanting to
104
- /// be able to reflash via cargo-espflash or espflash
105
- #[ arg( long) ]
106
- pub erase_otadata : bool ,
101
+ /// Erase partitions by label
102
+ #[ arg(
103
+ long,
104
+ requires = "partition_table" ,
105
+ value_name = "LABELS" ,
106
+ value_delimiter = ','
107
+ ) ]
108
+ pub erase_parts : Option < Vec < String > > ,
109
+ /// Erase specified data partitions
110
+ #[ arg( long, requires = "partition_table" , value_name = "PARTS" , value_parser = clap_enum_variants!( DataType ) , value_delimiter = ',' ) ]
111
+ pub erase_data_parts : Option < Vec < DataType > > ,
107
112
/// Image format to flash
108
113
#[ arg( long, value_parser = clap_enum_variants!( ImageFormatKind ) ) ]
109
114
pub format : Option < ImageFormatKind > ,
@@ -339,12 +344,11 @@ pub fn flash_elf_image(
339
344
flasher : & mut Flasher ,
340
345
elf_data : & [ u8 ] ,
341
346
bootloader : Option < & Path > ,
342
- partition_table : Option < & Path > ,
347
+ partition_table : Option < PartitionTable > ,
343
348
image_format : Option < ImageFormatKind > ,
344
349
flash_mode : Option < FlashMode > ,
345
350
flash_size : Option < FlashSize > ,
346
351
flash_freq : Option < FlashFrequency > ,
347
- erase_otadata : bool ,
348
352
) -> Result < ( ) > {
349
353
// If the '--bootloader' option is provided, load the binary file at the
350
354
// specified path.
@@ -357,39 +361,6 @@ pub fn flash_elf_image(
357
361
None
358
362
} ;
359
363
360
- // If the '--partition-table' option is provided, load the partition table from
361
- // the CSV or binary file at the specified path.
362
- let partition_table = if let Some ( path) = partition_table {
363
- let path = fs:: canonicalize ( path) . into_diagnostic ( ) ?;
364
-
365
- let data = fs:: read ( path)
366
- . into_diagnostic ( )
367
- . wrap_err ( "Failed to open partition table" ) ?;
368
- let table = PartitionTable :: try_from ( data) . into_diagnostic ( ) ?;
369
-
370
- Some ( table)
371
- } else {
372
- None
373
- } ;
374
-
375
- if erase_otadata {
376
- let partition_table = match & partition_table {
377
- Some ( partition_table) => partition_table,
378
- None => return Err ( ( MissingPartitionTable { } ) . into ( ) ) ,
379
- } ;
380
-
381
- let otadata =
382
- match partition_table. find_by_subtype ( Type :: Data , SubType :: Data ( DataType :: Ota ) ) {
383
- Some ( otadata) => otadata,
384
- None => return Err ( ( NoOtadataError { } ) . into ( ) ) ,
385
- } ;
386
-
387
- let offset = otadata. offset ( ) ;
388
- let size = otadata. size ( ) ;
389
-
390
- flasher. erase_region ( offset, size) ?;
391
- }
392
-
393
364
// Load the ELF data, optionally using the provider bootloader/partition
394
365
// table/image format, to the device's flash memory.
395
366
flasher. load_elf_to_flash_with_format (
@@ -406,11 +377,24 @@ pub fn flash_elf_image(
406
377
Ok ( ( ) )
407
378
}
408
379
380
+ pub fn parse_partition_table ( path : & Path ) -> Result < PartitionTable > {
381
+ let data = fs:: read ( path)
382
+ . into_diagnostic ( )
383
+ . wrap_err ( "Failed to open partition table" ) ?;
384
+ PartitionTable :: try_from ( data) . into_diagnostic ( )
385
+ }
386
+
387
+ pub fn erase_partition ( flasher : & mut Flasher , part : & Partition ) -> Result < ( ) > {
388
+ log:: info!( "Erasing {} ({:?})..." , part. name( ) , part. subtype( ) ) ;
389
+ let offset = part. offset ( ) ;
390
+ let size = part. size ( ) ;
391
+ flasher. erase_region ( offset, size) . into_diagnostic ( )
392
+ }
393
+
409
394
/// Convert and display CSV and binary partition tables
410
395
pub fn partition_table ( args : PartitionTableArgs ) -> Result < ( ) > {
411
396
if args. to_binary {
412
- let input = fs:: read_to_string ( & args. partition_table ) . into_diagnostic ( ) ?;
413
- let table = PartitionTable :: try_from_str ( input) . into_diagnostic ( ) ?;
397
+ let table = parse_partition_table ( & args. partition_table ) ?;
414
398
415
399
// Use either stdout or a file if provided for the output.
416
400
let mut writer: Box < dyn Write > = if let Some ( output) = args. output {
0 commit comments