11use std:: { borrow:: Cow , io:: Write , iter:: once, mem:: size_of} ;
22
33use bytemuck:: { bytes_of, from_bytes} ;
4- use esp_idf_part:: { PartitionTable , Type } ;
4+ use esp_idf_part:: { Partition , PartitionTable , Type } ;
55use sha2:: { Digest , Sha256 } ;
66
77use crate :: {
@@ -35,6 +35,7 @@ impl<'a> IdfBootloaderFormat<'a> {
3535 chip : Chip ,
3636 params : Esp32Params ,
3737 partition_table : Option < PartitionTable > ,
38+ target_app_partition : Option < String > ,
3839 bootloader : Option < Vec < u8 > > ,
3940 flash_mode : Option < FlashMode > ,
4041 flash_size : Option < FlashSize > ,
@@ -144,17 +145,27 @@ impl<'a> IdfBootloaderFormat<'a> {
144145 let hash = hasher. finalize ( ) ;
145146 data. write_all ( & hash) ?;
146147
147- // The default partition table contains the "factory" partition, and if a user
148- // provides a partition table via command-line then the validation step confirms
149- // that at least one "app" partition is present. We prefer the "factory"
150- // partition, and use any available "app" partitions if not present.
151- let factory_partition = partition_table
152- . find ( "factory" )
153- . or_else ( || partition_table. find_by_type ( Type :: App ) )
154- . unwrap ( ) ;
148+ let target_app_partition: & Partition =
149+ // Use the target app partition if provided
150+ if let Some ( target_partition) = target_app_partition {
151+ partition_table
152+ . find ( & target_partition)
153+ . ok_or ( Error :: AppPartitionNotFound ) ?
154+ } else {
155+
156+ // The default partition table contains the "factory" partition, and if a user
157+ // provides a partition table via command-line then the validation step confirms
158+ // that at least one "app" partition is present. We prefer the "factory"
159+ // partition, and use any available "app" partitions if not present.
160+
161+ partition_table
162+ . find ( "factory" )
163+ . or_else ( || partition_table. find_by_type ( Type :: App ) )
164+ . ok_or ( Error :: AppPartitionNotFound ) ?
165+ } ;
155166
156167 let app_size = data. len ( ) as u32 ;
157- let part_size = factory_partition . size ( ) ;
168+ let part_size = target_app_partition . size ( ) ;
158169
159170 // The size of the application must not exceed the size of the factory
160171 // partition.
@@ -163,7 +174,7 @@ impl<'a> IdfBootloaderFormat<'a> {
163174 }
164175
165176 let flash_segment = RomSegment {
166- addr : factory_partition . offset ( ) ,
177+ addr : target_app_partition . offset ( ) ,
167178 data : Cow :: Owned ( data) ,
168179 } ;
169180
@@ -313,9 +324,18 @@ pub mod tests {
313324 let expected_bin = fs:: read ( "tests/resources/esp32_hal_blinky.bin" ) . unwrap ( ) ;
314325
315326 let image = ElfFirmwareImage :: try_from ( input_bytes. as_slice ( ) ) . unwrap ( ) ;
316- let flash_image =
317- IdfBootloaderFormat :: new ( & image, Chip :: Esp32 , PARAMS , None , None , None , None , None )
318- . unwrap ( ) ;
327+ let flash_image = IdfBootloaderFormat :: new (
328+ & image,
329+ Chip :: Esp32 ,
330+ PARAMS ,
331+ None ,
332+ None ,
333+ None ,
334+ None ,
335+ None ,
336+ None ,
337+ )
338+ . unwrap ( ) ;
319339
320340 let segments = flash_image. flash_segments ( ) . collect :: < Vec < _ > > ( ) ;
321341 assert_eq ! ( segments. len( ) , 3 ) ;
0 commit comments