Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 29 additions & 4 deletions tockloader/app_tab.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import math
import struct
import textwrap

Expand Down Expand Up @@ -166,16 +167,40 @@ def set_size_constraint(self, constraint):
# Make sure the total app size is a power of two.
for tbf in self._get_tbfs():
current_size = tbf.tbfh.get_app_size()
original_app_size = current_size
if (current_size & (current_size - 1)) != 0:
# This is not a power of two, but should be.
count = 0
while current_size != 0:
current_size >>= 1
count += 1
tbf.tbfh.set_app_size(1 << count)
logging.debug(
"Rounding app up to ^2 size ({} bytes)".format(1 << count)
)

# Use 64kB as a heuristic for packing. Use the next power
# of two for sizes less than 64kB. Otherwise we use the
# the following to reduce wasted space:
# (X - 1) * (NextPowerOfTwo / 8) < size < X * (NextPowerOfTwo)
if original_app_size < (1024 * 64):
logging.debug(
"Rounding app up to ^2 size ({} bytes)".format(1 << count)
)
tbf.tbfh.set_app_size(1 << count)
else:
next_power2 = 1 << count
# Arm cortex-m v7 has 8 subregions for each MPU region
# of equal size, so we can enable X subregions of size
# 2^N / 8.
multiple = next_power2 / 8
number_of_unmasked_subregions = math.ceil(
original_app_size / multiple
)
new_size = int(number_of_unmasked_subregions * multiple)
logging.debug(
"Rounding app up to (X - 1) * (NextPowerOfTwo / 8) \
< size < X * (NextPowerOfTwo) ({} bytes)".format(
new_size
)
)
tbf.tbfh.set_app_size(new_size)

elif type(constraint) is tuple:
if constraint[0] == "multiple":
Expand Down
6 changes: 4 additions & 2 deletions tockloader/tockloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class TockLoader:
# - `start_address`: The absolute address in flash where apps start and
# must be loaded.
# - `order`: How apps should be sorted when flashed onto the board.
# Supported values: size_descending, None
# Supported values: size_descending, size_ascending, None
# - `size_constraint`: Valid sizes for the entire application.
# Supported values: powers_of_two, (multiple, value),
# None
Expand All @@ -94,7 +94,7 @@ class TockLoader:
},
"arch": {
"cortex-m": {
"order": "size_descending",
"order": "size_ascending",
"size_constraint": "powers_of_two",
"alignment_constraint": "size",
}
Expand Down Expand Up @@ -1561,6 +1561,8 @@ def is_valid(slices):
pass
elif self.app_settings["order"] == "size_descending":
apps.sort(key=lambda app: app.get_size(), reverse=True)
elif self.app_settings["order"] == "size_ascending":
apps.sort(key=lambda app: app.get_size())
elif self.app_settings["order"] == None:
# Any order is fine.
pass
Expand Down