mbed os with nrf51 internal bandgap enabled to read battery level
Dependents: BLE_file_test BLE_Blink ExternalEncoder
tools/export/iar/__init__.py@0:f269e3021894, 2016-10-23 (annotated)
- Committer:
- elessair
- Date:
- Sun Oct 23 15:10:02 2016 +0000
- Revision:
- 0:f269e3021894
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
elessair | 0:f269e3021894 | 1 | import os |
elessair | 0:f269e3021894 | 2 | from os.path import sep, join, exists |
elessair | 0:f269e3021894 | 3 | from collections import namedtuple |
elessair | 0:f269e3021894 | 4 | from subprocess import Popen, PIPE |
elessair | 0:f269e3021894 | 5 | from distutils.spawn import find_executable |
elessair | 0:f269e3021894 | 6 | import re |
elessair | 0:f269e3021894 | 7 | import sys |
elessair | 0:f269e3021894 | 8 | |
elessair | 0:f269e3021894 | 9 | from tools.targets import TARGET_MAP |
elessair | 0:f269e3021894 | 10 | from tools.export.exporters import Exporter, FailedBuildException |
elessair | 0:f269e3021894 | 11 | import json |
elessair | 0:f269e3021894 | 12 | from tools.export.cmsis import DeviceCMSIS |
elessair | 0:f269e3021894 | 13 | |
elessair | 0:f269e3021894 | 14 | class IAR(Exporter): |
elessair | 0:f269e3021894 | 15 | NAME = 'iar' |
elessair | 0:f269e3021894 | 16 | TOOLCHAIN = 'IAR' |
elessair | 0:f269e3021894 | 17 | |
elessair | 0:f269e3021894 | 18 | #iar_definitions.json location |
elessair | 0:f269e3021894 | 19 | def_loc = os.path.join( |
elessair | 0:f269e3021894 | 20 | os.path.dirname(os.path.abspath(__file__)), '..', '..', '..', |
elessair | 0:f269e3021894 | 21 | 'tools','export', 'iar', 'iar_definitions.json') |
elessair | 0:f269e3021894 | 22 | |
elessair | 0:f269e3021894 | 23 | #create a dictionary of the definitions |
elessair | 0:f269e3021894 | 24 | with open(def_loc, 'r') as f: |
elessair | 0:f269e3021894 | 25 | IAR_DEFS = json.load(f) |
elessair | 0:f269e3021894 | 26 | |
elessair | 0:f269e3021894 | 27 | #supported targets have a device name and corresponding definition in |
elessair | 0:f269e3021894 | 28 | #iar_definitions.json |
elessair | 0:f269e3021894 | 29 | TARGETS = [target for target, obj in TARGET_MAP.iteritems() |
elessair | 0:f269e3021894 | 30 | if hasattr(obj, 'device_name') and |
elessair | 0:f269e3021894 | 31 | obj.device_name in IAR_DEFS.keys()] |
elessair | 0:f269e3021894 | 32 | |
elessair | 0:f269e3021894 | 33 | SPECIAL_TEMPLATES = { |
elessair | 0:f269e3021894 | 34 | 'rz_a1h' : 'iar/iar_rz_a1h.ewp.tmpl', |
elessair | 0:f269e3021894 | 35 | 'nucleo_f746zg' : 'iar/iar_nucleo_f746zg.ewp.tmpl' |
elessair | 0:f269e3021894 | 36 | } |
elessair | 0:f269e3021894 | 37 | |
elessair | 0:f269e3021894 | 38 | def iar_groups(self, grouped_src): |
elessair | 0:f269e3021894 | 39 | """Return a namedtuple of group info |
elessair | 0:f269e3021894 | 40 | Positional Arguments: |
elessair | 0:f269e3021894 | 41 | grouped_src: dictionary mapping a group(str) to sources |
elessair | 0:f269e3021894 | 42 | within it (list of file names) |
elessair | 0:f269e3021894 | 43 | Relevant part of IAR template |
elessair | 0:f269e3021894 | 44 | {% for group in groups %} |
elessair | 0:f269e3021894 | 45 | <group> |
elessair | 0:f269e3021894 | 46 | <name>group.name</name> |
elessair | 0:f269e3021894 | 47 | {% for file in group.files %} |
elessair | 0:f269e3021894 | 48 | <file> |
elessair | 0:f269e3021894 | 49 | <name>$PROJ_DIR${{file}}</name> |
elessair | 0:f269e3021894 | 50 | </file> |
elessair | 0:f269e3021894 | 51 | {% endfor %} |
elessair | 0:f269e3021894 | 52 | </group> |
elessair | 0:f269e3021894 | 53 | {% endfor %} |
elessair | 0:f269e3021894 | 54 | """ |
elessair | 0:f269e3021894 | 55 | IARgroup = namedtuple('IARgroup', ['name','files']) |
elessair | 0:f269e3021894 | 56 | groups = [] |
elessair | 0:f269e3021894 | 57 | for name, files in grouped_src.items(): |
elessair | 0:f269e3021894 | 58 | groups.append(IARgroup(name,files)) |
elessair | 0:f269e3021894 | 59 | return groups |
elessair | 0:f269e3021894 | 60 | |
elessair | 0:f269e3021894 | 61 | def iar_device(self): |
elessair | 0:f269e3021894 | 62 | """Retrieve info from iar_definitions.json""" |
elessair | 0:f269e3021894 | 63 | device_name = TARGET_MAP[self.target].device_name |
elessair | 0:f269e3021894 | 64 | device_info = self.IAR_DEFS[device_name] |
elessair | 0:f269e3021894 | 65 | iar_defaults ={ |
elessair | 0:f269e3021894 | 66 | "OGChipSelectEditMenu": "", |
elessair | 0:f269e3021894 | 67 | "CoreVariant": '', |
elessair | 0:f269e3021894 | 68 | "GFPUCoreSlave": '', |
elessair | 0:f269e3021894 | 69 | "GFPUCoreSlave2": 40, |
elessair | 0:f269e3021894 | 70 | "GBECoreSlave": 35 |
elessair | 0:f269e3021894 | 71 | } |
elessair | 0:f269e3021894 | 72 | |
elessair | 0:f269e3021894 | 73 | iar_defaults.update(device_info) |
elessair | 0:f269e3021894 | 74 | IARdevice = namedtuple('IARdevice', iar_defaults.keys()) |
elessair | 0:f269e3021894 | 75 | return IARdevice(**iar_defaults) |
elessair | 0:f269e3021894 | 76 | |
elessair | 0:f269e3021894 | 77 | def format_file(self, file): |
elessair | 0:f269e3021894 | 78 | """Make IAR compatible path""" |
elessair | 0:f269e3021894 | 79 | return join('$PROJ_DIR$',file) |
elessair | 0:f269e3021894 | 80 | |
elessair | 0:f269e3021894 | 81 | def format_src(self, srcs): |
elessair | 0:f269e3021894 | 82 | """Group source files""" |
elessair | 0:f269e3021894 | 83 | grouped = self.group_project_files(srcs) |
elessair | 0:f269e3021894 | 84 | for group, files in grouped.items(): |
elessair | 0:f269e3021894 | 85 | grouped[group] = [self.format_file(src) for src in files] |
elessair | 0:f269e3021894 | 86 | return grouped |
elessair | 0:f269e3021894 | 87 | |
elessair | 0:f269e3021894 | 88 | def get_ewp_template(self): |
elessair | 0:f269e3021894 | 89 | return self.SPECIAL_TEMPLATES.get(self.target.lower(), 'iar/ewp.tmpl') |
elessair | 0:f269e3021894 | 90 | |
elessair | 0:f269e3021894 | 91 | def generate(self): |
elessair | 0:f269e3021894 | 92 | """Generate the .eww, .ewd, and .ewp files""" |
elessair | 0:f269e3021894 | 93 | srcs = self.resources.headers + self.resources.s_sources + \ |
elessair | 0:f269e3021894 | 94 | self.resources.c_sources + self.resources.cpp_sources + \ |
elessair | 0:f269e3021894 | 95 | self.resources.objects + self.resources.libraries |
elessair | 0:f269e3021894 | 96 | flags = self.flags |
elessair | 0:f269e3021894 | 97 | flags['c_flags'] = list(set(flags['common_flags'] |
elessair | 0:f269e3021894 | 98 | + flags['c_flags'] |
elessair | 0:f269e3021894 | 99 | + flags['cxx_flags'])) |
elessair | 0:f269e3021894 | 100 | if '--vla' in flags['c_flags']: |
elessair | 0:f269e3021894 | 101 | flags['c_flags'].remove('--vla') |
elessair | 0:f269e3021894 | 102 | if '--no_static_destruction' in flags['c_flags']: |
elessair | 0:f269e3021894 | 103 | flags['c_flags'].remove('--no_static_destruction') |
elessair | 0:f269e3021894 | 104 | #Optimizations |
elessair | 0:f269e3021894 | 105 | if '-Oh' in flags['c_flags']: |
elessair | 0:f269e3021894 | 106 | flags['c_flags'].remove('-Oh') |
elessair | 0:f269e3021894 | 107 | ctx = { |
elessair | 0:f269e3021894 | 108 | 'name': self.project_name, |
elessair | 0:f269e3021894 | 109 | 'groups': self.iar_groups(self.format_src(srcs)), |
elessair | 0:f269e3021894 | 110 | 'linker_script': self.format_file(self.resources.linker_script), |
elessair | 0:f269e3021894 | 111 | 'include_paths': [self.format_file(src) for src in self.resources.inc_dirs], |
elessair | 0:f269e3021894 | 112 | 'device': self.iar_device(), |
elessair | 0:f269e3021894 | 113 | 'ewp': sep+self.project_name + ".ewp", |
elessair | 0:f269e3021894 | 114 | 'debugger': DeviceCMSIS(self.target).debug.replace('-','').upper() |
elessair | 0:f269e3021894 | 115 | } |
elessair | 0:f269e3021894 | 116 | ctx.update(flags) |
elessair | 0:f269e3021894 | 117 | |
elessair | 0:f269e3021894 | 118 | self.gen_file('iar/eww.tmpl', ctx, self.project_name+".eww") |
elessair | 0:f269e3021894 | 119 | self.gen_file('iar/ewd.tmpl', ctx, self.project_name + ".ewd") |
elessair | 0:f269e3021894 | 120 | self.gen_file(self.get_ewp_template(), ctx, self.project_name + ".ewp") |
elessair | 0:f269e3021894 | 121 | |
elessair | 0:f269e3021894 | 122 | def build(self): |
elessair | 0:f269e3021894 | 123 | """ Build IAR project """ |
elessair | 0:f269e3021894 | 124 | # > IarBuild [project_path] -build [project_name] |
elessair | 0:f269e3021894 | 125 | proj_file = join(self.export_dir, self.project_name + ".ewp") |
elessair | 0:f269e3021894 | 126 | |
elessair | 0:f269e3021894 | 127 | if find_executable("IarBuild"): |
elessair | 0:f269e3021894 | 128 | iar_exe = "IarBuild.exe" |
elessair | 0:f269e3021894 | 129 | else: |
elessair | 0:f269e3021894 | 130 | iar_exe = join('C:', sep, |
elessair | 0:f269e3021894 | 131 | 'Program Files (x86)', 'IAR Systems', |
elessair | 0:f269e3021894 | 132 | 'Embedded Workbench 7.5', 'common', 'bin', |
elessair | 0:f269e3021894 | 133 | 'IarBuild.exe') |
elessair | 0:f269e3021894 | 134 | if not exists(iar_exe): |
elessair | 0:f269e3021894 | 135 | raise Exception("IarBuild.exe not found. Add to path.") |
elessair | 0:f269e3021894 | 136 | |
elessair | 0:f269e3021894 | 137 | cmd = [iar_exe, proj_file, '-build', self.project_name] |
elessair | 0:f269e3021894 | 138 | p = Popen(cmd, stdout=PIPE, stderr=PIPE) |
elessair | 0:f269e3021894 | 139 | num_errors = 0 |
elessair | 0:f269e3021894 | 140 | #Parse the output for printing and errors |
elessair | 0:f269e3021894 | 141 | for line in p.stdout.readlines(): |
elessair | 0:f269e3021894 | 142 | sys.stdout.write(line) |
elessair | 0:f269e3021894 | 143 | error_re = '\s*Total number of errors:\s*(\d+)\s*' |
elessair | 0:f269e3021894 | 144 | m = re.match(error_re, line) |
elessair | 0:f269e3021894 | 145 | if m is not None: |
elessair | 0:f269e3021894 | 146 | num_errors = int(m.group(1)) |
elessair | 0:f269e3021894 | 147 | if num_errors !=0: |
elessair | 0:f269e3021894 | 148 | # Seems like something went wrong. |
elessair | 0:f269e3021894 | 149 | raise FailedBuildException("Project: %s build failed with %s erros" % ( |
elessair | 0:f269e3021894 | 150 | proj_file, num_errors)) |