takashi kadono / Mbed OS Nucleo446_SSD1331

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Wed Oct 10 00:33:53 2018 +0000
Revision:
0:8fdf9a60065b
how to make mbed librry

Who changed what in which revision?

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