Skip to content

Let libraries, targets configure bootloader #5909

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 6 commits into from
Feb 1, 2018
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
28 changes: 0 additions & 28 deletions tools/build_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,31 +284,6 @@ def get_mbed_official_release(version):

return mbed_official_release

def add_regions_to_profile(profile, config, toolchain_class):
"""Add regions to the build profile, if there are any.

Positional Arguments:
profile - the profile to update
config - the configuration object that owns the region
toolchain_class - the class of the toolchain being used
"""
if not profile:
return
regions = list(config.regions)
for region in regions:
for define in [(region.name.upper() + "_ADDR", region.start),
(region.name.upper() + "_SIZE", region.size)]:
profile["common"].append("-D%s=0x%x" % define)
active_region = [r for r in regions if r.active][0]
for define in [("MBED_APP_START", active_region.start),
("MBED_APP_SIZE", active_region.size)]:
profile["ld"].append(toolchain_class.make_ld_define(*define))

print("Using regions in this build:")
for region in regions:
print(" Region %s size 0x%x, offset 0x%x"
% (region.name, region.size, region.start))


def prepare_toolchain(src_paths, build_dir, target, toolchain_name,
macros=None, clean=False, jobs=1,
Expand Down Expand Up @@ -352,9 +327,6 @@ def prepare_toolchain(src_paths, build_dir, target, toolchain_name,
for key in profile:
profile[key].extend(contents[toolchain_name][key])

if config.has_regions:
add_regions_to_profile(profile, config, cur_tc)

toolchain = cur_tc(target, notify, macros, silent, build_dir=build_dir,
extra_verbose=extra_verbose, build_profile=profile)

Expand Down
85 changes: 43 additions & 42 deletions tools/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

from copy import deepcopy
import os
from os.path import dirname, abspath, exists, join
from os.path import dirname, abspath, exists, join, isabs
import sys
from collections import namedtuple
from os.path import splitext, relpath
Expand All @@ -30,6 +30,10 @@
from tools.targets import CUMULATIVE_ATTRIBUTES, TARGET_MAP, \
generate_py_target, get_resolution_order

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

# Base class for all configuration exceptions
class ConfigException(Exception):
"""Config system only exception. Makes it easier to distinguish config
Expand Down Expand Up @@ -84,6 +88,8 @@ def get_full_name(name, unit_name, unit_kind, label=None,
else:
prefix = unit_name + '.'
return prefix + name
if name in BOOTLOADER_OVERRIDES:
return name
# The name has a prefix, so check if it is valid
if not allow_prefix:
raise ConfigException("Invalid parameter name '%s' in '%s'" %
Expand Down Expand Up @@ -362,8 +368,6 @@ class Config(object):
"artifact_name": str}
}

__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 @@ -441,6 +445,9 @@ def __init__(self, tgt, top_level_dirs=None, app_config=None):
self.target = tgt
self.target = deepcopy(self.target)
self.target_labels = self.target.labels
for override in BOOTLOADER_OVERRIDES:
_, attr = override.split(".")
setattr(self.target, attr, None)

self.cumulative_overrides = {key: ConfigCumulativeOverride(key)
for key in CUMULATIVE_ATTRIBUTES}
Expand Down Expand Up @@ -488,15 +495,11 @@ def add_config_files(self, flist):
@property
def has_regions(self):
"""Does this config have regions defined?"""
if 'target_overrides' in self.app_config_data:
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 or
'target.mbed_app_start' in target_overrides or
'target.mbed_app_size' in target_overrides)
else:
return False
for override in BOOTLOADER_OVERRIDES:
_, attr = override.split(".")
if getattr(self.target, attr, None):
return True
return False

@property
def sectors(self):
Expand Down Expand Up @@ -526,12 +529,8 @@ def regions(self):
"targets.json `device_name` not found in "
"arm_pack_manager index.")
cmsis_part = cache.index[self.target.device_name]
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)):
if ((self.target.bootloader_img or self.target.restrict_size) and
(self.target.mbed_app_start or self.target.mbed_app_size)):
raise ConfigException(
"target.bootloader_img and target.restirct_size are "
"incompatible with target.mbed_app_start and "
Expand All @@ -546,23 +545,22 @@ def regions(self):
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_bootloader_build(target_overrides,
rom_start, 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)
if self.target.bootloader_img or self.target.restrict_size:
return self._generate_bootloader_build(rom_start, rom_size)
elif self.target.mbed_app_start or self.target.mbed_app_size:
return self._generate_linker_overrides(rom_start, rom_size)
else:
raise ConfigException(
"Bootloader build requested but no bootlader configuration")

def _generate_bootloader_build(self, target_overrides, rom_start, rom_size):
def _generate_bootloader_build(self, rom_start, rom_size):
start = rom_start
if 'target.bootloader_img' in target_overrides:
basedir = abspath(dirname(self.app_config_location))
filename = join(basedir, target_overrides['target.bootloader_img'])
if self.target.bootloader_img:
if isabs(self.target.bootloader_img):
filename = self.target.bootloader_img
else:
basedir = abspath(dirname(self.app_config_location))
filename = join(basedir, self.target.bootloader_img)
if not exists(filename):
raise ConfigException("Bootloader %s not found" % filename)
part = intelhex_offset(filename, offset=rom_start)
Expand All @@ -574,8 +572,8 @@ def _generate_bootloader_build(self, target_overrides, rom_start, rom_size):
yield Region("bootloader", rom_start, part_size, False,
filename)
start = rom_start + part_size
if 'target.restrict_size' in target_overrides:
new_size = int(target_overrides['target.restrict_size'], 0)
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
yield Region("application", start, new_size, True, None)
start += new_size
Expand Down Expand Up @@ -618,14 +616,13 @@ 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)
def _generate_linker_overrides(self, rom_start, rom_size):
if self.target.mbed_app_start is not None:
start = int(self.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)
if self.target.mbed_app_size is not None:
size = int(self.target.mbed_app_size, 0)
else:
size = (rom_size + rom_start) - start
if start < rom_start:
Expand Down Expand Up @@ -695,18 +692,22 @@ def _process_config_and_overrides(self, data, params, unit_name, unit_kind):

# Consider the others as overrides
for name, val in overrides.items():
if (name in PATH_OVERRIDES and "__config_path" in data):
val = os.path.join(
os.path.dirname(data["__config_path"]), val)

# Get the full name of the parameter
full_name = ConfigParameter.get_full_name(name, unit_name,
unit_kind, label)
if full_name in params:
params[full_name].set_value(val, unit_name, unit_kind,
label)
elif name in self.__unused_overrides:
pass
elif (name.startswith("target.") and
unit_kind is "application"):
(unit_kind is "application" or
name in BOOTLOADER_OVERRIDES)):
_, attribute = name.split(".")
setattr(self.target, attribute, val)
continue
else:
self.config_errors.append(
ConfigException(
Expand Down Expand Up @@ -759,7 +760,7 @@ def get_target_config_data(self):
rel_names = [tgt for tgt, _ in
get_resolution_order(self.target.json_data, tname,
[])]
if full_name in self.__unused_overrides:
if full_name in BOOTLOADER_OVERRIDES:
continue
if (full_name not in params) or \
(params[full_name].defined_by[7:] not in rel_names):
Expand Down
2 changes: 2 additions & 0 deletions tools/export/gnuarmeclipse/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ def create_jinja_ctx(self):

# Hack to fill in build_dir
toolchain.build_dir = self.toolchain.build_dir
toolchain.config = self.toolchain.config
toolchain.set_config_data(self.toolchain.config.get_config_data())

flags = self.toolchain_flags(toolchain)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "bl",
"target_overrides": {
"LPC1768": {
"target.bootloader_img": "does_not_exists.bin",
"target.restrict_size": "0xFFFFF"
}
}
}
3 changes: 2 additions & 1 deletion tools/test/config/bootloader_missing/mbed_app.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"target_overrides": {
"K64F": {
"target.bootloader_img": "does_not_exists.bin"
"target.bootloader_img": "does_not_exists.bin",
"target.restrict_size": "0xFFFFF"
}
}
}
3 changes: 3 additions & 0 deletions tools/test/config/bootloader_missing/test_data.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"K64F": {
"exception_msg": "not found"
},
"LPC1768": {
"exception_msg": "not found"
}
}
22 changes: 22 additions & 0 deletions tools/toolchains/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1231,9 +1231,31 @@ def mem_stats(self, map):

return None

def add_regions(self):
"""Add regions to the build profile, if there are any.
"""
print("Using regions in this build:")
for region in self.config.regions:
for define in [(region.name.upper() + "_ADDR", region.start),
(region.name.upper() + "_SIZE", region.size)]:
define_string = "-D%s=0x%x" % define
self.cc.append(define_string)
self.cppc.append(define_string)
self.flags["common"].append(define_string)
if region.active:
for define in [("MBED_APP_START", region.start),
("MBED_APP_SIZE", region.size)]:
define_string = self.make_ld_define(*define)
self.ld.append(define_string)
self.flags["ld"].append(define_string)
print(" Region %s size 0x%x, offset 0x%x"
% (region.name, region.size, region.start))

# Set the configuration data
def set_config_data(self, config_data):
self.config_data = config_data
if self.config.has_regions:
self.add_regions()

# Creates the configuration header if needed:
# - if there is no configuration data, "mbed_config.h" is not create (or deleted if it exists).
Expand Down