Clone of official tools
targets/__init__.py@38:399953da035d, 2017-07-13 (annotated)
- Committer:
- The Other Jimmy
- Date:
- Thu Jul 13 15:26:26 2017 -0500
- Revision:
- 38:399953da035d
- Parent:
- 36:96847d42f010
- Child:
- 40:7d3fa6b99b2b
Update to tools release 5.5.2
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
The Other Jimmy |
36:96847d42f010 | 1 | """ |
The Other Jimmy |
36:96847d42f010 | 2 | mbed SDK |
The Other Jimmy |
36:96847d42f010 | 3 | Copyright (c) 2011-2016 ARM Limited |
The Other Jimmy |
36:96847d42f010 | 4 | |
The Other Jimmy |
36:96847d42f010 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); |
The Other Jimmy |
36:96847d42f010 | 6 | you may not use this file except in compliance with the License. |
The Other Jimmy |
36:96847d42f010 | 7 | You may obtain a copy of the License at |
The Other Jimmy |
36:96847d42f010 | 8 | |
The Other Jimmy |
36:96847d42f010 | 9 | http://www.apache.org/licenses/LICENSE-2.0 |
The Other Jimmy |
36:96847d42f010 | 10 | |
The Other Jimmy |
36:96847d42f010 | 11 | Unless required by applicable law or agreed to in writing, software |
The Other Jimmy |
36:96847d42f010 | 12 | distributed under the License is distributed on an "AS IS" BASIS, |
The Other Jimmy |
36:96847d42f010 | 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
The Other Jimmy |
36:96847d42f010 | 14 | See the License for the specific language governing permissions and |
The Other Jimmy |
36:96847d42f010 | 15 | limitations under the License. |
The Other Jimmy |
36:96847d42f010 | 16 | """ |
The Other Jimmy |
36:96847d42f010 | 17 | |
The Other Jimmy |
36:96847d42f010 | 18 | import os |
The Other Jimmy |
36:96847d42f010 | 19 | import binascii |
The Other Jimmy |
36:96847d42f010 | 20 | import struct |
The Other Jimmy |
36:96847d42f010 | 21 | import shutil |
The Other Jimmy |
36:96847d42f010 | 22 | import inspect |
The Other Jimmy |
36:96847d42f010 | 23 | import sys |
The Other Jimmy |
36:96847d42f010 | 24 | from copy import copy |
The Other Jimmy |
38:399953da035d | 25 | from collections import namedtuple, Mapping |
The Other Jimmy |
36:96847d42f010 | 26 | from tools.targets.LPC import patch |
The Other Jimmy |
36:96847d42f010 | 27 | from tools.paths import TOOLS_BOOTLOADERS |
The Other Jimmy |
36:96847d42f010 | 28 | from tools.utils import json_file_to_dict |
The Other Jimmy |
36:96847d42f010 | 29 | |
The Other Jimmy |
36:96847d42f010 | 30 | __all__ = ["target", "TARGETS", "TARGET_MAP", "TARGET_NAMES", "CORE_LABELS", |
The Other Jimmy |
36:96847d42f010 | 31 | "HookError", "generate_py_target", "Target", |
The Other Jimmy |
36:96847d42f010 | 32 | "CUMULATIVE_ATTRIBUTES", "get_resolution_order"] |
The Other Jimmy |
36:96847d42f010 | 33 | |
The Other Jimmy |
36:96847d42f010 | 34 | CORE_LABELS = { |
The Other Jimmy |
36:96847d42f010 | 35 | "Cortex-M0" : ["M0", "CORTEX_M", "LIKE_CORTEX_M0"], |
The Other Jimmy |
36:96847d42f010 | 36 | "Cortex-M0+": ["M0P", "CORTEX_M", "LIKE_CORTEX_M0"], |
The Other Jimmy |
36:96847d42f010 | 37 | "Cortex-M1" : ["M1", "CORTEX_M", "LIKE_CORTEX_M1"], |
The Other Jimmy |
36:96847d42f010 | 38 | "Cortex-M3" : ["M3", "CORTEX_M", "LIKE_CORTEX_M3"], |
The Other Jimmy |
36:96847d42f010 | 39 | "Cortex-M4" : ["M4", "CORTEX_M", "RTOS_M4_M7", "LIKE_CORTEX_M4"], |
The Other Jimmy |
36:96847d42f010 | 40 | "Cortex-M4F" : ["M4", "CORTEX_M", "RTOS_M4_M7", "LIKE_CORTEX_M4"], |
The Other Jimmy |
36:96847d42f010 | 41 | "Cortex-M7" : ["M7", "CORTEX_M", "RTOS_M4_M7", "LIKE_CORTEX_M7"], |
The Other Jimmy |
36:96847d42f010 | 42 | "Cortex-M7F" : ["M7", "CORTEX_M", "RTOS_M4_M7", "LIKE_CORTEX_M7"], |
The Other Jimmy |
36:96847d42f010 | 43 | "Cortex-M7FD" : ["M7", "CORTEX_M", "RTOS_M4_M7", "LIKE_CORTEX_M7"], |
The Other Jimmy |
36:96847d42f010 | 44 | "Cortex-A9" : ["A9", "CORTEX_A", "LIKE_CORTEX_A9"] |
The Other Jimmy |
36:96847d42f010 | 45 | } |
The Other Jimmy |
36:96847d42f010 | 46 | |
The Other Jimmy |
36:96847d42f010 | 47 | ################################################################################ |
The Other Jimmy |
36:96847d42f010 | 48 | # Generic Target class that reads and interprets the data in targets.json |
The Other Jimmy |
36:96847d42f010 | 49 | |
The Other Jimmy |
36:96847d42f010 | 50 | class HookError(Exception): |
The Other Jimmy |
36:96847d42f010 | 51 | """ A simple class that represents all the exceptions associated with |
The Other Jimmy |
36:96847d42f010 | 52 | hooking |
The Other Jimmy |
36:96847d42f010 | 53 | """ |
The Other Jimmy |
36:96847d42f010 | 54 | pass |
The Other Jimmy |
36:96847d42f010 | 55 | |
The Other Jimmy |
36:96847d42f010 | 56 | CACHES = {} |
The Other Jimmy |
36:96847d42f010 | 57 | def cached(func): |
The Other Jimmy |
36:96847d42f010 | 58 | """A simple decorator used for automatically caching data returned by a |
The Other Jimmy |
36:96847d42f010 | 59 | function |
The Other Jimmy |
36:96847d42f010 | 60 | """ |
The Other Jimmy |
36:96847d42f010 | 61 | def wrapper(*args, **kwargs): |
The Other Jimmy |
36:96847d42f010 | 62 | """The wrapped function itself""" |
The Other Jimmy |
36:96847d42f010 | 63 | if not CACHES.has_key((func.__name__, args)): |
The Other Jimmy |
36:96847d42f010 | 64 | CACHES[(func.__name__, args)] = func(*args, **kwargs) |
The Other Jimmy |
36:96847d42f010 | 65 | return CACHES[(func.__name__, args)] |
The Other Jimmy |
36:96847d42f010 | 66 | return wrapper |
The Other Jimmy |
36:96847d42f010 | 67 | |
The Other Jimmy |
36:96847d42f010 | 68 | |
The Other Jimmy |
36:96847d42f010 | 69 | # Cumulative attributes can have values appended to them, so they |
The Other Jimmy |
36:96847d42f010 | 70 | # need to be computed differently than regular attributes |
The Other Jimmy |
36:96847d42f010 | 71 | CUMULATIVE_ATTRIBUTES = ['extra_labels', 'macros', 'device_has', 'features'] |
The Other Jimmy |
36:96847d42f010 | 72 | |
The Other Jimmy |
36:96847d42f010 | 73 | |
The Other Jimmy |
36:96847d42f010 | 74 | def get_resolution_order(json_data, target_name, order, level=0): |
The Other Jimmy |
36:96847d42f010 | 75 | """ Return the order in which target descriptions are searched for |
The Other Jimmy |
36:96847d42f010 | 76 | attributes. This mimics the Python 2.2 method resolution order, which |
The Other Jimmy |
36:96847d42f010 | 77 | is what the old targets.py module used. For more details, check |
The Other Jimmy |
36:96847d42f010 | 78 | http://makina-corpus.com/blog/metier/2014/python-tutorial-understanding-python-mro-class-search-path |
The Other Jimmy |
36:96847d42f010 | 79 | The resolution order contains (name, level) tuples, where "name" is the |
The Other Jimmy |
36:96847d42f010 | 80 | name of the class and "level" is the level in the inheritance hierarchy |
The Other Jimmy |
36:96847d42f010 | 81 | (the target itself is at level 0, its first parent at level 1, its |
The Other Jimmy |
36:96847d42f010 | 82 | parent's parent at level 2 and so on) |
The Other Jimmy |
36:96847d42f010 | 83 | """ |
The Other Jimmy |
36:96847d42f010 | 84 | # the resolution order can't contain duplicate target names |
The Other Jimmy |
36:96847d42f010 | 85 | if target_name not in [l[0] for l in order]: |
The Other Jimmy |
36:96847d42f010 | 86 | order.append((target_name, level)) |
The Other Jimmy |
36:96847d42f010 | 87 | parents = json_data[target_name].get("inherits", []) |
The Other Jimmy |
36:96847d42f010 | 88 | for par in parents: |
The Other Jimmy |
36:96847d42f010 | 89 | order = get_resolution_order(json_data, par, order, level + 1) |
The Other Jimmy |
36:96847d42f010 | 90 | return order |
The Other Jimmy |
36:96847d42f010 | 91 | |
The Other Jimmy |
36:96847d42f010 | 92 | |
The Other Jimmy |
36:96847d42f010 | 93 | def target(name, json_data): |
The Other Jimmy |
36:96847d42f010 | 94 | """Construct a target object""" |
The Other Jimmy |
36:96847d42f010 | 95 | resolution_order = get_resolution_order(json_data, name, []) |
The Other Jimmy |
36:96847d42f010 | 96 | resolution_order_names = [tgt for tgt, _ in resolution_order] |
The Other Jimmy |
36:96847d42f010 | 97 | return Target(name=name, |
The Other Jimmy |
36:96847d42f010 | 98 | json_data={key: value for key, value in json_data.items() |
The Other Jimmy |
36:96847d42f010 | 99 | if key in resolution_order_names}, |
The Other Jimmy |
36:96847d42f010 | 100 | resolution_order=resolution_order, |
The Other Jimmy |
36:96847d42f010 | 101 | resolution_order_names=resolution_order_names) |
The Other Jimmy |
36:96847d42f010 | 102 | |
The Other Jimmy |
36:96847d42f010 | 103 | def generate_py_target(new_targets, name): |
The Other Jimmy |
36:96847d42f010 | 104 | """Add one or more new target(s) represented as a Python dictionary |
The Other Jimmy |
36:96847d42f010 | 105 | in 'new_targets'. It is an error to add a target with a name that |
The Other Jimmy |
36:96847d42f010 | 106 | already exists. |
The Other Jimmy |
36:96847d42f010 | 107 | """ |
The Other Jimmy |
36:96847d42f010 | 108 | base_targets = Target.get_json_target_data() |
The Other Jimmy |
36:96847d42f010 | 109 | for new_target in new_targets.keys(): |
The Other Jimmy |
36:96847d42f010 | 110 | if new_target in base_targets: |
The Other Jimmy |
36:96847d42f010 | 111 | raise Exception("Attempt to add target '%s' that already exists" |
The Other Jimmy |
36:96847d42f010 | 112 | % new_target) |
The Other Jimmy |
36:96847d42f010 | 113 | total_data = {} |
The Other Jimmy |
36:96847d42f010 | 114 | total_data.update(new_targets) |
The Other Jimmy |
36:96847d42f010 | 115 | total_data.update(base_targets) |
The Other Jimmy |
36:96847d42f010 | 116 | return target(name, total_data) |
The Other Jimmy |
36:96847d42f010 | 117 | |
The Other Jimmy |
36:96847d42f010 | 118 | class Target(namedtuple("Target", "name json_data resolution_order resolution_order_names")): |
The Other Jimmy |
36:96847d42f010 | 119 | """An object to represent a Target (MCU/Board)""" |
The Other Jimmy |
36:96847d42f010 | 120 | |
The Other Jimmy |
36:96847d42f010 | 121 | # Default location of the 'targets.json' file |
The Other Jimmy |
36:96847d42f010 | 122 | __targets_json_location_default = os.path.join( |
The Other Jimmy |
36:96847d42f010 | 123 | os.path.dirname(os.path.abspath(__file__)), '..', 'latest_targets.json') |
The Other Jimmy |
36:96847d42f010 | 124 | |
The Other Jimmy |
36:96847d42f010 | 125 | # Current/new location of the 'targets.json' file |
The Other Jimmy |
36:96847d42f010 | 126 | __targets_json_location = None |
The Other Jimmy |
36:96847d42f010 | 127 | |
The Other Jimmy |
38:399953da035d | 128 | # Extra custom targets files |
The Other Jimmy |
38:399953da035d | 129 | __extra_target_json_files = [] |
The Other Jimmy |
38:399953da035d | 130 | |
The Other Jimmy |
36:96847d42f010 | 131 | @staticmethod |
The Other Jimmy |
36:96847d42f010 | 132 | @cached |
The Other Jimmy |
36:96847d42f010 | 133 | def get_json_target_data(): |
The Other Jimmy |
36:96847d42f010 | 134 | """Load the description of JSON target data""" |
The Other Jimmy |
38:399953da035d | 135 | targets = json_file_to_dict(Target.__targets_json_location or |
The Other Jimmy |
38:399953da035d | 136 | Target.__targets_json_location_default) |
The Other Jimmy |
38:399953da035d | 137 | |
The Other Jimmy |
38:399953da035d | 138 | for extra_target in Target.__extra_target_json_files: |
The Other Jimmy |
38:399953da035d | 139 | for k, v in json_file_to_dict(extra_target).iteritems(): |
The Other Jimmy |
38:399953da035d | 140 | if k in targets: |
The Other Jimmy |
38:399953da035d | 141 | print 'WARNING: Custom target "%s" cannot replace existing target.' % k |
The Other Jimmy |
38:399953da035d | 142 | else: |
The Other Jimmy |
38:399953da035d | 143 | targets[k] = v |
The Other Jimmy |
38:399953da035d | 144 | |
The Other Jimmy |
38:399953da035d | 145 | return targets |
The Other Jimmy |
38:399953da035d | 146 | |
The Other Jimmy |
38:399953da035d | 147 | @staticmethod |
The Other Jimmy |
38:399953da035d | 148 | def add_extra_targets(source_dir): |
The Other Jimmy |
38:399953da035d | 149 | extra_targets_file = os.path.join(source_dir, "custom_targets.json") |
The Other Jimmy |
38:399953da035d | 150 | if os.path.exists(extra_targets_file): |
The Other Jimmy |
38:399953da035d | 151 | Target.__extra_target_json_files.append(extra_targets_file) |
The Other Jimmy |
38:399953da035d | 152 | CACHES.clear() |
The Other Jimmy |
36:96847d42f010 | 153 | |
The Other Jimmy |
36:96847d42f010 | 154 | @staticmethod |
The Other Jimmy |
36:96847d42f010 | 155 | def set_targets_json_location(location=None): |
The Other Jimmy |
36:96847d42f010 | 156 | """Set the location of the targets.json file""" |
The Other Jimmy |
36:96847d42f010 | 157 | Target.__targets_json_location = (location or |
The Other Jimmy |
36:96847d42f010 | 158 | Target.__targets_json_location_default) |
The Other Jimmy |
38:399953da035d | 159 | Target.__extra_target_json_files = [] |
The Other Jimmy |
36:96847d42f010 | 160 | # Invalidate caches, since the location of the JSON file changed |
The Other Jimmy |
36:96847d42f010 | 161 | CACHES.clear() |
The Other Jimmy |
36:96847d42f010 | 162 | |
The Other Jimmy |
36:96847d42f010 | 163 | @staticmethod |
The Other Jimmy |
36:96847d42f010 | 164 | @cached |
The Other Jimmy |
36:96847d42f010 | 165 | def get_module_data(): |
The Other Jimmy |
36:96847d42f010 | 166 | """Get the members of this module using Python's "inspect" module""" |
The Other Jimmy |
36:96847d42f010 | 167 | return dict([(m[0], m[1]) for m in |
The Other Jimmy |
36:96847d42f010 | 168 | inspect.getmembers(sys.modules[__name__])]) |
The Other Jimmy |
36:96847d42f010 | 169 | |
The Other Jimmy |
36:96847d42f010 | 170 | @staticmethod |
The Other Jimmy |
36:96847d42f010 | 171 | def __add_paths_to_progen(data): |
The Other Jimmy |
36:96847d42f010 | 172 | """Modify the exporter specification ("progen") by changing all |
The Other Jimmy |
36:96847d42f010 | 173 | "template" keys to full paths |
The Other Jimmy |
36:96847d42f010 | 174 | """ |
The Other Jimmy |
36:96847d42f010 | 175 | out = {} |
The Other Jimmy |
36:96847d42f010 | 176 | for key, val in data.items(): |
The Other Jimmy |
36:96847d42f010 | 177 | if isinstance(val, dict): |
The Other Jimmy |
36:96847d42f010 | 178 | out[key] = Target.__add_paths_to_progen(val) |
The Other Jimmy |
36:96847d42f010 | 179 | elif key == "template": |
The Other Jimmy |
36:96847d42f010 | 180 | out[key] = [os.path.join(os.path.dirname(__file__), 'export', v) |
The Other Jimmy |
36:96847d42f010 | 181 | for v in val] |
The Other Jimmy |
36:96847d42f010 | 182 | else: |
The Other Jimmy |
36:96847d42f010 | 183 | out[key] = val |
The Other Jimmy |
36:96847d42f010 | 184 | return out |
The Other Jimmy |
36:96847d42f010 | 185 | |
The Other Jimmy |
36:96847d42f010 | 186 | def __getattr_cumulative(self, attrname): |
The Other Jimmy |
36:96847d42f010 | 187 | """Look for the attribute in the class and its parents, as defined by |
The Other Jimmy |
36:96847d42f010 | 188 | the resolution order |
The Other Jimmy |
36:96847d42f010 | 189 | """ |
The Other Jimmy |
36:96847d42f010 | 190 | tdata = self.json_data |
The Other Jimmy |
36:96847d42f010 | 191 | # For a cumulative attribute, figure out when it was defined the |
The Other Jimmy |
36:96847d42f010 | 192 | # last time (in attribute resolution order) then follow the "_add" |
The Other Jimmy |
36:96847d42f010 | 193 | # and "_remove" data fields |
The Other Jimmy |
36:96847d42f010 | 194 | for idx, tgt in enumerate(self.resolution_order): |
The Other Jimmy |
36:96847d42f010 | 195 | # the attribute was defined at this level in the resolution |
The Other Jimmy |
36:96847d42f010 | 196 | # order |
The Other Jimmy |
36:96847d42f010 | 197 | if attrname in tdata[tgt[0]]: |
The Other Jimmy |
36:96847d42f010 | 198 | def_idx = idx |
The Other Jimmy |
36:96847d42f010 | 199 | break |
The Other Jimmy |
36:96847d42f010 | 200 | else: |
The Other Jimmy |
36:96847d42f010 | 201 | raise AttributeError("Attribute '%s' not found in target '%s'" |
The Other Jimmy |
36:96847d42f010 | 202 | % (attrname, self.name)) |
The Other Jimmy |
36:96847d42f010 | 203 | # Get the starting value of the attribute |
The Other Jimmy |
36:96847d42f010 | 204 | starting_value = (tdata[self.resolution_order[def_idx][0]][attrname] |
The Other Jimmy |
36:96847d42f010 | 205 | or [])[:] |
The Other Jimmy |
36:96847d42f010 | 206 | # Traverse the resolution list in high inheritance to low |
The Other Jimmy |
36:96847d42f010 | 207 | # inheritance level, left to right order to figure out all the |
The Other Jimmy |
36:96847d42f010 | 208 | # other classes that change the definition by adding or removing |
The Other Jimmy |
36:96847d42f010 | 209 | # elements |
The Other Jimmy |
36:96847d42f010 | 210 | for idx in xrange(self.resolution_order[def_idx][1] - 1, -1, -1): |
The Other Jimmy |
36:96847d42f010 | 211 | same_level_targets = [tar[0] for tar in self.resolution_order |
The Other Jimmy |
36:96847d42f010 | 212 | if tar[1] == idx] |
The Other Jimmy |
36:96847d42f010 | 213 | for tar in same_level_targets: |
The Other Jimmy |
36:96847d42f010 | 214 | data = tdata[tar] |
The Other Jimmy |
36:96847d42f010 | 215 | # Do we have anything to add ? |
The Other Jimmy |
36:96847d42f010 | 216 | if data.has_key(attrname + "_add"): |
The Other Jimmy |
36:96847d42f010 | 217 | starting_value.extend(data[attrname + "_add"]) |
The Other Jimmy |
36:96847d42f010 | 218 | # Do we have anything to remove ? |
The Other Jimmy |
36:96847d42f010 | 219 | if data.has_key(attrname + "_remove"): |
The Other Jimmy |
36:96847d42f010 | 220 | # Macros can be defined either without a value (MACRO) |
The Other Jimmy |
36:96847d42f010 | 221 | # or with a value (MACRO=10). When removing, we specify |
The Other Jimmy |
36:96847d42f010 | 222 | # only the name of the macro, without the value. So we |
The Other Jimmy |
36:96847d42f010 | 223 | # need to create a mapping between the macro name and |
The Other Jimmy |
36:96847d42f010 | 224 | # its value. This will work for extra_labels and other |
The Other Jimmy |
36:96847d42f010 | 225 | # type of arrays as well, since they fall into the |
The Other Jimmy |
36:96847d42f010 | 226 | # "macros without a value" category (simple definitions |
The Other Jimmy |
36:96847d42f010 | 227 | # without a value). |
The Other Jimmy |
36:96847d42f010 | 228 | name_def_map = {} |
The Other Jimmy |
36:96847d42f010 | 229 | for crtv in starting_value: |
The Other Jimmy |
36:96847d42f010 | 230 | if crtv.find('=') != -1: |
The Other Jimmy |
36:96847d42f010 | 231 | temp = crtv.split('=') |
The Other Jimmy |
36:96847d42f010 | 232 | if len(temp) != 2: |
The Other Jimmy |
36:96847d42f010 | 233 | raise ValueError( |
The Other Jimmy |
36:96847d42f010 | 234 | "Invalid macro definition '%s'" % crtv) |
The Other Jimmy |
36:96847d42f010 | 235 | name_def_map[temp[0]] = crtv |
The Other Jimmy |
36:96847d42f010 | 236 | else: |
The Other Jimmy |
36:96847d42f010 | 237 | name_def_map[crtv] = crtv |
The Other Jimmy |
36:96847d42f010 | 238 | for element in data[attrname + "_remove"]: |
The Other Jimmy |
36:96847d42f010 | 239 | if element not in name_def_map: |
The Other Jimmy |
36:96847d42f010 | 240 | raise ValueError( |
The Other Jimmy |
36:96847d42f010 | 241 | ("Unable to remove '%s' in '%s.%s' since " |
The Other Jimmy |
36:96847d42f010 | 242 | % (element, self.name, attrname)) + |
The Other Jimmy |
36:96847d42f010 | 243 | "it doesn't exist") |
The Other Jimmy |
36:96847d42f010 | 244 | starting_value.remove(name_def_map[element]) |
The Other Jimmy |
36:96847d42f010 | 245 | return starting_value |
The Other Jimmy |
36:96847d42f010 | 246 | |
The Other Jimmy |
36:96847d42f010 | 247 | def __getattr_helper(self, attrname): |
The Other Jimmy |
36:96847d42f010 | 248 | """Compute the value of a given target attribute""" |
The Other Jimmy |
36:96847d42f010 | 249 | if attrname in CUMULATIVE_ATTRIBUTES: |
The Other Jimmy |
36:96847d42f010 | 250 | return self.__getattr_cumulative(attrname) |
The Other Jimmy |
36:96847d42f010 | 251 | else: |
The Other Jimmy |
36:96847d42f010 | 252 | tdata = self.json_data |
The Other Jimmy |
36:96847d42f010 | 253 | starting_value = None |
The Other Jimmy |
36:96847d42f010 | 254 | for tgt in self.resolution_order: |
The Other Jimmy |
36:96847d42f010 | 255 | data = tdata[tgt[0]] |
The Other Jimmy |
36:96847d42f010 | 256 | if data.has_key(attrname): |
The Other Jimmy |
36:96847d42f010 | 257 | starting_value = data[attrname] |
The Other Jimmy |
36:96847d42f010 | 258 | break |
The Other Jimmy |
36:96847d42f010 | 259 | else: # Attribute not found |
The Other Jimmy |
36:96847d42f010 | 260 | raise AttributeError( |
The Other Jimmy |
36:96847d42f010 | 261 | "Attribute '%s' not found in target '%s'" |
The Other Jimmy |
36:96847d42f010 | 262 | % (attrname, self.name)) |
The Other Jimmy |
36:96847d42f010 | 263 | # 'progen' needs the full path to the template (the path in JSON is |
The Other Jimmy |
36:96847d42f010 | 264 | # relative to tools/export) |
The Other Jimmy |
36:96847d42f010 | 265 | if attrname == "progen": |
The Other Jimmy |
36:96847d42f010 | 266 | return self.__add_paths_to_progen(starting_value) |
The Other Jimmy |
36:96847d42f010 | 267 | else: |
The Other Jimmy |
36:96847d42f010 | 268 | return starting_value |
The Other Jimmy |
36:96847d42f010 | 269 | |
The Other Jimmy |
36:96847d42f010 | 270 | def __getattr__(self, attrname): |
The Other Jimmy |
36:96847d42f010 | 271 | """ Return the value of an attribute. This function only computes the |
The Other Jimmy |
36:96847d42f010 | 272 | attribute's value once, then adds it to the instance attributes (in |
The Other Jimmy |
36:96847d42f010 | 273 | __dict__), so the next time it is returned directly |
The Other Jimmy |
36:96847d42f010 | 274 | """ |
The Other Jimmy |
36:96847d42f010 | 275 | result = self.__getattr_helper(attrname) |
The Other Jimmy |
36:96847d42f010 | 276 | self.__dict__[attrname] = result |
The Other Jimmy |
36:96847d42f010 | 277 | return result |
The Other Jimmy |
36:96847d42f010 | 278 | |
The Other Jimmy |
36:96847d42f010 | 279 | @staticmethod |
The Other Jimmy |
36:96847d42f010 | 280 | @cached |
The Other Jimmy |
36:96847d42f010 | 281 | def get_target(target_name): |
The Other Jimmy |
36:96847d42f010 | 282 | """ Return the target instance starting from the target name """ |
The Other Jimmy |
36:96847d42f010 | 283 | return target(target_name, Target.get_json_target_data()) |
The Other Jimmy |
36:96847d42f010 | 284 | |
The Other Jimmy |
36:96847d42f010 | 285 | |
The Other Jimmy |
36:96847d42f010 | 286 | @property |
The Other Jimmy |
36:96847d42f010 | 287 | def program_cycle_s(self): |
The Other Jimmy |
36:96847d42f010 | 288 | """Special override for program_cycle_s as it's default value depends |
The Other Jimmy |
36:96847d42f010 | 289 | upon is_disk_virtual |
The Other Jimmy |
36:96847d42f010 | 290 | """ |
The Other Jimmy |
36:96847d42f010 | 291 | try: |
The Other Jimmy |
36:96847d42f010 | 292 | return self.__getattr__("program_cycle_s") |
The Other Jimmy |
36:96847d42f010 | 293 | except AttributeError: |
The Other Jimmy |
36:96847d42f010 | 294 | return 4 if self.is_disk_virtual else 1.5 |
The Other Jimmy |
36:96847d42f010 | 295 | |
The Other Jimmy |
36:96847d42f010 | 296 | @property |
The Other Jimmy |
36:96847d42f010 | 297 | def labels(self): |
The Other Jimmy |
36:96847d42f010 | 298 | """Get all possible labels for this target""" |
The Other Jimmy |
36:96847d42f010 | 299 | names = copy(self.resolution_order_names) |
The Other Jimmy |
36:96847d42f010 | 300 | if "Target" in names: |
The Other Jimmy |
36:96847d42f010 | 301 | names.remove("Target") |
The Other Jimmy |
36:96847d42f010 | 302 | labels = (names + CORE_LABELS[self.core] + self.extra_labels) |
The Other Jimmy |
36:96847d42f010 | 303 | # Automatically define UVISOR_UNSUPPORTED if the target doesn't |
The Other Jimmy |
36:96847d42f010 | 304 | # specifically define UVISOR_SUPPORTED |
The Other Jimmy |
36:96847d42f010 | 305 | if "UVISOR_SUPPORTED" not in labels: |
The Other Jimmy |
36:96847d42f010 | 306 | labels.append("UVISOR_UNSUPPORTED") |
The Other Jimmy |
36:96847d42f010 | 307 | return labels |
The Other Jimmy |
36:96847d42f010 | 308 | |
The Other Jimmy |
36:96847d42f010 | 309 | def init_hooks(self, hook, toolchain_name): |
The Other Jimmy |
36:96847d42f010 | 310 | """Initialize the post-build hooks for a toolchain. For now, this |
The Other Jimmy |
36:96847d42f010 | 311 | function only allows "post binary" hooks (hooks that are executed |
The Other Jimmy |
36:96847d42f010 | 312 | after the binary image is extracted from the executable file) |
The Other Jimmy |
36:96847d42f010 | 313 | """ |
The Other Jimmy |
36:96847d42f010 | 314 | |
The Other Jimmy |
36:96847d42f010 | 315 | # If there's no hook, simply return |
The Other Jimmy |
36:96847d42f010 | 316 | try: |
The Other Jimmy |
36:96847d42f010 | 317 | hook_data = self.post_binary_hook |
The Other Jimmy |
36:96847d42f010 | 318 | except AttributeError: |
The Other Jimmy |
36:96847d42f010 | 319 | return |
The Other Jimmy |
36:96847d42f010 | 320 | # A hook was found. The hook's name is in the format |
The Other Jimmy |
36:96847d42f010 | 321 | # "classname.functionname" |
The Other Jimmy |
36:96847d42f010 | 322 | temp = hook_data["function"].split(".") |
The Other Jimmy |
36:96847d42f010 | 323 | if len(temp) != 2: |
The Other Jimmy |
36:96847d42f010 | 324 | raise HookError( |
The Other Jimmy |
36:96847d42f010 | 325 | ("Invalid format for hook '%s' in target '%s'" |
The Other Jimmy |
36:96847d42f010 | 326 | % (hook_data["function"], self.name)) + |
The Other Jimmy |
36:96847d42f010 | 327 | " (must be 'class_name.function_name')") |
The Other Jimmy |
36:96847d42f010 | 328 | class_name, function_name = temp[0], temp[1] |
The Other Jimmy |
36:96847d42f010 | 329 | # "class_name" must refer to a class in this file, so check if the |
The Other Jimmy |
36:96847d42f010 | 330 | # class exists |
The Other Jimmy |
36:96847d42f010 | 331 | mdata = self.get_module_data() |
The Other Jimmy |
36:96847d42f010 | 332 | if not mdata.has_key(class_name) or \ |
The Other Jimmy |
36:96847d42f010 | 333 | not inspect.isclass(mdata[class_name]): |
The Other Jimmy |
36:96847d42f010 | 334 | raise HookError( |
The Other Jimmy |
36:96847d42f010 | 335 | ("Class '%s' required by '%s' in target '%s'" |
The Other Jimmy |
36:96847d42f010 | 336 | % (class_name, hook_data["function"], self.name)) + |
The Other Jimmy |
36:96847d42f010 | 337 | " not found in targets.py") |
The Other Jimmy |
36:96847d42f010 | 338 | # "function_name" must refer to a static function inside class |
The Other Jimmy |
36:96847d42f010 | 339 | # "class_name" |
The Other Jimmy |
36:96847d42f010 | 340 | cls = mdata[class_name] |
The Other Jimmy |
36:96847d42f010 | 341 | if (not hasattr(cls, function_name)) or \ |
The Other Jimmy |
36:96847d42f010 | 342 | (not inspect.isfunction(getattr(cls, function_name))): |
The Other Jimmy |
36:96847d42f010 | 343 | raise HookError( |
The Other Jimmy |
36:96847d42f010 | 344 | ("Static function '%s' " % function_name) + |
The Other Jimmy |
36:96847d42f010 | 345 | ("required by '%s' " % hook_data["function"]) + |
The Other Jimmy |
36:96847d42f010 | 346 | ("in target '%s' " % self.name) + |
The Other Jimmy |
36:96847d42f010 | 347 | ("not found in class '%s'" % class_name)) |
The Other Jimmy |
36:96847d42f010 | 348 | # Check if the hook specification also has target restrictions |
The Other Jimmy |
36:96847d42f010 | 349 | toolchain_restrictions = hook_data.get("toolchains", []) |
The Other Jimmy |
36:96847d42f010 | 350 | if toolchain_restrictions and \ |
The Other Jimmy |
36:96847d42f010 | 351 | (toolchain_name not in toolchain_restrictions): |
The Other Jimmy |
36:96847d42f010 | 352 | return |
The Other Jimmy |
36:96847d42f010 | 353 | # Finally, hook the requested function |
The Other Jimmy |
36:96847d42f010 | 354 | hook.hook_add_binary("post", getattr(cls, function_name)) |
The Other Jimmy |
36:96847d42f010 | 355 | |
The Other Jimmy |
36:96847d42f010 | 356 | ################################################################################ |
The Other Jimmy |
36:96847d42f010 | 357 | # Target specific code goes in this section |
The Other Jimmy |
36:96847d42f010 | 358 | # This code can be invoked from the target description using the |
The Other Jimmy |
36:96847d42f010 | 359 | # "post_binary_hook" key |
The Other Jimmy |
36:96847d42f010 | 360 | |
The Other Jimmy |
36:96847d42f010 | 361 | class LPCTargetCode(object): |
The Other Jimmy |
36:96847d42f010 | 362 | """General LPC Target patching code""" |
The Other Jimmy |
36:96847d42f010 | 363 | @staticmethod |
The Other Jimmy |
36:96847d42f010 | 364 | def lpc_patch(t_self, resources, elf, binf): |
The Other Jimmy |
36:96847d42f010 | 365 | """Patch an elf file""" |
The Other Jimmy |
36:96847d42f010 | 366 | t_self.debug("LPC Patch: %s" % os.path.split(binf)[1]) |
The Other Jimmy |
36:96847d42f010 | 367 | patch(binf) |
The Other Jimmy |
36:96847d42f010 | 368 | |
The Other Jimmy |
36:96847d42f010 | 369 | class LPC4088Code(object): |
The Other Jimmy |
36:96847d42f010 | 370 | """Code specific to the LPC4088""" |
The Other Jimmy |
36:96847d42f010 | 371 | @staticmethod |
The Other Jimmy |
36:96847d42f010 | 372 | def binary_hook(t_self, resources, elf, binf): |
The Other Jimmy |
36:96847d42f010 | 373 | """Hook to be run after an elf file is built""" |
The Other Jimmy |
36:96847d42f010 | 374 | if not os.path.isdir(binf): |
The Other Jimmy |
36:96847d42f010 | 375 | # Regular binary file, nothing to do |
The Other Jimmy |
36:96847d42f010 | 376 | LPCTargetCode.lpc_patch(t_self, resources, elf, binf) |
The Other Jimmy |
36:96847d42f010 | 377 | return |
The Other Jimmy |
36:96847d42f010 | 378 | outbin = open(binf + ".temp", "wb") |
The Other Jimmy |
36:96847d42f010 | 379 | partf = open(os.path.join(binf, "ER_IROM1"), "rb") |
The Other Jimmy |
36:96847d42f010 | 380 | # Pad the fist part (internal flash) with 0xFF to 512k |
The Other Jimmy |
36:96847d42f010 | 381 | data = partf.read() |
The Other Jimmy |
36:96847d42f010 | 382 | outbin.write(data) |
The Other Jimmy |
36:96847d42f010 | 383 | outbin.write('\xFF' * (512*1024 - len(data))) |
The Other Jimmy |
36:96847d42f010 | 384 | partf.close() |
The Other Jimmy |
36:96847d42f010 | 385 | # Read and append the second part (external flash) in chunks of fixed |
The Other Jimmy |
36:96847d42f010 | 386 | # size |
The Other Jimmy |
36:96847d42f010 | 387 | chunksize = 128 * 1024 |
The Other Jimmy |
36:96847d42f010 | 388 | partf = open(os.path.join(binf, "ER_IROM2"), "rb") |
The Other Jimmy |
36:96847d42f010 | 389 | while True: |
The Other Jimmy |
36:96847d42f010 | 390 | data = partf.read(chunksize) |
The Other Jimmy |
36:96847d42f010 | 391 | outbin.write(data) |
The Other Jimmy |
36:96847d42f010 | 392 | if len(data) < chunksize: |
The Other Jimmy |
36:96847d42f010 | 393 | break |
The Other Jimmy |
36:96847d42f010 | 394 | partf.close() |
The Other Jimmy |
36:96847d42f010 | 395 | outbin.close() |
The Other Jimmy |
36:96847d42f010 | 396 | # Remove the directory with the binary parts and rename the temporary |
The Other Jimmy |
36:96847d42f010 | 397 | # file to 'binf' |
The Other Jimmy |
36:96847d42f010 | 398 | shutil.rmtree(binf, True) |
The Other Jimmy |
36:96847d42f010 | 399 | os.rename(binf + '.temp', binf) |
The Other Jimmy |
36:96847d42f010 | 400 | t_self.debug("Generated custom binary file (internal flash + SPIFI)") |
The Other Jimmy |
36:96847d42f010 | 401 | LPCTargetCode.lpc_patch(t_self, resources, elf, binf) |
The Other Jimmy |
36:96847d42f010 | 402 | |
The Other Jimmy |
36:96847d42f010 | 403 | class TEENSY3_1Code(object): |
The Other Jimmy |
36:96847d42f010 | 404 | """Hooks for the TEENSY3.1""" |
The Other Jimmy |
36:96847d42f010 | 405 | @staticmethod |
The Other Jimmy |
36:96847d42f010 | 406 | def binary_hook(t_self, resources, elf, binf): |
The Other Jimmy |
36:96847d42f010 | 407 | """Hook that is run after elf is generated""" |
The Other Jimmy |
36:96847d42f010 | 408 | # This function is referenced by old versions of targets.json and should |
The Other Jimmy |
36:96847d42f010 | 409 | # be kept for backwards compatibility. |
The Other Jimmy |
36:96847d42f010 | 410 | pass |
The Other Jimmy |
36:96847d42f010 | 411 | |
The Other Jimmy |
36:96847d42f010 | 412 | class MTSCode(object): |
The Other Jimmy |
36:96847d42f010 | 413 | """Generic MTS code""" |
The Other Jimmy |
36:96847d42f010 | 414 | @staticmethod |
The Other Jimmy |
36:96847d42f010 | 415 | def _combine_bins_helper(target_name, binf): |
The Other Jimmy |
36:96847d42f010 | 416 | """combine bins with the bootloader for a particular target""" |
The Other Jimmy |
36:96847d42f010 | 417 | loader = os.path.join(TOOLS_BOOTLOADERS, target_name, "bootloader.bin") |
The Other Jimmy |
36:96847d42f010 | 418 | target = binf + ".tmp" |
The Other Jimmy |
36:96847d42f010 | 419 | if not os.path.exists(loader): |
The Other Jimmy |
36:96847d42f010 | 420 | print "Can't find bootloader binary: " + loader |
The Other Jimmy |
36:96847d42f010 | 421 | return |
The Other Jimmy |
36:96847d42f010 | 422 | outbin = open(target, 'w+b') |
The Other Jimmy |
36:96847d42f010 | 423 | part = open(loader, 'rb') |
The Other Jimmy |
36:96847d42f010 | 424 | data = part.read() |
The Other Jimmy |
36:96847d42f010 | 425 | outbin.write(data) |
The Other Jimmy |
36:96847d42f010 | 426 | outbin.write('\xFF' * (64*1024 - len(data))) |
The Other Jimmy |
36:96847d42f010 | 427 | part.close() |
The Other Jimmy |
36:96847d42f010 | 428 | part = open(binf, 'rb') |
The Other Jimmy |
36:96847d42f010 | 429 | data = part.read() |
The Other Jimmy |
36:96847d42f010 | 430 | outbin.write(data) |
The Other Jimmy |
36:96847d42f010 | 431 | part.close() |
The Other Jimmy |
36:96847d42f010 | 432 | outbin.seek(0, 0) |
The Other Jimmy |
36:96847d42f010 | 433 | data = outbin.read() |
The Other Jimmy |
36:96847d42f010 | 434 | outbin.seek(0, 1) |
The Other Jimmy |
36:96847d42f010 | 435 | crc = struct.pack('<I', binascii.crc32(data) & 0xFFFFFFFF) |
The Other Jimmy |
36:96847d42f010 | 436 | outbin.write(crc) |
The Other Jimmy |
36:96847d42f010 | 437 | outbin.close() |
The Other Jimmy |
36:96847d42f010 | 438 | os.remove(binf) |
The Other Jimmy |
36:96847d42f010 | 439 | os.rename(target, binf) |
The Other Jimmy |
36:96847d42f010 | 440 | |
The Other Jimmy |
36:96847d42f010 | 441 | @staticmethod |
The Other Jimmy |
36:96847d42f010 | 442 | def combine_bins_mts_dot(t_self, resources, elf, binf): |
The Other Jimmy |
36:96847d42f010 | 443 | """A hook for the MTS MDOT""" |
The Other Jimmy |
36:96847d42f010 | 444 | MTSCode._combine_bins_helper("MTS_MDOT_F411RE", binf) |
The Other Jimmy |
36:96847d42f010 | 445 | |
The Other Jimmy |
36:96847d42f010 | 446 | @staticmethod |
The Other Jimmy |
36:96847d42f010 | 447 | def combine_bins_mts_dragonfly(t_self, resources, elf, binf): |
The Other Jimmy |
36:96847d42f010 | 448 | """A hoof for the MTS Dragonfly""" |
The Other Jimmy |
36:96847d42f010 | 449 | MTSCode._combine_bins_helper("MTS_DRAGONFLY_F411RE", binf) |
The Other Jimmy |
36:96847d42f010 | 450 | |
The Other Jimmy |
36:96847d42f010 | 451 | class MCU_NRF51Code(object): |
The Other Jimmy |
36:96847d42f010 | 452 | """NRF51 Hooks""" |
The Other Jimmy |
36:96847d42f010 | 453 | @staticmethod |
The Other Jimmy |
36:96847d42f010 | 454 | def binary_hook(t_self, resources, _, binf): |
The Other Jimmy |
36:96847d42f010 | 455 | """Hook that merges the soft device with the bin file""" |
The Other Jimmy |
36:96847d42f010 | 456 | # Scan to find the actual paths of soft device |
The Other Jimmy |
36:96847d42f010 | 457 | sdf = None |
The Other Jimmy |
36:96847d42f010 | 458 | for softdevice_and_offset_entry\ |
The Other Jimmy |
36:96847d42f010 | 459 | in t_self.target.EXPECTED_SOFTDEVICES_WITH_OFFSETS: |
The Other Jimmy |
36:96847d42f010 | 460 | for hexf in resources.hex_files: |
The Other Jimmy |
36:96847d42f010 | 461 | if hexf.find(softdevice_and_offset_entry['name']) != -1: |
The Other Jimmy |
36:96847d42f010 | 462 | t_self.debug("SoftDevice file found %s." |
The Other Jimmy |
36:96847d42f010 | 463 | % softdevice_and_offset_entry['name']) |
The Other Jimmy |
36:96847d42f010 | 464 | sdf = hexf |
The Other Jimmy |
36:96847d42f010 | 465 | |
The Other Jimmy |
36:96847d42f010 | 466 | if sdf is not None: |
The Other Jimmy |
36:96847d42f010 | 467 | break |
The Other Jimmy |
36:96847d42f010 | 468 | if sdf is not None: |
The Other Jimmy |
36:96847d42f010 | 469 | break |
The Other Jimmy |
36:96847d42f010 | 470 | |
The Other Jimmy |
36:96847d42f010 | 471 | if sdf is None: |
The Other Jimmy |
36:96847d42f010 | 472 | t_self.debug("Hex file not found. Aborting.") |
The Other Jimmy |
36:96847d42f010 | 473 | return |
The Other Jimmy |
36:96847d42f010 | 474 | |
The Other Jimmy |
36:96847d42f010 | 475 | # Look for bootloader file that matches this soft device or bootloader |
The Other Jimmy |
36:96847d42f010 | 476 | # override image |
The Other Jimmy |
36:96847d42f010 | 477 | blf = None |
The Other Jimmy |
36:96847d42f010 | 478 | if t_self.target.MERGE_BOOTLOADER is True: |
The Other Jimmy |
36:96847d42f010 | 479 | for hexf in resources.hex_files: |
The Other Jimmy |
36:96847d42f010 | 480 | if hexf.find(t_self.target.OVERRIDE_BOOTLOADER_FILENAME) != -1: |
The Other Jimmy |
36:96847d42f010 | 481 | t_self.debug("Bootloader file found %s." |
The Other Jimmy |
36:96847d42f010 | 482 | % t_self.target.OVERRIDE_BOOTLOADER_FILENAME) |
The Other Jimmy |
36:96847d42f010 | 483 | blf = hexf |
The Other Jimmy |
36:96847d42f010 | 484 | break |
The Other Jimmy |
36:96847d42f010 | 485 | elif hexf.find(softdevice_and_offset_entry['boot']) != -1: |
The Other Jimmy |
36:96847d42f010 | 486 | t_self.debug("Bootloader file found %s." |
The Other Jimmy |
36:96847d42f010 | 487 | % softdevice_and_offset_entry['boot']) |
The Other Jimmy |
36:96847d42f010 | 488 | blf = hexf |
The Other Jimmy |
36:96847d42f010 | 489 | break |
The Other Jimmy |
36:96847d42f010 | 490 | |
The Other Jimmy |
36:96847d42f010 | 491 | # Merge user code with softdevice |
The Other Jimmy |
36:96847d42f010 | 492 | from intelhex import IntelHex |
The Other Jimmy |
36:96847d42f010 | 493 | binh = IntelHex() |
The Other Jimmy |
36:96847d42f010 | 494 | _, ext = os.path.splitext(binf) |
The Other Jimmy |
36:96847d42f010 | 495 | if ext == ".hex": |
The Other Jimmy |
36:96847d42f010 | 496 | binh.loadhex(binf) |
The Other Jimmy |
36:96847d42f010 | 497 | elif ext == ".bin": |
The Other Jimmy |
36:96847d42f010 | 498 | binh.loadbin(binf, softdevice_and_offset_entry['offset']) |
The Other Jimmy |
36:96847d42f010 | 499 | |
The Other Jimmy |
36:96847d42f010 | 500 | if t_self.target.MERGE_SOFT_DEVICE is True: |
The Other Jimmy |
36:96847d42f010 | 501 | t_self.debug("Merge SoftDevice file %s" |
The Other Jimmy |
36:96847d42f010 | 502 | % softdevice_and_offset_entry['name']) |
The Other Jimmy |
36:96847d42f010 | 503 | sdh = IntelHex(sdf) |
The Other Jimmy |
36:96847d42f010 | 504 | binh.merge(sdh) |
The Other Jimmy |
36:96847d42f010 | 505 | |
The Other Jimmy |
36:96847d42f010 | 506 | if t_self.target.MERGE_BOOTLOADER is True and blf is not None: |
The Other Jimmy |
36:96847d42f010 | 507 | t_self.debug("Merge BootLoader file %s" % blf) |
The Other Jimmy |
36:96847d42f010 | 508 | blh = IntelHex(blf) |
The Other Jimmy |
36:96847d42f010 | 509 | binh.merge(blh) |
The Other Jimmy |
36:96847d42f010 | 510 | |
The Other Jimmy |
36:96847d42f010 | 511 | with open(binf.replace(".bin", ".hex"), "w") as fileout: |
The Other Jimmy |
36:96847d42f010 | 512 | binh.write_hex_file(fileout, write_start_addr=False) |
The Other Jimmy |
36:96847d42f010 | 513 | |
The Other Jimmy |
36:96847d42f010 | 514 | class NCS36510TargetCode: |
The Other Jimmy |
36:96847d42f010 | 515 | @staticmethod |
The Other Jimmy |
36:96847d42f010 | 516 | def ncs36510_addfib(t_self, resources, elf, binf): |
The Other Jimmy |
36:96847d42f010 | 517 | from tools.targets.NCS import add_fib_at_start |
The Other Jimmy |
36:96847d42f010 | 518 | print("binf ", binf) |
The Other Jimmy |
36:96847d42f010 | 519 | add_fib_at_start(binf[:-4]) |
The Other Jimmy |
36:96847d42f010 | 520 | |
The Other Jimmy |
36:96847d42f010 | 521 | class RTL8195ACode: |
The Other Jimmy |
36:96847d42f010 | 522 | """RTL8195A Hooks""" |
The Other Jimmy |
36:96847d42f010 | 523 | @staticmethod |
The Other Jimmy |
36:96847d42f010 | 524 | def binary_hook(t_self, resources, elf, binf): |
The Other Jimmy |
36:96847d42f010 | 525 | from tools.targets.REALTEK_RTL8195AM import rtl8195a_elf2bin |
The Other Jimmy |
36:96847d42f010 | 526 | rtl8195a_elf2bin(t_self.name, elf, binf) |
The Other Jimmy |
36:96847d42f010 | 527 | ################################################################################ |
The Other Jimmy |
36:96847d42f010 | 528 | |
The Other Jimmy |
36:96847d42f010 | 529 | # Instantiate all public targets |
The Other Jimmy |
38:399953da035d | 530 | def update_target_data(): |
The Other Jimmy |
38:399953da035d | 531 | TARGETS[:] = [Target.get_target(tgt) for tgt, obj |
The Other Jimmy |
38:399953da035d | 532 | in Target.get_json_target_data().items() |
The Other Jimmy |
38:399953da035d | 533 | if obj.get("public", True)] |
The Other Jimmy |
38:399953da035d | 534 | # Map each target name to its unique instance |
The Other Jimmy |
38:399953da035d | 535 | TARGET_MAP.clear() |
The Other Jimmy |
38:399953da035d | 536 | TARGET_MAP.update(dict([(tgt.name, tgt) for tgt in TARGETS])) |
The Other Jimmy |
38:399953da035d | 537 | TARGET_NAMES[:] = TARGET_MAP.keys() |
The Other Jimmy |
36:96847d42f010 | 538 | |
The Other Jimmy |
38:399953da035d | 539 | TARGETS = [] |
The Other Jimmy |
38:399953da035d | 540 | TARGET_MAP = dict() |
The Other Jimmy |
38:399953da035d | 541 | TARGET_NAMES = [] |
The Other Jimmy |
36:96847d42f010 | 542 | |
The Other Jimmy |
38:399953da035d | 543 | update_target_data() |
The Other Jimmy |
36:96847d42f010 | 544 | |
The Other Jimmy |
36:96847d42f010 | 545 | # Some targets with different name have the same exporters |
The Other Jimmy |
36:96847d42f010 | 546 | EXPORT_MAP = {} |
The Other Jimmy |
36:96847d42f010 | 547 | |
The Other Jimmy |
36:96847d42f010 | 548 | # Detection APIs |
The Other Jimmy |
36:96847d42f010 | 549 | def get_target_detect_codes(): |
The Other Jimmy |
36:96847d42f010 | 550 | """ Returns dictionary mapping detect_code -> platform_name |
The Other Jimmy |
36:96847d42f010 | 551 | """ |
The Other Jimmy |
36:96847d42f010 | 552 | result = {} |
The Other Jimmy |
36:96847d42f010 | 553 | for tgt in TARGETS: |
The Other Jimmy |
36:96847d42f010 | 554 | for detect_code in tgt.detect_code: |
The Other Jimmy |
36:96847d42f010 | 555 | result[detect_code] = tgt.name |
The Other Jimmy |
36:96847d42f010 | 556 | return result |
The Other Jimmy |
36:96847d42f010 | 557 | |
The Other Jimmy |
36:96847d42f010 | 558 | def set_targets_json_location(location=None): |
The Other Jimmy |
36:96847d42f010 | 559 | """Sets the location of the JSON file that contains the targets""" |
The Other Jimmy |
36:96847d42f010 | 560 | # First instruct Target about the new location |
The Other Jimmy |
36:96847d42f010 | 561 | Target.set_targets_json_location(location) |
The Other Jimmy |
36:96847d42f010 | 562 | # Then re-initialize TARGETS, TARGET_MAP and TARGET_NAMES. The |
The Other Jimmy |
36:96847d42f010 | 563 | # re-initialization does not create new variables, it keeps the old ones |
The Other Jimmy |
36:96847d42f010 | 564 | # instead. This ensures compatibility with code that does |
The Other Jimmy |
36:96847d42f010 | 565 | # "from tools.targets import TARGET_NAMES" |
The Other Jimmy |
38:399953da035d | 566 | update_target_data() |
The Other Jimmy |
38:399953da035d | 567 |