@@ -498,6 +498,20 @@ def has_regions(self):
498
498
else :
499
499
return False
500
500
501
+ @property
502
+ def sectors (self ):
503
+ """Return a list of tuples of sector start,size"""
504
+ cache = Cache (False , False )
505
+ if self .target .device_name not in cache .index :
506
+ raise ConfigException ("Bootloader not supported on this target: "
507
+ "targets.json `device_name` not found in "
508
+ "arm_pack_manager index." )
509
+ cmsis_part = cache .index [self .target .device_name ]
510
+ sectors = cmsis_part ['sectors' ]
511
+ if sectors :
512
+ return sectors
513
+ raise ConfigException ("No sector info available" )
514
+
501
515
@property
502
516
def regions (self ):
503
517
"""Generate a list of regions from the config"""
@@ -526,12 +540,16 @@ def regions(self):
526
540
rom_size = int (cmsis_part ['memory' ]['IROM1' ]['size' ], 0 )
527
541
rom_start = int (cmsis_part ['memory' ]['IROM1' ]['start' ], 0 )
528
542
except KeyError :
529
- raise ConfigException ("Not enough information in CMSIS packs to "
530
- "build a bootloader project" )
543
+ try :
544
+ rom_size = int (cmsis_part ['memory' ]['PROGRAM_FLASH' ]['size' ], 0 )
545
+ rom_start = int (cmsis_part ['memory' ]['PROGRAM_FLASH' ]['start' ], 0 )
546
+ except KeyError :
547
+ raise ConfigException ("Not enough information in CMSIS packs to "
548
+ "build a bootloader project" )
531
549
if ('target.bootloader_img' in target_overrides or
532
550
'target.restrict_size' in target_overrides ):
533
- return self ._generate_booloader_build (target_overrides ,
534
- rom_start , rom_size )
551
+ return self ._generate_bootloader_build (target_overrides ,
552
+ rom_start , rom_size )
535
553
elif ('target.mbed_app_start' in target_overrides or
536
554
'target.mbed_app_size' in target_overrides ):
537
555
return self ._generate_linker_overrides (target_overrides ,
@@ -540,8 +558,8 @@ def regions(self):
540
558
raise ConfigException (
541
559
"Bootloader build requested but no bootlader configuration" )
542
560
543
- def _generate_booloader_build (self , target_overrides , rom_start , rom_size ):
544
- start = 0
561
+ def _generate_bootloader_build (self , target_overrides , rom_start , rom_size ):
562
+ start = rom_start
545
563
if 'target.bootloader_img' in target_overrides :
546
564
basedir = abspath (dirname (self .app_config_location ))
547
565
filename = join (basedir , target_overrides ['target.bootloader_img' ])
@@ -552,21 +570,48 @@ def _generate_booloader_build(self, target_overrides, rom_start, rom_size):
552
570
raise ConfigException ("bootloader executable does not "
553
571
"start at 0x%x" % rom_start )
554
572
part_size = (part .maxaddr () - part .minaddr ()) + 1
555
- yield Region ("bootloader" , rom_start + start , part_size , False ,
573
+ part_size = Config ._align_ceiling (rom_start + part_size , self .sectors ) - rom_start
574
+ yield Region ("bootloader" , rom_start , part_size , False ,
556
575
filename )
557
- start += part_size
576
+ start = rom_start + part_size
558
577
if 'target.restrict_size' in target_overrides :
559
578
new_size = int (target_overrides ['target.restrict_size' ], 0 )
560
- yield Region ("application" , rom_start + start , new_size , True , None )
579
+ new_size = Config ._align_floor (start + new_size , self .sectors ) - start
580
+ yield Region ("application" , start , new_size , True , None )
561
581
start += new_size
562
- yield Region ("post_application" , rom_start + start , rom_size - start ,
582
+ yield Region ("post_application" , start , rom_size - start ,
563
583
False , None )
564
584
else :
565
- yield Region ("application" , rom_start + start , rom_size - start ,
585
+ yield Region ("application" , start , rom_size - start ,
566
586
True , None )
567
- if start > rom_size :
587
+ if start > rom_start + rom_size :
568
588
raise ConfigException ("Not enough memory on device to fit all "
569
589
"application regions" )
590
+
591
+ @staticmethod
592
+ def _find_sector (address , sectors ):
593
+ target_size = - 1
594
+ target_start = - 1
595
+ for (start , size ) in sectors :
596
+ if address < start :
597
+ break
598
+ target_start = start
599
+ target_size = size
600
+ if (target_size < 0 ):
601
+ raise ConfigException ("No valid sector found" )
602
+ return target_start , target_size
603
+
604
+ @staticmethod
605
+ def _align_floor (address , sectors ):
606
+ target_start , target_size = Config ._find_sector (address , sectors )
607
+ sector_num = (address - target_start ) // target_size
608
+ return target_start + (sector_num * target_size )
609
+
610
+ @staticmethod
611
+ def _align_ceiling (address , sectors ):
612
+ target_start , target_size = Config ._find_sector (address , sectors )
613
+ sector_num = ((address - target_start ) + target_size - 1 ) // target_size
614
+ return target_start + (sector_num * target_size )
570
615
571
616
@property
572
617
def report (self ):
0 commit comments