ON Semiconductor / mbed-os

Dependents:   mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers __init__.py Source File

__init__.py

00001 import os
00002 from os.path import sep, join, exists
00003 from collections import namedtuple
00004 from subprocess import Popen, PIPE
00005 import shutil
00006 import re
00007 import sys
00008 
00009 from tools.targets import TARGET_MAP
00010 from tools.export.exporters import Exporter, TargetNotSupportedException
00011 import json
00012 from tools.export.cmsis import DeviceCMSIS
00013 from multiprocessing import cpu_count
00014 
00015 class IAR(Exporter):
00016     NAME = 'iar'
00017     TOOLCHAIN = 'IAR'
00018 
00019     #iar_definitions.json location
00020     def_loc = os.path.join(
00021         os.path.dirname(os.path.abspath(__file__)), '..', '..', '..',
00022         'tools','export', 'iar', 'iar_definitions.json')
00023 
00024     #create a dictionary of the definitions
00025     with open(def_loc, 'r') as f:
00026         IAR_DEFS = json.load(f)
00027 
00028     #supported targets have a device name and corresponding definition in
00029     #iar_definitions.json
00030     TARGETS = [target for target, obj in TARGET_MAP.iteritems()
00031                if hasattr(obj, 'device_name') and
00032                obj.device_name in IAR_DEFS.keys() and "IAR" in obj.supported_toolchains]
00033 
00034     def iar_groups(self, grouped_src):
00035         """Return a namedtuple of group info
00036         Positional Arguments:
00037         grouped_src: dictionary mapping a group(str) to sources
00038             within it (list of file names)
00039         Relevant part of IAR template
00040         {% for group in groups %}
00041         <group>
00042             <name>group.name</name>
00043             {% for file in group.files %}
00044             <file>
00045             <name>$PROJ_DIR${{file}}</name>
00046             </file>
00047             {% endfor %}
00048         </group>
00049         {% endfor %}
00050         """
00051         IARgroup = namedtuple('IARgroup', ['name','files'])
00052         groups = []
00053         for name, files in grouped_src.items():
00054             groups.append(IARgroup(name,files))
00055         return groups
00056 
00057     def iar_device(self):
00058         """Retrieve info from iar_definitions.json"""
00059         device_name =  TARGET_MAP[self.target].device_name
00060         device_info = self.IAR_DEFS[device_name]
00061         iar_defaults ={
00062             "OGChipSelectEditMenu": "",
00063             "CoreVariant": '',
00064             "GFPUCoreSlave": '',
00065             "GFPUCoreSlave2": 40,
00066             "GBECoreSlave": 35,
00067             "FPU2": 0,
00068             "NrRegs": 0,
00069         }
00070 
00071         iar_defaults.update(device_info)
00072         IARdevice = namedtuple('IARdevice', iar_defaults.keys())
00073         return IARdevice(**iar_defaults)
00074 
00075     def format_file(self, file):
00076         """Make IAR compatible path"""
00077         return join('$PROJ_DIR$',file)
00078 
00079     def format_src(self, srcs):
00080         """Group source files"""
00081         grouped = self.group_project_files(srcs)
00082         for group, files in grouped.items():
00083             grouped[group] = [self.format_file(src) for src in files]
00084         return grouped
00085 
00086     def generate(self):
00087         """Generate the .eww, .ewd, and .ewp files"""
00088         srcs = self.resources.headers + self.resources.s_sources + \
00089                self.resources.c_sources + self.resources.cpp_sources + \
00090                self.resources.objects + self.resources.libraries
00091         flags = self.flags
00092         c_flags = list(set(flags['common_flags']
00093                                     + flags['c_flags']
00094                                     + flags['cxx_flags']))
00095         # Flags set in template to be set by user in IDE
00096         template = ["--vla", "--no_static_destruction"]
00097         # Flag invalid if set in template
00098         # Optimizations are also set in template
00099         invalid_flag = lambda x: x in template or re.match("-O(\d|time|n)", x)
00100         flags['c_flags'] = [flag for flag in c_flags if not invalid_flag(flag)]
00101 
00102         try:
00103             debugger = DeviceCMSIS(self.target).debug.replace('-','').upper()
00104         except TargetNotSupportedException:
00105             debugger = "CMSISDAP"
00106 
00107         ctx = {
00108             'name': self.project_name,
00109             'groups': self.iar_groups(self.format_src(srcs)),
00110             'linker_script': self.format_file(self.resources.linker_script),
00111             'include_paths': [self.format_file(src) for src in self.resources.inc_dirs],
00112             'device': self.iar_device(),
00113             'ewp': sep+self.project_name + ".ewp",
00114             'debugger': debugger
00115         }
00116         ctx.update(flags)
00117 
00118         self.gen_file('iar/eww.tmpl', ctx, self.project_name + ".eww")
00119         self.gen_file('iar/ewd.tmpl', ctx, self.project_name + ".ewd")
00120         self.gen_file('iar/ewp.tmpl', ctx, self.project_name + ".ewp")
00121 
00122     @staticmethod
00123     def build(project_name, log_name="build_log.txt", cleanup=True):
00124         """ Build IAR project """
00125         # > IarBuild [project_path] -build [project_name]
00126         proj_file = project_name + ".ewp"
00127         cmd = ["IarBuild", proj_file, '-build', project_name]
00128 
00129         # IAR does not support a '0' option to automatically use all
00130         # available CPUs, so we use Python's multiprocessing library
00131         # to detect the number of CPUs available
00132         cpus_available = cpu_count()
00133         jobs = cpus_available if cpus_available else None
00134 
00135         # Only add the parallel flag if we're using more than one CPU
00136         if jobs:
00137             cmd += ['-parallel', str(jobs)]
00138 
00139         # Build the project
00140         p = Popen(cmd, stdout=PIPE, stderr=PIPE)
00141         out, err = p.communicate()
00142         ret_code = p.returncode
00143 
00144         out_string = "=" * 10 + "STDOUT" + "=" * 10 + "\n"
00145         out_string += out
00146         out_string += "=" * 10 + "STDERR" + "=" * 10 + "\n"
00147         out_string += err
00148 
00149         if ret_code == 0:
00150             out_string += "SUCCESS"
00151         else:
00152             out_string += "FAILURE"
00153 
00154         print out_string
00155 
00156         if log_name:
00157             # Write the output to the log file
00158             with open(log_name, 'w+') as f:
00159                 f.write(out_string)
00160 
00161         # Cleanup the exported and built files
00162         if cleanup:
00163             os.remove(project_name + ".ewp")
00164             os.remove(project_name + ".ewd")
00165             os.remove(project_name + ".eww")
00166             # legacy output file location
00167             if exists('.build'):
00168                 shutil.rmtree('.build')
00169             if exists('BUILD'):
00170                 shutil.rmtree('BUILD')
00171 
00172         if ret_code !=0:
00173             # Seems like something went wrong.
00174             return -1
00175         else:
00176             return 0