@@ -115,6 +115,12 @@ pub enum DataType {
115
115
Spiffs = 0x82 ,
116
116
}
117
117
118
+ impl DataType {
119
+ fn is_multiple_allowed ( self ) -> bool {
120
+ matches ! ( self , Self :: Fat | Self :: Spiffs )
121
+ }
122
+ }
123
+
118
124
#[ derive( Debug , Deserialize , PartialEq , Copy , Clone ) ]
119
125
#[ allow( dead_code) ]
120
126
#[ serde( untagged) ]
@@ -141,6 +147,13 @@ impl SubType {
141
147
SubType :: Data ( ty) => * ty as u8 ,
142
148
}
143
149
}
150
+
151
+ fn is_multiple_allowed ( self ) -> bool {
152
+ match self {
153
+ SubType :: App ( _) => false ,
154
+ SubType :: Data ( ty) => ty. is_multiple_allowed ( ) ,
155
+ }
156
+ }
144
157
}
145
158
146
159
#[ derive( Debug ) ]
@@ -198,7 +211,7 @@ impl PartitionTable {
198
211
. from_reader ( data. trim ( ) . as_bytes ( ) ) ;
199
212
200
213
// Default offset is 0x8000 in esp-idf, partition table size is 0x1000
201
- let mut offset = 0x9000 ;
214
+ let mut offset = 0x9000 ;
202
215
let mut partitions = Vec :: with_capacity ( data. lines ( ) . count ( ) ) ;
203
216
for record in reader. records ( ) {
204
217
let record = record. map_err ( |e| CSVError :: new ( e, data. clone ( ) ) ) ?;
@@ -292,7 +305,9 @@ impl PartitionTable {
292
305
. into ( ) ) ;
293
306
}
294
307
295
- if partition1. sub_type == partition2. sub_type {
308
+ if partition1. sub_type == partition2. sub_type
309
+ && !SubType :: is_multiple_allowed ( partition1. sub_type )
310
+ {
296
311
return Err ( DuplicatePartitionsError :: new (
297
312
source, * line1, * line2, "sub-type" ,
298
313
)
@@ -550,20 +565,31 @@ ota_0, app, ota_0, 0x110000, 1M,
550
565
ota_1, app, ota_1, 0x210000, 1M,
551
566
" ;
552
567
553
- const PTABLE_2 : & str = "
568
+ const PTABLE_2 : & str = "
554
569
# ESP-IDF Partition Table
555
570
# Name, Type, SubType, Offset, Size, Flags
556
571
nvs, data, nvs, , 0x4000,
557
572
phy_init, data, phy, , 0x1000,
558
573
factory, app, factory, , 1M,
559
574
" ;
560
575
561
- const PTABLE_3 : & str = "
576
+ const PTABLE_3 : & str = "
562
577
# ESP-IDF Partition Table
563
578
# Name, Type, SubType, Offset, Size, Flags
564
579
nvs, data, nvs, 0x10000, 0x4000,
565
580
phy_init, data, phy, , 0x1000,
566
581
factory, app, factory, , 1M,
582
+ " ;
583
+
584
+ const PTABLE_SPIFFS : & str = "
585
+ # ESP-IDF Partition Table
586
+ # Name, Type, SubType, Offset, Size, Flags
587
+ nvs, data, nvs, 0x9000, 0x4000,
588
+ otadata, data, ota, 0xd000, 0x2000,
589
+ phy_init, data, phy, 0xf000, 0x1000,
590
+ factory, app, factory, 0x10000, 1M,
591
+ a, data, spiffs, 0x110000, 1M,
592
+ b, data, spiffs, 0x210000, 1M,
567
593
" ;
568
594
569
595
#[ test]
@@ -600,12 +626,16 @@ factory, app, factory, , 1M,
600
626
601
627
let pt1 = PartitionTable :: try_from_str ( PTABLE_1 ) ;
602
628
assert ! ( pt1. is_ok( ) ) ;
629
+
630
+ let pt_spiffs = PartitionTable :: try_from_str ( PTABLE_SPIFFS ) ;
631
+ assert ! ( pt_spiffs. is_ok( ) ) ;
603
632
}
604
633
605
634
#[ test]
606
635
fn blank_offsets_are_filled_in ( ) {
607
- let pt2 = PartitionTable :: try_from_str ( PTABLE_2 ) . expect ( "Failed to parse partition table with blank offsets" ) ;
608
-
636
+ let pt2 = PartitionTable :: try_from_str ( PTABLE_2 )
637
+ . expect ( "Failed to parse partition table with blank offsets" ) ;
638
+
609
639
assert_eq ! ( 3 , pt2. partitions. len( ) ) ;
610
640
assert_eq ! ( 0x4000 , pt2. partitions[ 0 ] . size) ;
611
641
assert_eq ! ( 0x1000 , pt2. partitions[ 1 ] . size) ;
@@ -618,8 +648,9 @@ factory, app, factory, , 1M,
618
648
619
649
#[ test]
620
650
fn first_offsets_are_respected ( ) {
621
- let pt3 = PartitionTable :: try_from_str ( PTABLE_3 ) . expect ( "Failed to parse partition table with blank offsets" ) ;
622
-
651
+ let pt3 = PartitionTable :: try_from_str ( PTABLE_3 )
652
+ . expect ( "Failed to parse partition table with blank offsets" ) ;
653
+
623
654
assert_eq ! ( 3 , pt3. partitions. len( ) ) ;
624
655
assert_eq ! ( 0x4000 , pt3. partitions[ 0 ] . size) ;
625
656
assert_eq ! ( 0x1000 , pt3. partitions[ 1 ] . size) ;
0 commit comments