@@ -780,13 +780,29 @@ def _make_header_region(self, start, header_format, offset=None):
780780 return (start , region )
781781
782782 @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 ):
784784 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 )
788790 return newstart
789791
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+
790806 def _generate_bootloader_build (self , rom_memories ):
791807 rom_start , rom_size = rom_memories .get ('ROM' )
792808 start = rom_start
@@ -803,26 +819,41 @@ def _generate_bootloader_build(self, rom_memories):
803819 if part .minaddr () != rom_start :
804820 raise ConfigException ("bootloader executable does not "
805821 "start at 0x%x" % rom_start )
822+ regions = part .segments ()
806823
807824 # find the last valid address that's within rom_end and use that
808825 # 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
818826
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+
821852 start = rom_start + part_size
822853 if self .target .header_format :
823854 if self .target .header_offset :
824855 start = self ._assign_new_offset (
825- rom_start , start , self .target .header_offset , "header" )
856+ rom_start , self .target .header_offset , "header" , regions )
826857 start , region = self ._make_header_region (
827858 start , self .target .header_format )
828859 yield region ._replace (filename = self .target .header_format )
@@ -832,14 +863,14 @@ def _generate_bootloader_build(self, rom_memories):
832863 new_size = Config ._align_floor (start + new_size , self .sectors ) - start
833864
834865 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 )
836867
837868 yield Region ("application" , start , new_size , True , None )
838869 start += new_size
839870 if self .target .header_format and not self .target .bootloader_img :
840871 if self .target .header_offset :
841872 start = self ._assign_new_offset (
842- rom_start , start , self .target .header_offset , "header" )
873+ rom_start , self .target .header_offset , "header" , regions )
843874 start , region = self ._make_header_region (
844875 start , self .target .header_format )
845876 yield region
@@ -849,8 +880,10 @@ def _generate_bootloader_build(self, rom_memories):
849880 else :
850881 if self .target .app_offset :
851882 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 ,
854887 True , None )
855888 if start > rom_end :
856889 raise ConfigException ("Not enough memory on device to fit all "
0 commit comments