diff --git a/tools/build_api.py b/tools/build_api.py index 3702447c3f..8b00c64b7e 100644 --- a/tools/build_api.py +++ b/tools/build_api.py @@ -400,6 +400,7 @@ def _fill_header(region_list, current_region): start += Config.header_member_size(member) return header + def merge_region_list(region_list, destination, notify, padding=b'\xFF'): """Merge the region_list into a single image @@ -410,7 +411,6 @@ def merge_region_list(region_list, destination, notify, padding=b'\xFF'): """ merged = IntelHex() _, format = splitext(destination) - notify.info("Merging Regions") for region in region_list: @@ -425,20 +425,17 @@ def merge_region_list(region_list, destination, notify, padding=b'\xFF'): notify.info(" Filling region %s with %s" % (region.name, region.filename)) part = intelhex_offset(region.filename, offset=region.start) part.start_addr = None - part_size = (part.maxaddr() - part.minaddr()) + 1 - if part_size > region.size: - raise ToolException("Contents of region %s does not fit" - % region.name) merged.merge(part) - pad_size = region.size - part_size - if pad_size > 0 and region != region_list[-1]: - notify.info(" Padding region %s with 0x%x bytes" % - (region.name, pad_size)) - if format is ".hex": - """The offset will be in the hex file generated when we're done, - so we can skip padding here""" - else: - merged.puts(merged.maxaddr() + 1, padding * pad_size) + + # Hex file can have gaps, so no padding needed. While other formats may + # need padding. Iterate through segments and pad the gaps. + if format != ".hex": + # begin patching from the end of the first segment + _, begin = merged.segments()[0] + for start, stop in merged.segments()[1:]: + pad_size = start - begin + merged.puts(begin, padding * pad_size) + begin = stop + 1 if not exists(dirname(destination)): makedirs(dirname(destination)) diff --git a/tools/config/__init__.py b/tools/config/__init__.py index f7ad8ebc38..1d51add46e 100644 --- a/tools/config/__init__.py +++ b/tools/config/__init__.py @@ -778,7 +778,7 @@ class Config(object): newstart = rom_start + integer(new_offset, 0) if newstart < start: raise ConfigException( - "Can not place % region inside previous region" % region_name) + "Can not place %r region inside previous region" % region_name) return newstart def _generate_bootloader_build(self, rom_memories): @@ -797,8 +797,19 @@ class Config(object): if part.minaddr() != rom_start: raise ConfigException("bootloader executable does not " "start at 0x%x" % rom_start) - part_size = (part.maxaddr() - part.minaddr()) + 1 - part_size = Config._align_ceiling(rom_start + part_size, self.sectors) - rom_start + + # find the last valid address that's within rom_end and use that + # to compute the bootloader size + end_address = None + for start, stop in part.segments(): + if (stop < rom_end): + end_address = stop + else: + break + if end_address == None: + raise ConfigException("bootloader segments don't fit within rom region") + part_size = Config._align_ceiling(end_address, self.sectors) - rom_start + yield Region("bootloader", rom_start, part_size, False, filename) start = rom_start + part_size @@ -809,9 +820,14 @@ class Config(object): start, region = self._make_header_region( start, self.target.header_format) yield region._replace(filename=self.target.header_format) + if self.target.restrict_size is not None: new_size = int(self.target.restrict_size, 0) new_size = Config._align_floor(start + new_size, self.sectors) - start + + if self.target.app_offset: + start = self._assign_new_offset(rom_start, start, self.target.app_offset, "application") + yield Region("application", start, new_size, True, None) start += new_size if self.target.header_format and not self.target.bootloader_img: @@ -821,9 +837,7 @@ class Config(object): start, region = self._make_header_region( start, self.target.header_format) yield region - if self.target.app_offset: - start = self._assign_new_offset( - rom_start, start, self.target.app_offset, "application") + yield Region("post_application", start, rom_end - start, False, None) else: @@ -832,7 +846,7 @@ class Config(object): rom_start, start, self.target.app_offset, "application") yield Region("application", start, rom_end - start, True, None) - if start > rom_start + rom_size: + if start > rom_end: raise ConfigException("Not enough memory on device to fit all " "application regions")