diff --git a/tools/build_api.py b/tools/build_api.py index 4a3de865d3..c647c4ebf6 100644 --- a/tools/build_api.py +++ b/tools/build_api.py @@ -411,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: @@ -426,20 +425,21 @@ 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 len(part.segments()) == 1: + part_size = (part.maxaddr() - part.minaddr()) + 1 + else: + # make same assumption as in region builder; first segments must fit. + part_size = part.segments()[0][1] - part.segments()[0][0] + 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]: + if pad_size > 0 and region != region_list[-1] and format != ".hex": 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) + merged.puts(merged.maxaddr() + 1, padding * pad_size) if not exists(dirname(destination)): makedirs(dirname(destination)) diff --git a/tools/config/__init__.py b/tools/config/__init__.py index e963fd1b38..0e040faf58 100644 --- a/tools/config/__init__.py +++ b/tools/config/__init__.py @@ -692,12 +692,13 @@ 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_start, rom_size): start = rom_start rom_end = rom_start + rom_size + max_app_addr = -1 if self.target.bootloader_img: if isabs(self.target.bootloader_img): filename = self.target.bootloader_img @@ -710,8 +711,23 @@ 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 + if len(part.segments()) == 1: + part_size = (part.maxaddr() - part.minaddr()) + 1 + part_size = Config._align_ceiling(rom_start + part_size, self.sectors) - rom_start + else: + # assume first segment is at start + # second at the end or outside ROM + # rest outside regular ROM + if part.segments()[0][0] != 0x0: + raise ConfigException("bootloader segments not in order") + part_size = part.segments()[0][1] - part.segments()[0][0] + part_size = Config._align_ceiling(rom_start + part_size, self.sectors) - rom_start + if part.segments()[1][0] < rom_end and self.target.restrict_size is None: + if self.target.app_offset: + self.target.restrict_size = "0x%x" % (part.segments()[1][0] - int(self.target.app_offset, 0)) + else: + max_app_addr = part.segments()[1][0] + yield Region("bootloader", rom_start, part_size, False, filename) start = rom_start + part_size @@ -722,9 +738,17 @@ class Config(object): start, region = self._make_header_region( start, self.target.header_format) yield region._replace(filename=self.target.header_format) + + if max_app_addr != -1 and self.target.restrict_size is None and not self.target.app_offset: + self.target.restrict_size = "0x%x" % (max_app_addr - start) + 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: @@ -734,9 +758,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: @@ -745,7 +767,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")