@@ -780,13 +780,29 @@ def _make_header_region(self, start, header_format, offset=None):
780
780
return (start , region )
781
781
782
782
@staticmethod
783
- def _assign_new_offset (rom_start , start , new_offset , region_name ):
783
+ def _assign_new_offset (rom_start , new_offset , region_name , regions ):
784
784
newstart = rom_start + integer (new_offset , 0 )
785
- if newstart < start :
786
- raise ConfigException (
787
- "Can not place %r region inside previous region" % region_name )
785
+
786
+ for s , e in regions :
787
+ if newstart > s and newstart < e :
788
+ raise ConfigException (
789
+ "Can not place %r region inside previous region" % region_name )
788
790
return newstart
789
791
792
+ @staticmethod
793
+ def _get_end_address (region_list , start_address , rom_end ):
794
+ """Given a start address and set of regions, sort the
795
+ regions and then compute the end address.
796
+ The end address is either rom_end or beginning of the
797
+ next section, whichever is smaller
798
+ """
799
+ # Sort the list by starting address
800
+ region_list = sorted (region_list , key = lambda x :x [0 ])
801
+ for s , e in region_list :
802
+ if start_address < s :
803
+ return s
804
+ return rom_end
805
+
790
806
def _generate_bootloader_build (self , rom_memories ):
791
807
rom_start , rom_size = rom_memories .get ('ROM' )
792
808
start = rom_start
@@ -803,26 +819,41 @@ def _generate_bootloader_build(self, rom_memories):
803
819
if part .minaddr () != rom_start :
804
820
raise ConfigException ("bootloader executable does not "
805
821
"start at 0x%x" % rom_start )
822
+ regions = part .segments ()
806
823
807
824
# find the last valid address that's within rom_end and use that
808
825
# to compute the bootloader size
809
- end_address = None
810
- for start , stop in part .segments ():
811
- if (stop < rom_end ):
812
- end_address = stop
813
- else :
814
- break
815
- if end_address == None :
816
- raise ConfigException ("bootloader segments don't fit within rom region" )
817
- part_size = Config ._align_ceiling (end_address , self .sectors ) - rom_start
818
826
819
- yield Region ("bootloader" , rom_start , part_size , False ,
820
- filename )
827
+ # we have multiple parts in bootloader. Treat each of them as
828
+ # a different region (BLP1, BLP2 ...)
829
+ if len (part .segments ()) > 1 :
830
+ end_address = None
831
+ part_count = 0
832
+ for start , stop in part .segments ():
833
+ part_count += 1
834
+ if (stop < rom_end ):
835
+ end_address = stop
836
+ else :
837
+ break
838
+ if end_address == None :
839
+ raise ConfigException ("bootloader segments don't fit within rom" )
840
+ part_size = Config ._align_ceiling (end_address , self .sectors ) - rom_start
841
+ # Generate the region in the loop (bootloader0, bootloader1, ...)
842
+ yield Region ("bootloader" + str (part_count ), start , part_size , False , filename )
843
+ else :
844
+ # Number of segments is 1
845
+ _ , end_address = part .segments ()[0 ]
846
+ if (end_address > rom_end ):
847
+ raise ConfigException ("bootloader segments don't fit within rom" )
848
+ part_size = Config ._align_ceiling (end_address , self .sectors ) - rom_start
849
+ yield Region ("bootloader" , rom_start , part_size , False ,
850
+ filename )
851
+
821
852
start = rom_start + part_size
822
853
if self .target .header_format :
823
854
if self .target .header_offset :
824
855
start = self ._assign_new_offset (
825
- rom_start , start , self .target .header_offset , "header" )
856
+ rom_start , self .target .header_offset , "header" , regions )
826
857
start , region = self ._make_header_region (
827
858
start , self .target .header_format )
828
859
yield region ._replace (filename = self .target .header_format )
@@ -832,14 +863,14 @@ def _generate_bootloader_build(self, rom_memories):
832
863
new_size = Config ._align_floor (start + new_size , self .sectors ) - start
833
864
834
865
if self .target .app_offset :
835
- start = self ._assign_new_offset (rom_start , start , self .target .app_offset , "application" )
866
+ start = self ._assign_new_offset (rom_start , self .target .app_offset , "application" , regions )
836
867
837
868
yield Region ("application" , start , new_size , True , None )
838
869
start += new_size
839
870
if self .target .header_format and not self .target .bootloader_img :
840
871
if self .target .header_offset :
841
872
start = self ._assign_new_offset (
842
- rom_start , start , self .target .header_offset , "header" )
873
+ rom_start , self .target .header_offset , "header" , regions )
843
874
start , region = self ._make_header_region (
844
875
start , self .target .header_format )
845
876
yield region
@@ -849,8 +880,10 @@ def _generate_bootloader_build(self, rom_memories):
849
880
else :
850
881
if self .target .app_offset :
851
882
start = self ._assign_new_offset (
852
- rom_start , start , self .target .app_offset , "application" )
853
- yield Region ("application" , start , rom_end - start ,
883
+ rom_start , self .target .app_offset , "application" , regions )
884
+ # compute the end address of the application region based on existing segments
885
+ end = self ._get_end_address (regions , start , rom_end )
886
+ yield Region ("application" , start , end - start ,
854
887
True , None )
855
888
if start > rom_end :
856
889
raise ConfigException ("Not enough memory on device to fit all "
0 commit comments