@@ -188,7 +188,119 @@ pub fn reshuffle_apps(
188188 // addresses can be used. Otherwise, the algorithm will just look for the next
189189 // available address, leaving a lot of space in the front. This can happen
190190 // after uninstalling a rust app
191+
192+ for app in & rust_apps {
193+ print ! ( "rust app address(es): " ) ;
194+ for address in & app. compatible_addresses {
195+ if address. is_some ( ) {
196+ print ! ( "[{:#x}, {:#x}]" , address. unwrap( ) . 0 , address. unwrap( ) . 1 ) ;
197+ }
198+ }
199+ println ! ( ) ;
200+ }
201+
191202 rust_apps. sort_by_key ( |app| app. compatible_addresses [ 0 ] . unwrap ( ) . 0 ) ;
203+
204+ let mut initial_configuration: Vec < Index > = Vec :: new ( ) ;
205+ let mut new_rust_app: Option < & FixedApp > = None ;
206+ for app in & rust_apps {
207+ if app. installed {
208+ initial_configuration. push ( app. as_index (
209+ Some ( app. compatible_addresses [ 0 ] . unwrap ( ) . 1 ) ,
210+ app. compatible_addresses [ 0 ] . unwrap ( ) . 0 ,
211+ ) ) ;
212+ } else {
213+ new_rust_app = Some ( app) ;
214+ }
215+ }
216+
217+ log:: info!( "first intial configuration: " ) ;
218+ for app in & initial_configuration {
219+ log:: info!(
220+ "app idx {}, addr {:#x}, size {}" ,
221+ app. idx. unwrap( ) ,
222+ app. address,
223+ app. size
224+ ) ;
225+ }
226+
227+ if let Some ( new_app) = new_rust_app {
228+ let mut found: bool = false ;
229+ for candidate in new_app. compatible_addresses . iter ( ) . flatten ( ) {
230+ let ( flash_addr, ram_addr) = * candidate;
231+ let new_start = flash_addr;
232+ let new_end = flash_addr + new_app. size ;
233+ log:: info!(
234+ "checking for new_start {:#x}, new_end {:#x}" ,
235+ new_start,
236+ new_end
237+ ) ;
238+
239+ // Check before first element
240+ if initial_configuration. is_empty ( ) {
241+ initial_configuration. push ( new_app. as_index ( Some ( ram_addr) , flash_addr) ) ;
242+ found = true ;
243+ break ;
244+ }
245+
246+ // Check gap before first installed app
247+ let first = & initial_configuration[ 0 ] ;
248+ if new_end <= first. address {
249+ initial_configuration. insert ( 0 , new_app. as_index ( Some ( ram_addr) , flash_addr) ) ;
250+ found = true ;
251+ break ;
252+ }
253+
254+ // Check gaps between apps
255+ for i in 0 ..initial_configuration. len ( ) - 1 {
256+ let current = & initial_configuration[ i] ;
257+ let next = & initial_configuration[ i + 1 ] ;
258+
259+ let gap_start = current. address + current. size ;
260+ let gap_end = next. address ;
261+
262+ if new_start >= gap_start && new_end <= gap_end {
263+ initial_configuration
264+ . insert ( i + 1 , new_app. as_index ( Some ( ram_addr) , flash_addr) ) ;
265+ found = true ;
266+ break ;
267+ }
268+ }
269+
270+ // Check after last app
271+ let last = initial_configuration. last ( ) . unwrap ( ) ;
272+ let gap_start = last. address + last. size ;
273+
274+ log:: info!(
275+ "checking for last gap {:#x}, obtained with addr {:#x}, size {}" ,
276+ gap_start,
277+ last. address,
278+ last. size
279+ ) ;
280+
281+ if new_start >= gap_start {
282+ initial_configuration. push ( new_app. as_index ( Some ( ram_addr) , flash_addr) ) ;
283+ found = true ;
284+ break ;
285+ }
286+ }
287+
288+ if !found {
289+ warn ! ( "No suitable space found for new app" ) ;
290+ return None ;
291+ }
292+ }
293+
294+ println ! ( "final intial configuration: " ) ;
295+ for app in & initial_configuration {
296+ println ! (
297+ "app idx {}, addr {:#x}, size {}" ,
298+ app. idx. unwrap( ) ,
299+ app. address,
300+ app. size
301+ ) ;
302+ }
303+
192304 log:: info!( "sorted rust apps {:#x?}" , rust_apps) ;
193305 // panic!();
194306
@@ -211,136 +323,123 @@ pub fn reshuffle_apps(
211323 let mut total_padding: usize = 0 ;
212324 let mut permutation_index: usize = 0 ;
213325 let mut rust_index: usize = 0 ;
214- let mut reordered_apps: Vec < Index > = Vec :: new ( ) ;
326+ let mut reordered_apps: Vec < Index > = initial_configuration . clone ( ) ;
215327 let mut compatible_index: usize = 0 ;
216- loop {
217- let insert_c: bool ; // every iteration will insert an app, or break if there are none left
218-
219- // start either where the last app ends, or at start address if there are no apps
220- let address = reordered_apps
221- . last ( )
222- . map_or ( settings. start_address , |app| app. address + app. size ) ;
223-
224- if order. get ( permutation_index) . is_some ( ) {
225- // we have a C app
226- if rust_apps. get ( rust_index) . is_some ( ) {
227- // we also have a rust app, insert C app only if it fits
228- loop {
229- if rust_apps[ rust_index] . compatible_addresses [ compatible_index]
230- . expect ( "No available binary (idk)" )
231- . 0
232- >= address
233- {
234- break ;
235- } else {
236- compatible_index += 1 ;
237- }
238- }
239- insert_c = c_apps[ order[ permutation_index] ] . size
240- <= rust_apps[ rust_index] . compatible_addresses [ compatible_index]
241- . expect ( "No candidate (1)" )
242- . 0
243- - address;
328+
329+ for index in order {
330+ let c_app = & c_apps[ index] ;
331+ let insert_size = c_app. size ;
332+
333+ if reordered_apps. is_empty ( ) {
334+ reordered_apps. push ( c_app. as_index ( None , settings. start_address ) ) ;
335+
336+ continue ;
337+ }
338+
339+ log:: info!( "checking for intermediate" ) ;
340+ let mut inserted = false ;
341+
342+ for i in 0 ..reordered_apps. len ( ) - 1 {
343+ let base = reordered_apps[ i] . address + reordered_apps[ i] . size ;
344+ let gap = reordered_apps[ i + 1 ] . address - base;
345+
346+ let needed_padding = if !base. is_multiple_of ( settings. page_size ) {
347+ settings. page_size - base % settings. page_size
244348 } else {
245- // we have only a C app, insert it accordingly
246- insert_c = true ;
247- }
248- } else {
249- // we don't have a c app
250- if rust_apps. get ( rust_index) . is_some ( ) {
251- loop {
252- log:: info!(
253- "comparing rust app addr {:#x?} and address {:#x?}" ,
254- rust_apps[ rust_index] . compatible_addresses[ compatible_index]
255- . unwrap( )
256- . 0 ,
257- address
349+ 0
350+ } ;
351+
352+ let final_addr = base + needed_padding;
353+
354+ if insert_size + needed_padding <= gap {
355+ if needed_padding > 0 {
356+ total_padding += needed_padding as usize ;
357+
358+ reordered_apps. insert (
359+ i + 1 ,
360+ Index {
361+ installed : false ,
362+ idx : None ,
363+ fixed : false ,
364+ ram_address : None ,
365+ address : base,
366+ size : needed_padding,
367+ } ,
258368 ) ;
259- if rust_apps[ rust_index] . compatible_addresses [ compatible_index]
260- . expect ( "No available binary (idk)" )
261- . 0
262- >= address
263- {
264- break ;
265- } else {
266- compatible_index += 1 ;
267- }
369+
370+ reordered_apps. insert ( i + 2 , c_app. as_index ( None , final_addr) ) ;
371+ } else {
372+ reordered_apps. insert ( i + 1 , c_app. as_index ( None , final_addr) ) ;
268373 }
269- // we have a rust app, insert it
270- insert_c = false ;
271- } else {
272- // we don't have any app, break?
374+
375+ inserted = true ;
273376 break ;
274377 }
275378 }
276379
277- let mut start_address = reordered_apps
278- . last ( )
279- . map_or ( settings. start_address , |app| app. address + app. size ) ;
380+ if !inserted {
381+ let last = reordered_apps. last ( ) . unwrap ( ) ;
382+ let gap_start = last. address + last. size ;
383+
384+ log:: info!(
385+ "checking for last gap {:#x}, obtained with addr {:#x}, size {}" ,
386+ gap_start,
387+ last. address,
388+ last. size
389+ ) ;
280390
281- let needed_padding = if insert_c {
282- if !start_address. is_multiple_of ( settings. page_size ) {
391+ let needed_padding = if !gap_start. is_multiple_of ( settings. page_size ) {
283392 // c app needs to be inserted at a multiple of page_size
284- settings. page_size - start_address % settings. page_size
393+ settings. page_size - gap_start % settings. page_size
285394 } else {
286395 0
396+ } ;
397+
398+ if needed_padding > 0 {
399+ // insert a padding
400+ total_padding += needed_padding as usize ;
401+ reordered_apps. push ( Index {
402+ installed : false ,
403+ idx : None ,
404+ fixed : false ,
405+ ram_address : None ,
406+ address : settings. start_address + insert_size,
407+ size : needed_padding,
408+ } ) ;
409+ reordered_apps. push ( c_app. as_index ( None , gap_start + needed_padding) ) ;
410+ total_padding += needed_padding as usize ;
411+ } else {
412+ reordered_apps. push ( c_app. as_index ( None , gap_start) ) ;
287413 }
288- } else {
289- // rust app needs to be inserted at a fixed address, pad until there
290- rust_apps[ rust_index] . compatible_addresses [ compatible_index]
291- . expect ( "No compatible address! (3)" )
292- . 0
293- - start_address
294- } ;
295-
296- if needed_padding > 0 {
297- // insert a padding
298- total_padding += needed_padding as usize ;
299- reordered_apps. push ( Index {
300- installed : false ,
301- idx : None ,
302- fixed : false ,
303- ram_address : None ,
304- address : start_address,
305- size : needed_padding,
306- } ) ;
307-
308- start_address += needed_padding as u64 ;
309414 }
415+ }
310416
311- if insert_c {
312- // insert the c app, also change its address
313- let c_app = c_apps[ order[ permutation_index] ] . as_index ( None , start_address) ;
314- if c_app. idx . is_none ( ) {
315- panic ! ( "C app has no index assigned!" ) ;
316- }
417+ log:: info!(
418+ "obtained config before padding check {:#x?}" ,
419+ reordered_apps
420+ ) ;
317421
318- reordered_apps. push ( c_app) ;
319- permutation_index += 1 ;
320- } else {
321- // insert the rust app, don't change its address because it is fixed
322- let rust_app = rust_apps[ rust_index] . as_index (
323- Some (
324- rust_apps[ rust_index] . compatible_addresses [ compatible_index]
325- . expect ( "No compatible address! (4)" )
326- . 1 ,
327- ) ,
328- rust_apps[ rust_index] . compatible_addresses [ compatible_index]
329- . expect ( "No compatible address! (4)" )
330- . 0 ,
422+ let mut i = 0 ;
423+ while i < reordered_apps. len ( ) - 1 {
424+ let gap = reordered_apps[ i + 1 ] . address
425+ - ( reordered_apps[ i] . address + reordered_apps[ i] . size ) ;
426+
427+ if gap > 0 {
428+ reordered_apps. insert (
429+ i + 1 ,
430+ Index {
431+ installed : false ,
432+ idx : None ,
433+ fixed : false ,
434+ ram_address : None ,
435+ address : reordered_apps[ i] . address + reordered_apps[ i] . size ,
436+ size : gap,
437+ } ,
331438 ) ;
332- log:: debug!(
333- "rust app flash {:#x?}, rust app ram {:#x?}" ,
334- rust_app. address,
335- rust_app. ram_address
336- ) ;
337- if rust_app. idx . is_none ( ) {
338- panic ! ( "Rust app has no index assigned!" ) ;
339- }
340-
341- reordered_apps. push ( rust_app) ;
342- rust_index += 1 ;
439+ i += 1 ; // skip over inserted padding
343440 }
441+
442+ i += 1 ;
344443 }
345444
346445 // find the configuration that uses the minimum padding
@@ -356,6 +455,7 @@ pub fn reshuffle_apps(
356455 }
357456 }
358457 log:: info!( "obtained config {:#x?}" , saved_configuration) ;
458+ // panic!();
359459 Some ( saved_configuration)
360460}
361461
0 commit comments