mbed-os

Dependents:   cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more

Committer:
be_bryan
Date:
Mon Dec 11 17:54:04 2017 +0000
Revision:
0:b74591d5ab33
motor ++

Who changed what in which revision?

UserRevisionLine numberNew contents of line
be_bryan 0:b74591d5ab33 1 import os
be_bryan 0:b74591d5ab33 2 from os.path import sep, join, exists
be_bryan 0:b74591d5ab33 3 from collections import namedtuple
be_bryan 0:b74591d5ab33 4 from subprocess import Popen, PIPE
be_bryan 0:b74591d5ab33 5 import shutil
be_bryan 0:b74591d5ab33 6 import re
be_bryan 0:b74591d5ab33 7 import sys
be_bryan 0:b74591d5ab33 8
be_bryan 0:b74591d5ab33 9 from tools.targets import TARGET_MAP
be_bryan 0:b74591d5ab33 10 from tools.export.exporters import Exporter, TargetNotSupportedException
be_bryan 0:b74591d5ab33 11 import json
be_bryan 0:b74591d5ab33 12 from tools.export.cmsis import DeviceCMSIS
be_bryan 0:b74591d5ab33 13 from tools.utils import NotSupportedException
be_bryan 0:b74591d5ab33 14 from multiprocessing import cpu_count
be_bryan 0:b74591d5ab33 15
be_bryan 0:b74591d5ab33 16
be_bryan 0:b74591d5ab33 17 def _supported(mcu, iar_targets):
be_bryan 0:b74591d5ab33 18 if "IAR" not in mcu.supported_toolchains:
be_bryan 0:b74591d5ab33 19 return False
be_bryan 0:b74591d5ab33 20 if hasattr(mcu, 'device_name') and mcu.device_name in iar_targets:
be_bryan 0:b74591d5ab33 21 return True
be_bryan 0:b74591d5ab33 22 if mcu.name in iar_targets:
be_bryan 0:b74591d5ab33 23 return True
be_bryan 0:b74591d5ab33 24 return False
be_bryan 0:b74591d5ab33 25
be_bryan 0:b74591d5ab33 26
be_bryan 0:b74591d5ab33 27 _iar_defs = os.path.join(
be_bryan 0:b74591d5ab33 28 os.path.dirname(os.path.abspath(__file__)), 'iar_definitions.json')
be_bryan 0:b74591d5ab33 29
be_bryan 0:b74591d5ab33 30 with open(_iar_defs, 'r') as f:
be_bryan 0:b74591d5ab33 31 _GUI_OPTIONS = json.load(f)
be_bryan 0:b74591d5ab33 32
be_bryan 0:b74591d5ab33 33
be_bryan 0:b74591d5ab33 34 class IAR(Exporter):
be_bryan 0:b74591d5ab33 35 NAME = 'iar'
be_bryan 0:b74591d5ab33 36 TOOLCHAIN = 'IAR'
be_bryan 0:b74591d5ab33 37
be_bryan 0:b74591d5ab33 38 @classmethod
be_bryan 0:b74591d5ab33 39 def is_target_supported(cls, target_name):
be_bryan 0:b74591d5ab33 40 target = TARGET_MAP[target_name]
be_bryan 0:b74591d5ab33 41 return _supported(target, _GUI_OPTIONS.keys())
be_bryan 0:b74591d5ab33 42
be_bryan 0:b74591d5ab33 43
be_bryan 0:b74591d5ab33 44 def iar_groups(self, grouped_src):
be_bryan 0:b74591d5ab33 45 """Return a namedtuple of group info
be_bryan 0:b74591d5ab33 46 Positional Arguments:
be_bryan 0:b74591d5ab33 47 grouped_src: dictionary mapping a group(str) to sources
be_bryan 0:b74591d5ab33 48 within it (list of file names)
be_bryan 0:b74591d5ab33 49 Relevant part of IAR template
be_bryan 0:b74591d5ab33 50 {% for group in groups %}
be_bryan 0:b74591d5ab33 51 <group>
be_bryan 0:b74591d5ab33 52 <name>group.name</name>
be_bryan 0:b74591d5ab33 53 {% for file in group.files %}
be_bryan 0:b74591d5ab33 54 <file>
be_bryan 0:b74591d5ab33 55 <name>$PROJ_DIR${{file}}</name>
be_bryan 0:b74591d5ab33 56 </file>
be_bryan 0:b74591d5ab33 57 {% endfor %}
be_bryan 0:b74591d5ab33 58 </group>
be_bryan 0:b74591d5ab33 59 {% endfor %}
be_bryan 0:b74591d5ab33 60 """
be_bryan 0:b74591d5ab33 61 IARgroup = namedtuple('IARgroup', ['name','files'])
be_bryan 0:b74591d5ab33 62 groups = []
be_bryan 0:b74591d5ab33 63 for name, files in grouped_src.items():
be_bryan 0:b74591d5ab33 64 groups.append(IARgroup(name,files))
be_bryan 0:b74591d5ab33 65 return groups
be_bryan 0:b74591d5ab33 66
be_bryan 0:b74591d5ab33 67 def iar_device(self):
be_bryan 0:b74591d5ab33 68 """Retrieve info from iar_definitions.json"""
be_bryan 0:b74591d5ab33 69 tgt = TARGET_MAP[self.target]
be_bryan 0:b74591d5ab33 70 device_name = (tgt.device_name if hasattr(tgt, "device_name") else
be_bryan 0:b74591d5ab33 71 tgt.name)
be_bryan 0:b74591d5ab33 72 device_info = _GUI_OPTIONS[device_name]
be_bryan 0:b74591d5ab33 73 iar_defaults ={
be_bryan 0:b74591d5ab33 74 "OGChipSelectEditMenu": "",
be_bryan 0:b74591d5ab33 75 "CoreVariant": '',
be_bryan 0:b74591d5ab33 76 "GFPUCoreSlave": '',
be_bryan 0:b74591d5ab33 77 "GFPUCoreSlave2": 40,
be_bryan 0:b74591d5ab33 78 "GBECoreSlave": 35,
be_bryan 0:b74591d5ab33 79 "GBECoreSlave2": '',
be_bryan 0:b74591d5ab33 80 "FPU2": 0,
be_bryan 0:b74591d5ab33 81 "NrRegs": 0,
be_bryan 0:b74591d5ab33 82 "NEON": '',
be_bryan 0:b74591d5ab33 83 "CExtraOptionsCheck": 0,
be_bryan 0:b74591d5ab33 84 "CExtraOptions": "",
be_bryan 0:b74591d5ab33 85 "CMSISDAPJtagSpeedList": 0,
be_bryan 0:b74591d5ab33 86 }
be_bryan 0:b74591d5ab33 87
be_bryan 0:b74591d5ab33 88 iar_defaults.update(device_info)
be_bryan 0:b74591d5ab33 89 IARdevice = namedtuple('IARdevice', iar_defaults.keys())
be_bryan 0:b74591d5ab33 90 return IARdevice(**iar_defaults)
be_bryan 0:b74591d5ab33 91
be_bryan 0:b74591d5ab33 92 def format_file(self, file):
be_bryan 0:b74591d5ab33 93 """Make IAR compatible path"""
be_bryan 0:b74591d5ab33 94 return join('$PROJ_DIR$',file)
be_bryan 0:b74591d5ab33 95
be_bryan 0:b74591d5ab33 96 def format_src(self, srcs):
be_bryan 0:b74591d5ab33 97 """Group source files"""
be_bryan 0:b74591d5ab33 98 grouped = self.group_project_files(srcs)
be_bryan 0:b74591d5ab33 99 for group, files in grouped.items():
be_bryan 0:b74591d5ab33 100 grouped[group] = [self.format_file(src) for src in files]
be_bryan 0:b74591d5ab33 101 return grouped
be_bryan 0:b74591d5ab33 102
be_bryan 0:b74591d5ab33 103 def generate(self):
be_bryan 0:b74591d5ab33 104 """Generate the .eww, .ewd, and .ewp files"""
be_bryan 0:b74591d5ab33 105 if not self.resources.linker_script:
be_bryan 0:b74591d5ab33 106 raise NotSupportedException("No linker script found.")
be_bryan 0:b74591d5ab33 107 srcs = self.resources.headers + self.resources.s_sources + \
be_bryan 0:b74591d5ab33 108 self.resources.c_sources + self.resources.cpp_sources + \
be_bryan 0:b74591d5ab33 109 self.resources.objects + self.resources.libraries
be_bryan 0:b74591d5ab33 110 flags = self.flags
be_bryan 0:b74591d5ab33 111 c_flags = list(set(flags['common_flags']
be_bryan 0:b74591d5ab33 112 + flags['c_flags']
be_bryan 0:b74591d5ab33 113 + flags['cxx_flags']))
be_bryan 0:b74591d5ab33 114 # Flags set in template to be set by user in IDE
be_bryan 0:b74591d5ab33 115 template = ["--vla", "--no_static_destruction"]
be_bryan 0:b74591d5ab33 116 # Flag invalid if set in template
be_bryan 0:b74591d5ab33 117 # Optimizations are also set in template
be_bryan 0:b74591d5ab33 118 invalid_flag = lambda x: x in template or re.match("-O(\d|time|n|hz?)", x)
be_bryan 0:b74591d5ab33 119 flags['c_flags'] = [flag for flag in c_flags if not invalid_flag(flag)]
be_bryan 0:b74591d5ab33 120
be_bryan 0:b74591d5ab33 121 try:
be_bryan 0:b74591d5ab33 122 debugger = DeviceCMSIS(self.target).debug.replace('-','').upper()
be_bryan 0:b74591d5ab33 123 except TargetNotSupportedException:
be_bryan 0:b74591d5ab33 124 debugger = "CMSISDAP"
be_bryan 0:b74591d5ab33 125
be_bryan 0:b74591d5ab33 126 ctx = {
be_bryan 0:b74591d5ab33 127 'name': self.project_name,
be_bryan 0:b74591d5ab33 128 'groups': self.iar_groups(self.format_src(srcs)),
be_bryan 0:b74591d5ab33 129 'linker_script': self.format_file(self.resources.linker_script),
be_bryan 0:b74591d5ab33 130 'include_paths': [self.format_file(src) for src in self.resources.inc_dirs],
be_bryan 0:b74591d5ab33 131 'device': self.iar_device(),
be_bryan 0:b74591d5ab33 132 'ewp': sep+self.project_name + ".ewp",
be_bryan 0:b74591d5ab33 133 'debugger': debugger
be_bryan 0:b74591d5ab33 134 }
be_bryan 0:b74591d5ab33 135 ctx.update(flags)
be_bryan 0:b74591d5ab33 136
be_bryan 0:b74591d5ab33 137 self.gen_file('iar/eww.tmpl', ctx, self.project_name + ".eww")
be_bryan 0:b74591d5ab33 138 self.gen_file('iar/ewd.tmpl', ctx, self.project_name + ".ewd")
be_bryan 0:b74591d5ab33 139 self.gen_file('iar/ewp.tmpl', ctx, self.project_name + ".ewp")
be_bryan 0:b74591d5ab33 140
be_bryan 0:b74591d5ab33 141 @staticmethod
be_bryan 0:b74591d5ab33 142 def build(project_name, log_name="build_log.txt", cleanup=True):
be_bryan 0:b74591d5ab33 143 """ Build IAR project """
be_bryan 0:b74591d5ab33 144 # > IarBuild [project_path] -build [project_name]
be_bryan 0:b74591d5ab33 145 proj_file = project_name + ".ewp"
be_bryan 0:b74591d5ab33 146 cmd = ["IarBuild", proj_file, '-build', project_name]
be_bryan 0:b74591d5ab33 147
be_bryan 0:b74591d5ab33 148 # IAR does not support a '0' option to automatically use all
be_bryan 0:b74591d5ab33 149 # available CPUs, so we use Python's multiprocessing library
be_bryan 0:b74591d5ab33 150 # to detect the number of CPUs available
be_bryan 0:b74591d5ab33 151 cpus_available = cpu_count()
be_bryan 0:b74591d5ab33 152 jobs = cpus_available if cpus_available else None
be_bryan 0:b74591d5ab33 153
be_bryan 0:b74591d5ab33 154 # Only add the parallel flag if we're using more than one CPU
be_bryan 0:b74591d5ab33 155 if jobs:
be_bryan 0:b74591d5ab33 156 cmd += ['-parallel', str(jobs)]
be_bryan 0:b74591d5ab33 157
be_bryan 0:b74591d5ab33 158 # Build the project
be_bryan 0:b74591d5ab33 159 p = Popen(cmd, stdout=PIPE, stderr=PIPE)
be_bryan 0:b74591d5ab33 160 out, err = p.communicate()
be_bryan 0:b74591d5ab33 161 ret_code = p.returncode
be_bryan 0:b74591d5ab33 162
be_bryan 0:b74591d5ab33 163 out_string = "=" * 10 + "STDOUT" + "=" * 10 + "\n"
be_bryan 0:b74591d5ab33 164 out_string += out
be_bryan 0:b74591d5ab33 165 out_string += "=" * 10 + "STDERR" + "=" * 10 + "\n"
be_bryan 0:b74591d5ab33 166 out_string += err
be_bryan 0:b74591d5ab33 167
be_bryan 0:b74591d5ab33 168 if ret_code == 0:
be_bryan 0:b74591d5ab33 169 out_string += "SUCCESS"
be_bryan 0:b74591d5ab33 170 else:
be_bryan 0:b74591d5ab33 171 out_string += "FAILURE"
be_bryan 0:b74591d5ab33 172
be_bryan 0:b74591d5ab33 173 print out_string
be_bryan 0:b74591d5ab33 174
be_bryan 0:b74591d5ab33 175 if log_name:
be_bryan 0:b74591d5ab33 176 # Write the output to the log file
be_bryan 0:b74591d5ab33 177 with open(log_name, 'w+') as f:
be_bryan 0:b74591d5ab33 178 f.write(out_string)
be_bryan 0:b74591d5ab33 179
be_bryan 0:b74591d5ab33 180 # Cleanup the exported and built files
be_bryan 0:b74591d5ab33 181 if cleanup:
be_bryan 0:b74591d5ab33 182 os.remove(project_name + ".ewp")
be_bryan 0:b74591d5ab33 183 os.remove(project_name + ".ewd")
be_bryan 0:b74591d5ab33 184 os.remove(project_name + ".eww")
be_bryan 0:b74591d5ab33 185 # legacy output file location
be_bryan 0:b74591d5ab33 186 if exists('.build'):
be_bryan 0:b74591d5ab33 187 shutil.rmtree('.build')
be_bryan 0:b74591d5ab33 188 if exists('BUILD'):
be_bryan 0:b74591d5ab33 189 shutil.rmtree('BUILD')
be_bryan 0:b74591d5ab33 190
be_bryan 0:b74591d5ab33 191 if ret_code !=0:
be_bryan 0:b74591d5ab33 192 # Seems like something went wrong.
be_bryan 0:b74591d5ab33 193 return -1
be_bryan 0:b74591d5ab33 194 else:
be_bryan 0:b74591d5ab33 195 return 0
be_bryan 0:b74591d5ab33 196
be_bryan 0:b74591d5ab33 197