Skip to content

Add support for Unmanaged Bootloader #4202

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 18, 2017
Merged
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
47 changes: 44 additions & 3 deletions tools/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,8 @@ class Config(object):
"artifact_name": str}
}

__unused_overrides = set(["target.bootloader_img", "target.restrict_size"])
__unused_overrides = set(["target.bootloader_img", "target.restrict_size",
"target.mbed_app_start", "target.mbed_app_size"])

# Allowed features in configurations
__allowed_features = [
Expand Down Expand Up @@ -485,7 +486,9 @@ def has_regions(self):
target_overrides = self.app_config_data['target_overrides'].get(
self.target.name, {})
return ('target.bootloader_img' in target_overrides or
'target.restrict_size' in target_overrides)
'target.restrict_size' in target_overrides or
'target.mbed_app_start' in target_overrides or
'target.mbed_app_size' in target_overrides)
else:
return False

Expand All @@ -495,15 +498,37 @@ def regions(self):
if not self.target.bootloader_supported:
raise ConfigException("Bootloader not supported on this target.")
cmsis_part = Cache(False, False).index[self.target.device_name]
start = 0
target_overrides = self.app_config_data['target_overrides'].get(
self.target.name, {})
if (('target.bootloader_img' in target_overrides or
'target.restrict_size' in target_overrides) and
('target.mbed_app_start' in target_overrides or
'target.mbed_app_size' in target_overrides)):
raise ConfigException(
"target.bootloader_img and target.restirct_size are "
"incompatible with target.mbed_app_start and "
"target.mbed_app_size")
try:
rom_size = int(cmsis_part['memory']['IROM1']['size'], 0)
rom_start = int(cmsis_part['memory']['IROM1']['start'], 0)
except KeyError:
raise ConfigException("Not enough information in CMSIS packs to "
"build a bootloader project")
if ('target.bootloader_img' in target_overrides or
'target.restrict_size' in target_overrides):
return self._generate_booloader_build(target_overrides,
rom_size, rom_size)
elif ('target.mbed_app_start' in target_overrides or
'target.mbed_app_size' in target_overrides):
return self._generate_linker_overrides(target_overrides,
rom_start, rom_size)
else:
raise ConfigException(
"Bootloader build requested but no bootlader configuration")

@staticmethod
def _generate_booloader_build(target_overrides, rom_start, rom_size):
start = 0
if 'target.bootloader_img' in target_overrides:
filename = target_overrides['target.bootloader_img']
if not exists(filename):
Expand Down Expand Up @@ -534,6 +559,22 @@ def report(self):
return {'app_config': self.app_config_location,
'library_configs': map(relpath, self.processed_configs.keys())}

@staticmethod
def _generate_linker_overrides(target_overrides, rom_start, rom_size):
if 'target.mbed_app_start' in target_overrides:
start = int(target_overrides['target.mbed_app_start'], 0)
else:
start = rom_start
if 'target.mbed_app_size' in target_overrides:
size = int(target_overrides['target.mbed_app_size'], 0)
else:
size = (rom_size + rom_start) - start
if start < rom_start:
raise ConfigException("Application starts before ROM")
if size + start > rom_size + rom_start:
raise ConfigException("Application ends after ROM")
yield Region("application", start, size, True, None)

def _process_config_and_overrides(self, data, params, unit_name, unit_kind):
"""Process "config_parameters" and "target_config_overrides" into a
given dictionary
Expand Down
2 changes: 2 additions & 0 deletions tools/test/toolchains/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ def test_toolchain_profile_c(profile, source_file):
toolchain = tc_class(TARGET_MAP["K64F"], build_profile=profile)
toolchain.inc_md5 = ""
toolchain.build_dir = ""
toolchain.config = MagicMock(app_config_locaiton=None)
compile_command = toolchain.compile_command(to_compile,
to_compile + ".o", [])
for parameter in profile['c'] + profile['common']:
Expand All @@ -67,6 +68,7 @@ def test_toolchain_profile_cpp(profile, source_file):
toolchain = tc_class(TARGET_MAP["K64F"], build_profile=profile)
toolchain.inc_md5 = ""
toolchain.build_dir = ""
toolchain.config = MagicMock(app_config_locaiton=None)
compile_command = toolchain.compile_command(to_compile,
to_compile + ".o", [])
for parameter in profile['cxx'] + profile['common']:
Expand Down
9 changes: 7 additions & 2 deletions tools/toolchains/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,9 @@ def compile_command(self, source, object, includes):
deps = self.parse_dependencies(dep_path) if (exists(dep_path)) else []
except IOError, IndexError:
deps = []
if len(deps) == 0 or self.need_update(object, deps):
config_file = ([self.config.app_config_location]
if self.config.app_config_location else [])
if len(deps) == 0 or self.need_update(object, deps + config_file):
if ext == '.cpp' or self.COMPILE_C_AS_CPP:
return self.compile_cpp(source, object, includes)
else:
Expand Down Expand Up @@ -1008,7 +1010,10 @@ def link_program(self, r, tmp_path, name):
map = join(tmp_path, name + '.map')

r.objects = sorted(set(r.objects))
if self.need_update(elf, r.objects + r.libraries + [r.linker_script]):
config_file = ([self.config.app_config_location]
if self.config.app_config_location else [])
if self.need_update(elf, r.objects + r.libraries + [r.linker_script] +
config_file):
needed_update = True
self.progress("link", name)
self.link(elf, r.objects, r.libraries, r.lib_dirs, r.linker_script)
Expand Down