Skip to content

Commit 4952e31

Browse files
author
Jammu Kekkonen
committed
Fix bootloader build region generation and add support for bootloaders with multiple segments, as required by NRF52 bootloader.
1 parent 920db63 commit 4952e31

File tree

2 files changed

+37
-15
lines changed

2 files changed

+37
-15
lines changed

tools/build_api.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,6 @@ def merge_region_list(region_list, destination, notify, padding=b'\xFF'):
411411
"""
412412
merged = IntelHex()
413413
_, format = splitext(destination)
414-
415414
notify.info("Merging Regions")
416415

417416
for region in region_list:
@@ -426,20 +425,21 @@ def merge_region_list(region_list, destination, notify, padding=b'\xFF'):
426425
notify.info(" Filling region %s with %s" % (region.name, region.filename))
427426
part = intelhex_offset(region.filename, offset=region.start)
428427
part.start_addr = None
429-
part_size = (part.maxaddr() - part.minaddr()) + 1
428+
if len(part.segments()) == 1:
429+
part_size = (part.maxaddr() - part.minaddr()) + 1
430+
else:
431+
# make same assumption as in region builder; first segments must fit.
432+
part_size = part.segments()[0][1] - part.segments()[0][0]
433+
430434
if part_size > region.size:
431435
raise ToolException("Contents of region %s does not fit"
432436
% region.name)
433437
merged.merge(part)
434438
pad_size = region.size - part_size
435-
if pad_size > 0 and region != region_list[-1]:
439+
if pad_size > 0 and region != region_list[-1] and format != ".hex":
436440
notify.info(" Padding region %s with 0x%x bytes" %
437441
(region.name, pad_size))
438-
if format is ".hex":
439-
"""The offset will be in the hex file generated when we're done,
440-
so we can skip padding here"""
441-
else:
442-
merged.puts(merged.maxaddr() + 1, padding * pad_size)
442+
merged.puts(merged.maxaddr() + 1, padding * pad_size)
443443

444444
if not exists(dirname(destination)):
445445
makedirs(dirname(destination))

tools/config/__init__.py

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -692,12 +692,13 @@ def _assign_new_offset(rom_start, start, new_offset, region_name):
692692
newstart = rom_start + integer(new_offset, 0)
693693
if newstart < start:
694694
raise ConfigException(
695-
"Can not place % region inside previous region" % region_name)
695+
"Can not place %r region inside previous region" % region_name)
696696
return newstart
697697

698698
def _generate_bootloader_build(self, rom_start, rom_size):
699699
start = rom_start
700700
rom_end = rom_start + rom_size
701+
max_app_addr = -1
701702
if self.target.bootloader_img:
702703
if isabs(self.target.bootloader_img):
703704
filename = self.target.bootloader_img
@@ -710,8 +711,23 @@ def _generate_bootloader_build(self, rom_start, rom_size):
710711
if part.minaddr() != rom_start:
711712
raise ConfigException("bootloader executable does not "
712713
"start at 0x%x" % rom_start)
713-
part_size = (part.maxaddr() - part.minaddr()) + 1
714-
part_size = Config._align_ceiling(rom_start + part_size, self.sectors) - rom_start
714+
if len(part.segments()) == 1:
715+
part_size = (part.maxaddr() - part.minaddr()) + 1
716+
part_size = Config._align_ceiling(rom_start + part_size, self.sectors) - rom_start
717+
else:
718+
# assume first segment is at start
719+
# second at the end or outside ROM
720+
# rest outside regular ROM
721+
if part.segments()[0][0] != 0x0:
722+
raise ConfigException("bootloader segments not in order")
723+
part_size = part.segments()[0][1] - part.segments()[0][0]
724+
part_size = Config._align_ceiling(rom_start + part_size, self.sectors) - rom_start
725+
if part.segments()[1][0] < rom_end and self.target.restrict_size is None:
726+
if self.target.app_offset:
727+
self.target.restrict_size = "0x%x" % (part.segments()[1][0] - int(self.target.app_offset, 0))
728+
else:
729+
max_app_addr = part.segments()[1][0]
730+
715731
yield Region("bootloader", rom_start, part_size, False,
716732
filename)
717733
start = rom_start + part_size
@@ -722,9 +738,17 @@ def _generate_bootloader_build(self, rom_start, rom_size):
722738
start, region = self._make_header_region(
723739
start, self.target.header_format)
724740
yield region._replace(filename=self.target.header_format)
741+
742+
if max_app_addr != -1 and self.target.restrict_size is None and not self.target.app_offset:
743+
self.target.restrict_size = "0x%x" % (max_app_addr - start)
744+
725745
if self.target.restrict_size is not None:
726746
new_size = int(self.target.restrict_size, 0)
727747
new_size = Config._align_floor(start + new_size, self.sectors) - start
748+
749+
if self.target.app_offset:
750+
start = self._assign_new_offset(rom_start, start, self.target.app_offset, "application")
751+
728752
yield Region("application", start, new_size, True, None)
729753
start += new_size
730754
if self.target.header_format and not self.target.bootloader_img:
@@ -734,9 +758,7 @@ def _generate_bootloader_build(self, rom_start, rom_size):
734758
start, region = self._make_header_region(
735759
start, self.target.header_format)
736760
yield region
737-
if self.target.app_offset:
738-
start = self._assign_new_offset(
739-
rom_start, start, self.target.app_offset, "application")
761+
740762
yield Region("post_application", start, rom_end - start,
741763
False, None)
742764
else:
@@ -745,7 +767,7 @@ def _generate_bootloader_build(self, rom_start, rom_size):
745767
rom_start, start, self.target.app_offset, "application")
746768
yield Region("application", start, rom_end - start,
747769
True, None)
748-
if start > rom_start + rom_size:
770+
if start > rom_end:
749771
raise ConfigException("Not enough memory on device to fit all "
750772
"application regions")
751773

0 commit comments

Comments
 (0)