def is_target_supported(cls, target_name): target = TARGET_MAP[target_name] if not target.is_TFM_target: if int(target.build_tools_metadata["version"]) > 0: if not len( set(target.supported_toolchains).intersection( set(["ARM", "ARMC6"]))) > 0: return False else: if "ARMC6" not in target.supported_toolchains: return False if not DeviceCMSIS.check_supported(target_name): return False if "Cortex-A" in target.core: return False if not hasattr(target, "post_binary_hook"): return True if target.post_binary_hook[ 'function'] in cls.POST_BINARY_WHITELIST: return True else: return False else: return False
def is_target_supported(cls, target_name): target = TARGET_MAP[target_name] if not target.is_TFM_target: if int(target.build_tools_metadata["version"]) > 0: # Just check for ARMC5 as ARMC5 must be there irrespective of whether uARM is there or not if the target is staying with ARMC5 if "ARMC5" not in target.supported_toolchains: return False else: if not (set(target.supported_toolchains).intersection( set(["ARM", "uARM"]))): return False if not DeviceCMSIS.check_supported(target_name): return False if "Cortex-A" in target.core: return False if not hasattr(target, "post_binary_hook"): return True if target.post_binary_hook[ 'function'] in cls.POST_BINARY_WHITELIST: return True else: return False else: return False
def is_target_supported(cls, target_name): target = TARGET_MAP[target_name] if not (set(target.supported_toolchains).intersection(set(["ARMC6"]))): return False if not DeviceCMSIS.check_supported(target_name): return False if "Cortex-A" in target.core: return False if not hasattr(target, "post_binary_hook"): return True if target.post_binary_hook['function'] in cls.POST_BINARY_WHITELIST: return True else: return False
def is_target_supported(cls, target_name): target = TARGET_MAP[target_name] if not (set(target.supported_toolchains) and set(["ARM", "uARM"])): return False if not DeviceCMSIS.check_supported(target_name): return False if "Cortex-A" in target.core: return False if not hasattr(target, "post_binary_hook"): return True if target.post_binary_hook['function'] in cls.POST_BINARY_WHITELIST: return True else: return False
class IAR(Exporter): NAME = 'iar' TOOLCHAIN = 'IAR' #iar_definitions.json location def_loc = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..', '..', 'tools', 'export', 'iar', 'iar_definitions.json') #create a dictionary of the definitions with open(def_loc, 'r') as f: IAR_DEFS = json.load(f) #supported targets have a device name and corresponding definition in #iar_definitions.json TARGETS = [ target for target, obj in TARGET_MAP.iteritems() if hasattr(obj, 'device_name') and obj.device_name in IAR_DEFS.keys() and "IAR" in obj.supported_toolchains and DeviceCMSIS.check_supported(target) ] SPECIAL_TEMPLATES = { 'rz_a1h': 'iar/iar_rz_a1h.ewp.tmpl', 'nucleo_f746zg': 'iar/iar_nucleo_f746zg.ewp.tmpl' } def iar_groups(self, grouped_src): """Return a namedtuple of group info Positional Arguments: grouped_src: dictionary mapping a group(str) to sources within it (list of file names) Relevant part of IAR template {% for group in groups %} <group> <name>group.name</name> {% for file in group.files %} <file> <name>$PROJ_DIR${{file}}</name> </file> {% endfor %} </group> {% endfor %} """ IARgroup = namedtuple('IARgroup', ['name', 'files']) groups = [] for name, files in grouped_src.items(): groups.append(IARgroup(name, files)) return groups def iar_device(self): """Retrieve info from iar_definitions.json""" device_name = TARGET_MAP[self.target].device_name device_info = self.IAR_DEFS[device_name] iar_defaults = { "OGChipSelectEditMenu": "", "CoreVariant": '', "GFPUCoreSlave": '', "GFPUCoreSlave2": 40, "GBECoreSlave": 35 } iar_defaults.update(device_info) IARdevice = namedtuple('IARdevice', iar_defaults.keys()) return IARdevice(**iar_defaults) def format_file(self, file): """Make IAR compatible path""" return join('$PROJ_DIR$', file) def format_src(self, srcs): """Group source files""" grouped = self.group_project_files(srcs) for group, files in grouped.items(): grouped[group] = [self.format_file(src) for src in files] return grouped def get_ewp_template(self): return self.SPECIAL_TEMPLATES.get(self.target.lower(), 'iar/ewp.tmpl') def generate(self): """Generate the .eww, .ewd, and .ewp files""" srcs = self.resources.headers + self.resources.s_sources + \ self.resources.c_sources + self.resources.cpp_sources + \ self.resources.objects + self.resources.libraries flags = self.flags flags['c_flags'] = list( set(flags['common_flags'] + flags['c_flags'] + flags['cxx_flags'])) if '--vla' in flags['c_flags']: flags['c_flags'].remove('--vla') if '--no_static_destruction' in flags['c_flags']: flags['c_flags'].remove('--no_static_destruction') #Optimizations if '-Oh' in flags['c_flags']: flags['c_flags'].remove('-Oh') ctx = { 'name': self.project_name, 'groups': self.iar_groups(self.format_src(srcs)), 'linker_script': self.format_file(self.resources.linker_script), 'include_paths': [self.format_file(src) for src in self.resources.inc_dirs], 'device': self.iar_device(), 'ewp': sep + self.project_name + ".ewp", 'debugger': DeviceCMSIS(self.target).debug.replace('-', '').upper() } ctx.update(flags) self.gen_file('iar/eww.tmpl', ctx, self.project_name + ".eww") self.gen_file('iar/ewd.tmpl', ctx, self.project_name + ".ewd") self.gen_file(self.get_ewp_template(), ctx, self.project_name + ".ewp") @staticmethod def build(project_name, log_name="build_log.txt", cleanup=True): """ Build IAR project """ # > IarBuild [project_path] -build [project_name] proj_file = project_name + ".ewp" cmd = ["IarBuild", proj_file, '-build', project_name] # IAR does not support a '0' option to automatically use all # available CPUs, so we use Python's multiprocessing library # to detect the number of CPUs available cpus_available = cpu_count() jobs = cpus_available if cpus_available else None # Only add the parallel flag if we're using more than one CPU if jobs: cmd += ['-parallel', str(jobs)] # Build the project p = Popen(cmd, stdout=PIPE, stderr=PIPE) out, err = p.communicate() ret_code = p.returncode out_string = "=" * 10 + "STDOUT" + "=" * 10 + "\n" out_string += out out_string += "=" * 10 + "STDERR" + "=" * 10 + "\n" out_string += err if ret_code == 0: out_string += "SUCCESS" else: out_string += "FAILURE" print out_string if log_name: # Write the output to the log file with open(log_name, 'w+') as f: f.write(out_string) # Cleanup the exported and built files if cleanup: os.remove(project_name + ".ewp") os.remove(project_name + ".ewd") os.remove(project_name + ".eww") # legacy output file location if exists('.build'): shutil.rmtree('.build') if exists('BUILD'): shutil.rmtree('BUILD') if ret_code != 0: # Seems like something went wrong. return -1 else: return 0
def is_target_supported(cls, target_name): target = TARGET_MAP[target_name] return apply_supported_whitelist( cls.TOOLCHAIN, cls.POST_BINARY_WHITELIST, target) and\ DeviceCMSIS.check_supported(target_name)
class Uvision(Exporter): """Keil Uvision class This class encapsulates information to be contained in a Uvision project file (.uvprojx). The needed information can be viewed in uvision.tmpl """ NAME = 'uvision5' TOOLCHAIN = 'ARM' POST_BINARY_WHITELIST = set([ "MCU_NRF51Code.binary_hook", "TEENSY3_1Code.binary_hook", "LPCTargetCode.lpc_patch", "LPC4088Code.binary_hook", "MTSCode.combine_bins_mts_dot", "MTSCode.combine_bins_mts_dragonfly", "NCS36510TargetCode.ncs36510_addfib" ]) TARGETS = [tgt for tgt in filter_supported("ARM", POST_BINARY_WHITELIST) if DeviceCMSIS.check_supported(tgt)] #File associations within .uvprojx file file_types = {'.cpp': 8, '.c': 1, '.s': 2, '.obj': 3, '.o': 3, '.lib': 4, '.ar': 4, '.h': 5, '.hpp': 5, '.sct': 4} def uv_files(self, files): """An generator containing Uvision specific information about project files Positional Arguments: files - the location of source files .uvprojx XML for project file: <File> <FileType>{{file.type}}</FileType> <FileName>{{file.name}}</FileName> <FilePath>{{file.loc}}</FilePath> </File> """ for loc in files: #Encapsulates the information necessary for template entry above UVFile = namedtuple('UVFile', ['type','loc','name']) _, ext = os.path.splitext(loc) if ext.lower() in self.file_types: type = self.file_types[ext.lower()] name = ntpath.basename(normpath(loc)) yield UVFile(type, loc, name) def format_flags(self): """Format toolchain flags for Uvision""" flags = copy.deepcopy(self.flags) # to be preprocessed with armcc asm_flag_string = '--cpreproc --cpreproc_opts=-D__ASSERT_MSG,' + \ ",".join(flags['asm_flags']) flags['asm_flags'] = asm_flag_string # All non-asm flags are in one template field c_flags = list(set(flags['c_flags'] + flags['cxx_flags'] +flags['common_flags'])) # These flags are in template to be set by user i n IDE template = ["--no_vla", "--cpp", "--c99"] # Flag is invalid if set in template # Optimizations are also set in the template invalid_flag = lambda x: x in template or re.match("-O(\d|time)", x) flags['c_flags'] = [flag.replace('"','\\"') for flag in c_flags if not invalid_flag(flag)] flags['c_flags'] = " ".join(flags['c_flags']) return flags def format_src(self, srcs): """Make sources into the named tuple for use in the template""" grouped = self.group_project_files(srcs) for group, files in grouped.items(): grouped[group] = sorted(list(self.uv_files(files)), key=lambda (_, __, name): name.lower()) return grouped @staticmethod def format_fpu(core): """Generate a core's FPU string""" if core.endswith("FD"): return "FPU3(DFPU)" elif core.endswith("F"): return "FPU2" else: return "" def generate(self): """Generate the .uvproj file""" cache = Cache(True, False) if cache_d: cache.cache_descriptors() srcs = self.resources.headers + self.resources.s_sources + \ self.resources.c_sources + self.resources.cpp_sources + \ self.resources.objects + self.resources.libraries ctx = { 'name': self.project_name, # project_files => dict of generators - file group to generator of # UVFile tuples defined above 'project_files': sorted(list(self.format_src(srcs).iteritems()), key=lambda (group, _): group.lower()), 'linker_script':self.resources.linker_script, 'include_paths': '; '.join(self.resources.inc_dirs).encode('utf-8'), 'device': DeviceUvision(self.target), } core = ctx['device'].core ctx['cputype'] = core.rstrip("FD") if core.endswith("FD"): ctx['fpu_setting'] = 3 elif core.endswith("F"): ctx['fpu_setting'] = 2 else: ctx['fpu_setting'] = 1 ctx['fputype'] = self.format_fpu(core) ctx.update(self.format_flags()) self.gen_file('uvision/uvision.tmpl', ctx, self.project_name+".uvprojx") self.gen_file('uvision/uvision_debug.tmpl', ctx, self.project_name + ".uvoptx") @staticmethod def build(project_name, log_name='build_log.txt', cleanup=True): """ Build Uvision project """ # > UV4 -r -j0 -o [log_name] [project_name].uvprojx proj_file = project_name + ".uvprojx" cmd = ['UV4', '-r', '-j0', '-o', log_name, proj_file] # Build the project p = Popen(cmd, stdout=PIPE, stderr=PIPE) out, err = p.communicate() ret_code = p.returncode # Print the log file to stdout with open(log_name, 'r') as f: print f.read() # Cleanup the exported and built files if cleanup: os.remove(log_name) os.remove(project_name+".uvprojx") os.remove(project_name+".uvoptx") # legacy .build directory cleaned if exists if exists('.build'): shutil.rmtree('.build') if exists('BUILD'): shutil.rmtree('BUILD') # Returns 0 upon success, 1 upon a warning, and neither upon an error if ret_code != 0 and ret_code != 1: # Seems like something went wrong. return -1 else: return 0
class Uvision(Exporter): """Keil Uvision class This class encapsulates information to be contained in a Uvision project file (.uvprojx). The needed information can be viewed in uvision.tmpl """ NAME = 'uvision5' TOOLCHAIN = 'ARM' TARGETS = [] for target, obj in TARGET_MAP.iteritems(): if not ("ARM" in obj.supported_toolchains and hasattr(obj, "device_name")): continue if not DeviceCMSIS.check_supported(target): continue TARGETS.append(target) #File associations within .uvprojx file file_types = { '.cpp': 8, '.c': 1, '.s': 2, '.obj': 3, '.o': 3, '.lib': 4, '.ar': 4, '.h': 5, '.hpp': 5, '.sct': 4 } def uv_file(self, loc): """Return a namedtuple of information about project file Positional Arguments: loc - the file's location .uvprojx XML for project file: <File> <FileType>{{file.type}}</FileType> <FileName>{{file.name}}</FileName> <FilePath>{{file.loc}}</FilePath> </File> """ UVFile = namedtuple('UVFile', ['type', 'loc', 'name']) _, ext = os.path.splitext(loc) type = self.file_types[ext.lower()] name = ntpath.basename(normpath(loc)) return UVFile(type, loc, name) def format_flags(self): """Format toolchain flags for Uvision""" flags = copy.deepcopy(self.flags) asm_flag_string = '--cpreproc --cpreproc_opts=-D__ASSERT_MSG,' + \ ",".join(flags['asm_flags']) # asm flags only, common are not valid within uvision project, # they are armcc specific flags['asm_flags'] = asm_flag_string # cxx flags included, as uvision have them all in one tab flags['c_flags'] = list( set(['-D__ASSERT_MSG'] + flags['common_flags'] + flags['c_flags'] + flags['cxx_flags'])) # not compatible with c99 flag set in the template try: flags['c_flags'].remove("--c99") except ValueError: pass # cpp is not required as it's implicit for cpp files try: flags['c_flags'].remove("--cpp") except ValueError: pass # we want no-vla for only cxx, but it's also applied for C in IDE, # thus we remove it try: flags['c_flags'].remove("--no_vla") except ValueError: pass flags['c_flags'] = " ".join(flags['c_flags']) return flags def format_src(self, srcs): """Make sources into the named tuple for use in the template""" grouped = self.group_project_files(srcs) for group, files in grouped.items(): grouped[group] = [self.uv_file(src) for src in files] return grouped def generate(self): """Generate the .uvproj file""" cache = Cache(True, False) if cache_d: cache.cache_descriptors() srcs = self.resources.headers + self.resources.s_sources + \ self.resources.c_sources + self.resources.cpp_sources + \ self.resources.objects + self.resources.libraries ctx = { 'name': self.project_name, 'project_files': self.format_src(srcs), 'linker_script': self.resources.linker_script, 'include_paths': '; '.join(self.resources.inc_dirs).encode('utf-8'), 'device': DeviceUvision(self.target), } # Turn on FPU optimizations if the core has an FPU ctx['fpu_setting'] = 1 if 'f' not in ctx['device'].core.lower() \ or 'd' in ctx['device'].core.lower() else 2 ctx.update(self.format_flags()) self.gen_file('uvision/uvision.tmpl', ctx, self.project_name + ".uvprojx") self.gen_file('uvision/uvision_debug.tmpl', ctx, self.project_name + ".uvoptx") @staticmethod def build(project_name, log_name='build_log.txt', cleanup=True): """ Build Uvision project """ # > UV4 -r -j0 -o [log_name] [project_name].uvprojx proj_file = project_name + ".uvprojx" cmd = ['UV4', '-r', '-j0', '-o', log_name, proj_file] # Build the project p = Popen(cmd, stdout=PIPE, stderr=PIPE) out, err = p.communicate() ret_code = p.returncode # Print the log file to stdout with open(log_name, 'r') as f: print f.read() # Cleanup the exported and built files if cleanup: os.remove(log_name) os.remove(project_name + ".uvprojx") os.remove(project_name + ".uvoptx") # legacy .build directory cleaned if exists if exists('.build'): shutil.rmtree('.build') if exists('BUILD'): shutil.rmtree('BUILD') # Returns 0 upon success, 1 upon a warning, and neither upon an error if ret_code != 0 and ret_code != 1: # Seems like something went wrong. return -1 else: return 0