Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-sdk-tools by
Diff: targets.py
- Revision:
- 32:8ea194f6145b
- Parent:
- 30:f12ce67666d0
--- a/targets.py Mon Aug 29 11:56:59 2016 +0100 +++ b/targets.py Wed Jan 04 11:58:24 2017 -0600 @@ -21,10 +21,15 @@ import shutil import inspect import sys +from collections import namedtuple from tools.patch import patch from tools.paths import TOOLS_BOOTLOADERS from tools.utils import json_file_to_dict +__all__ = ["target", "TARGETS", "TARGET_MAP", "TARGET_NAMES", "CORE_LABELS", + "HookError", "generate_py_target", "Target", + "CUMULATIVE_ATTRIBUTES", "get_resolution_order"] + CORE_LABELS = { "ARM7TDMI-S": ["ARM7", "LIKE_CORTEX_ARM7"], "Cortex-M0" : ["M0", "CORTEX_M", "LIKE_CORTEX_M0"], @@ -60,15 +65,58 @@ return CACHES[(func.__name__, args)] return wrapper -class Target(object): + +# Cumulative attributes can have values appended to them, so they +# need to be computed differently than regular attributes +CUMULATIVE_ATTRIBUTES = ['extra_labels', 'macros', 'device_has', 'features'] + + +def get_resolution_order(json_data, target_name, order, level=0): + """ Return the order in which target descriptions are searched for + attributes. This mimics the Python 2.2 method resolution order, which + is what the old targets.py module used. For more details, check + http://makina-corpus.com/blog/metier/2014/python-tutorial-understanding-python-mro-class-search-path + The resolution order contains (name, level) tuples, where "name" is the + name of the class and "level" is the level in the inheritance hierarchy + (the target itself is at level 0, its first parent at level 1, its + parent's parent at level 2 and so on) + """ + # the resolution order can't contain duplicate target names + if target_name not in [l[0] for l in order]: + order.append((target_name, level)) + parents = json_data[target_name].get("inherits", []) + for par in parents: + order = get_resolution_order(json_data, par, order, level + 1) + return order + + +def target(name, json_data): + """Construct a target object""" + resolution_order = get_resolution_order(json_data, name, []) + resolution_order_names = [tgt for tgt, _ in resolution_order] + return Target(name=name, + json_data={key: value for key, value in json_data.items() + if key in resolution_order_names}, + resolution_order=resolution_order, + resolution_order_names=resolution_order_names) + +def generate_py_target(new_targets, name): + """Add one or more new target(s) represented as a Python dictionary + in 'new_targets'. It is an error to add a target with a name that + already exists. + """ + base_targets = Target.get_json_target_data() + for new_target in new_targets.keys(): + if new_target in base_targets: + raise Exception("Attempt to add target '%s' that already exists" + % new_target) + total_data = {} + total_data.update(new_targets) + total_data.update(base_targets) + return target(name, total_data) + +class Target(namedtuple("Target", "name json_data resolution_order resolution_order_names")): """An object to represent a Target (MCU/Board)""" - # Cumulative attributes can have values appended to them, so they - # need to be computed differently than regular attributes - cumulative_attributes = ['extra_labels', 'macros', 'device_has', 'features'] - - # List of targets that were added dynamically using "add_py_targets" (see - # below) - __py_targets = set() # Default location of the 'targets.json' file __targets_json_location_default = os.path.join( @@ -99,24 +147,6 @@ return dict([(m[0], m[1]) for m in inspect.getmembers(sys.modules[__name__])]) - def __get_resolution_order(self, target_name, order, level=0): - """ Return the order in which target descriptions are searched for - attributes. This mimics the Python 2.2 method resolution order, which - is what the old targets.py module used. For more details, check - http://makina-corpus.com/blog/metier/2014/python-tutorial-understanding-python-mro-class-search-path - The resolution order contains (name, level) tuples, where "name" is the - name of the class and "level" is the level in the inheritance hierarchy - (the target itself is at level 0, its first parent at level 1, its - parent's parent at level 2 and so on) - """ - # the resolution order can't contain duplicate target names - if target_name not in [l[0] for l in order]: - order.append((target_name, level)) - parents = self.get_json_target_data()[target_name].get("inherits", []) - for par in parents: - order = self.__get_resolution_order(par, order, level + 1) - return order - @staticmethod def __add_paths_to_progen(data): """Modify the exporter specification ("progen") by changing all @@ -137,14 +167,14 @@ """Look for the attribute in the class and its parents, as defined by the resolution order """ - tdata = self.get_json_target_data() + tdata = self.json_data # For a cumulative attribute, figure out when it was defined the # last time (in attribute resolution order) then follow the "_add" # and "_remove" data fields - for idx, target in enumerate(self.resolution_order): + for idx, tgt in enumerate(self.resolution_order): # the attribute was defined at this level in the resolution # order - if attrname in tdata[target[0]]: + if attrname in tdata[tgt[0]]: def_idx = idx break else: @@ -196,13 +226,13 @@ def __getattr_helper(self, attrname): """Compute the value of a given target attribute""" - if attrname in self.cumulative_attributes: + if attrname in CUMULATIVE_ATTRIBUTES: return self.__getattr_cumulative(attrname) else: - tdata = self.get_json_target_data() + tdata = self.json_data starting_value = None - for target in self.resolution_order: - data = tdata[target[0]] + for tgt in self.resolution_order: + data = tdata[tgt[0]] if data.has_key(attrname): starting_value = data[attrname] break @@ -227,40 +257,11 @@ return result @staticmethod - def add_py_targets(new_targets): - """Add one or more new target(s) represented as a Python dictionary - in 'new_targets'. It is an error to add a target with a name that - already exists. - """ - crt_data = Target.get_json_target_data() - for target_key, target_value in new_targets.items(): - if crt_data.has_key(target_key): - raise Exception( - "Attempt to add target '%s' that already exists" - % target_key) - # Add target data to the internal target dictionary - crt_data[target_key] = target_value - # Create the new target and add it to the relevant data structures - new_target = Target(target_key) - TARGETS.append(new_target) - TARGET_MAP[target_key] = new_target - TARGET_NAMES.append(target_key) - - @staticmethod @cached def get_target(target_name): """ Return the target instance starting from the target name """ - return Target(target_name) - - def __init__(self, target_name): - self.name = target_name + return target(target_name, Target.get_json_target_data()) - # Compute resolution order once (it will be used later in __getattr__) - self.resolution_order = self.__get_resolution_order(self.name, []) - # Create also a list with only the names of the targets in the - # resolution order - self.resolution_order_names = [target[0] for target - in self.resolution_order] @property def program_cycle_s(self): @@ -272,7 +273,8 @@ except AttributeError: return 4 if self.is_disk_virtual else 1.5 - def get_labels(self): + @property + def labels(self): """Get all possible labels for this target""" labels = [self.name] + CORE_LABELS[self.core] + self.extra_labels # Automatically define UVISOR_UNSUPPORTED if the target doesn't @@ -485,6 +487,12 @@ with open(binf.replace(".bin", ".hex"), "w") as fileout: binh.tofile(fileout, format='hex') +class NCS36510TargetCode: + @staticmethod + def ncs36510_addfib(t_self, resources, elf, binf): + from tools.add_fib import add_fib_at_start + print("binf ", binf) + add_fib_at_start(binf[:-4]) ################################################################################ # Instantiate all public targets @@ -505,9 +513,9 @@ """ Returns dictionary mapping detect_code -> platform_name """ result = {} - for target in TARGETS: - for detect_code in target.detect_code: - result[detect_code] = target.name + for tgt in TARGETS: + for detect_code in tgt.detect_code: + result[detect_code] = tgt.name return result def set_targets_json_location(location=None): @@ -518,9 +526,9 @@ # re-initialization does not create new variables, it keeps the old ones # instead. This ensures compatibility with code that does # "from tools.targets import TARGET_NAMES" - TARGETS[:] = [Target.get_target(target) for target, obj + TARGETS[:] = [Target.get_target(tgt) for tgt, obj in Target.get_json_target_data().items() if obj.get("public", True)] TARGET_MAP.clear() - TARGET_MAP.update(dict([(target.name, target) for target in TARGETS])) + TARGET_MAP.update(dict([(tgt.name, tgt) for tgt in TARGETS])) TARGET_NAMES[:] = TARGET_MAP.keys()