@@ -140,34 +140,45 @@ async fn push_inner<S: NorFlash>(
140
140
if next_address. is_none ( ) {
141
141
// No cap left on this page, move to the next page
142
142
let next_page = next_page :: < S > ( flash_range. clone ( ) , current_page) ;
143
- match get_page_state ( flash, flash_range. clone ( ) , cache, next_page) . await ? {
144
- PageState :: Open => {
143
+ let next_page_state = get_page_state ( flash, flash_range. clone ( ) , cache, next_page) . await ?;
144
+ let single_page = next_page == current_page;
145
+
146
+ match ( next_page_state, single_page) {
147
+ ( PageState :: Open , _) => {
145
148
close_page ( flash, flash_range. clone ( ) , cache, current_page) . await ?;
146
149
partial_close_page ( flash, flash_range. clone ( ) , cache, next_page) . await ?;
147
150
next_address = Some (
148
151
calculate_page_address :: < S > ( flash_range. clone ( ) , next_page)
149
152
+ S :: WORD_SIZE as u32 ,
150
153
) ;
151
154
}
152
- state @ PageState :: Closed => {
155
+ ( PageState :: Closed , _ ) | ( PageState :: PartialOpen , true ) => {
153
156
let next_page_data_start_address =
154
157
calculate_page_address :: < S > ( flash_range. clone ( ) , next_page)
155
158
+ S :: WORD_SIZE as u32 ;
156
159
157
160
if !allow_overwrite_old_data
158
- && !is_page_empty ( flash, flash_range. clone ( ) , cache, next_page, Some ( state) )
159
- . await ?
161
+ && !is_page_empty (
162
+ flash,
163
+ flash_range. clone ( ) ,
164
+ cache,
165
+ next_page,
166
+ Some ( next_page_state) ,
167
+ )
168
+ . await ?
160
169
{
161
170
cache. unmark_dirty ( ) ;
162
171
return Err ( Error :: FullStorage ) ;
163
172
}
164
173
165
174
open_page ( flash, flash_range. clone ( ) , cache, next_page) . await ?;
166
- close_page ( flash, flash_range. clone ( ) , cache, current_page) . await ?;
175
+ if !single_page {
176
+ close_page ( flash, flash_range. clone ( ) , cache, current_page) . await ?;
177
+ }
167
178
partial_close_page ( flash, flash_range. clone ( ) , cache, next_page) . await ?;
168
179
next_address = Some ( next_page_data_start_address) ;
169
180
}
170
- PageState :: PartialOpen => {
181
+ ( PageState :: PartialOpen , false ) => {
171
182
// This should never happen
172
183
return Err ( Error :: Corrupted {
173
184
#[ cfg( feature = "_test" ) ]
@@ -1525,4 +1536,29 @@ mod tests {
1525
1536
Err ( Error :: ItemTooBig )
1526
1537
) ;
1527
1538
}
1539
+
1540
+ #[ test]
1541
+ async fn push_on_single_page ( ) {
1542
+ let mut flash =
1543
+ mock_flash:: MockFlashBase :: < 1 , 4 , 256 > :: new ( WriteCountCheck :: Twice , None , true ) ;
1544
+ const FLASH_RANGE : Range < u32 > = 0x000 ..0x400 ;
1545
+
1546
+ for _ in 0 ..100 {
1547
+ match push (
1548
+ & mut flash,
1549
+ FLASH_RANGE ,
1550
+ & mut cache:: NoCache :: new ( ) ,
1551
+ & [ 0 , 1 , 2 , 3 , 4 ] ,
1552
+ true ,
1553
+ )
1554
+ . await
1555
+ {
1556
+ Ok ( _) => { }
1557
+ Err ( e) => {
1558
+ println ! ( "{}" , flash. print_items( ) . await ) ;
1559
+ panic ! ( "{e}" ) ;
1560
+ }
1561
+ }
1562
+ }
1563
+ }
1528
1564
}
0 commit comments