diff --git a/tools/export/__init__.py b/tools/export/__init__.py index 46c4488f1d..035f099265 100644 --- a/tools/export/__init__.py +++ b/tools/export/__init__.py @@ -33,7 +33,7 @@ EXPORTERS = { 'make_armc5': makefile.Armc5, 'make_iar': makefile.IAR, 'ds5_5': ds5_5.DS5_5, - 'iar': iar.IAREmbeddedWorkbench, + 'iar': iar.IAR, 'emblocks' : emblocks.IntermediateFile, 'coide' : coide.CoIDE, 'kds' : kds.KDS, diff --git a/tools/export/iar.py b/tools/export/iar.py deleted file mode 100644 index 2037de79fe..0000000000 --- a/tools/export/iar.py +++ /dev/null @@ -1,154 +0,0 @@ -""" -mbed SDK -Copyright (c) 2011-2016 ARM Limited - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -""" -import re -import os -from project_generator_definitions.definitions import ProGenDef - -from tools.export.exporters import Exporter, ExporterTargetsProperty -from tools.targets import TARGET_MAP, TARGET_NAMES - -# If you wish to add a new target, add it to project_generator_definitions, and then -# define progen_target name in the target class (`` self.progen_target = 'my_target_name' ``) -class IAREmbeddedWorkbench(Exporter): - """ - Exporter class for IAR Systems. This class uses project generator. - """ - # These 2 are currently for exporters backward compatiblity - NAME = 'iar_arm' - TOOLCHAIN = 'IAR' - # PROGEN_ACTIVE contains information for exporter scripts that this is using progen - PROGEN_ACTIVE = True - - MBED_CONFIG_HEADER_SUPPORTED = True - - @ExporterTargetsProperty - def TARGETS(cls): - if not hasattr(cls, "_targets_supported"): - cls._targets_supported = [] - progendef = ProGenDef('iar') - for target in TARGET_NAMES: - try: - if (progendef.is_supported(str(TARGET_MAP[target])) or - progendef.is_supported(TARGET_MAP[target].progen['target'])): - cls._targets_supported.append(target) - except AttributeError: - # target is not supported yet - continue - return cls._targets_supported - - def generate(self): - """ Generates the project files """ - project_data = self.progen_get_project_data() - try: - if TARGET_MAP[self.target].progen['iar']['template']: - project_data['template']=TARGET_MAP[self.target].progen['iar']['template'] - except KeyError: - # use default template - # by the mbed projects - project_data['template']=[os.path.join(os.path.dirname(__file__), 'iar_template.ewp.tmpl')] - - project_data['misc'] = self.flags - # VLA is enabled via template IccAllowVLA - if "--vla" in project_data['misc']['c_flags']: - project_data['misc']['c_flags'].remove("--vla") - # Static destruction enabled via template - if "--no_static_destruction" in project_data['misc']['cxx_flags']: - project_data['misc']['cxx_flags'].remove("--no_static_destruction") - project_data['misc']['asm_flags'] = list(set(project_data['misc']['asm_flags'])) - project_data['build_dir'] = os.path.join(project_data['build_dir'], 'iar_arm') - self.progen_gen_file(project_data) - -# Currently not used, we should reuse folder_name to create virtual folders -class IarFolder(): - """ - This is a recursive folder object. - To present the folder structure in the IDE as it is presented on the disk. - This can be used for uvision as well if you replace the __str__ method. - Example: - files: ./main.cpp, ./apis/I2C.h, ./mbed/common/I2C.cpp - in the project this would look like: - main.cpp - common/I2C.cpp - input: - folder_level : folder path to current folder - folder_name : name of current folder - source_files : list of source_files (all must be in same directory) - """ - def __init__(self, folder_level, folder_name, source_files): - self.folder_level = folder_level - self.folder_name = folder_name - self.source_files = source_files - self.sub_folders = {} - - def __str__(self): - """ - converts the folder structue to IAR project format. - """ - group_start = "" - group_end = "" - if self.folder_name != "": - group_start = "\n%s\n" %(self.folder_name) - group_end = "\n" - - str_content = group_start - #Add files in current folder - if self.source_files: - for src in self.source_files: - str_content += "\n$PROJ_DIR$/%s\n\n" % src - #Add sub folders - if self.sub_folders: - for folder_name in self.sub_folders.iterkeys(): - str_content += self.sub_folders[folder_name].__str__() - - str_content += group_end - return str_content - - def insert_file(self, source_input): - """ - Inserts a source file into the folder tree - """ - if self.source_files: - #All source_files in a IarFolder must be in same directory. - dir_sources = IarFolder.get_directory(self.source_files[0]) - #Check if sources are already at their deepest level. - if not self.folder_level == dir_sources: - _reg_exp = r"^" + re.escape(self.folder_level) + r"[/\\]?([^/\\]+)" - folder_name = re.match(_reg_exp, dir_sources).group(1) - self.sub_folders[folder_name] = IarFolder(os.path.join(self.folder_level, folder_name), folder_name, self.source_files) - self.source_files = [] - - dir_input = IarFolder.get_directory(source_input) - if dir_input == self.folder_level: - self.source_files.append(source_input) - else: - _reg_exp = r"^" + re.escape(self.folder_level) + r"[/\\]?([^/\\]+)" - folder_name = re.match(_reg_exp, dir_input).group(1) - if self.sub_folders.has_key(folder_name): - self.sub_folders[folder_name].insert_file(source_input) - else: - if self.folder_level == "": - #Top level exception - self.sub_folders[folder_name] = IarFolder(folder_name, folder_name, [source_input]) - else: - self.sub_folders[folder_name] = IarFolder(os.path.join(self.folder_level, folder_name), folder_name, [source_input]) - - @staticmethod - def get_directory(file_path): - """ - Returns the directory of the file - """ - return os.path.dirname(file_path) diff --git a/tools/export/iar/__init__.py b/tools/export/iar/__init__.py new file mode 100644 index 0000000000..0c1caa9bb5 --- /dev/null +++ b/tools/export/iar/__init__.py @@ -0,0 +1,136 @@ +import os +from os.path import sep, join, exists +from collections import namedtuple +from subprocess import Popen, PIPE +from distutils.spawn import find_executable +import re + +from tools.targets import TARGET_MAP +from tools.export.exporters import Exporter, FailedBuildException +import json +class IAR(Exporter): + NAME = 'iar' + TOOLCHAIN = 'IAR' + + def_loc = os.path.join( + os.path.dirname(os.path.abspath(__file__)), '..', '..', '..', + 'tools','export', 'iar', 'iar_definitions.json') + + with open(def_loc, 'r') as f: + IAR_DEFS = json.load(f) + TARGETS = [target for target, obj in TARGET_MAP.iteritems() + if hasattr(obj, 'device_name') and + obj.device_name in IAR_DEFS.keys()] + + SPECIAL_TEMPLATES = { + 'rz_a1h' : 'iar/iar_rz_a1h.ewp.tmpl', + 'nucleo_f746zg' : '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 + {% for file in group.files %} + + $PROJ_DIR${{file}} + + {% endfor %} + + {% 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): + 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): + return join('$PROJ_DIR$',file) + + def format_src(self, srcs): + 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 .ww 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'])) + flags['c_flags'].remove('--vla') + 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" + } + ctx.update(flags) + + self.gen_file('iar/eww.tmpl', ctx, self.project_name+".eww") + self.gen_file(self.get_ewp_template(), ctx, self.project_name + ".ewp") + + def _parse_subprocess_output(self, output): + num_errors = 0 + lines = output.split("\n") + error_re = '\s*Total number of errors:\s*(\d+)\s*' + for line in lines: + m = re.match(error_re, line) + if m is not None: + num_errors = m.group(1) + return int(num_errors) + + def build(self): + """ Build IAR project """ + # > IarBuild [project_path] -build [project_name] + proj_file = join(self.export_dir, self.project_name + ".ewp") + + if find_executable("IarBuild"): + iar_exe = "IarBuild.exe" + else: + iar_exe = join('C:', sep, + 'Program Files (x86)', 'IAR Systems', + 'Embedded Workbench 7.5', 'common', 'bin', + 'IarBuild.exe') + if not exists(iar_exe): + raise Exception("UV4.exe not found. Add to path.") + + cmd = [iar_exe, proj_file, '-build', self.project_name] + p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) + output, err = p.communicate() + num_errors = self._parse_subprocess_output(output) + if num_errors !=0: + # Seems like something went wrong. + raise FailedBuildException("Project: %s build failed with %s erros" % ( + proj_file, num_errors)) diff --git a/tools/export/iar/ewp.tmpl b/tools/export/iar/ewp.tmpl new file mode 100644 index 0000000000..6e562f1b4d --- /dev/null +++ b/tools/export/iar/ewp.tmpl @@ -0,0 +1,970 @@ + + + 2 + + {{name}} + + ARM + + 0 + + General + 3 + + 22 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 31 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + {% for group in groups %} + + {{group.name}} + {% for file in group.files %} + + {{file}} + + {% endfor %} + + {% endfor %} + diff --git a/tools/export/iar/eww.tmpl b/tools/export/iar/eww.tmpl new file mode 100644 index 0000000000..6f51c62c42 --- /dev/null +++ b/tools/export/iar/eww.tmpl @@ -0,0 +1,7 @@ + + + + $WS_DIR${{ewp}} + + + \ No newline at end of file diff --git a/tools/export/iar/iar_definitions.json b/tools/export/iar/iar_definitions.json new file mode 100644 index 0000000000..c119c2b85d --- /dev/null +++ b/tools/export/iar/iar_definitions.json @@ -0,0 +1,171 @@ +{ + "stm32l476vg": { + "OGChipSelectEditMenu": "STM32L476VG\tST STM32L476VG" + }, + "LPC11U24FBD48/401": { + "OGChipSelectEditMenu": "LPC11U24FBD64_401\tNXP LPC11U24FBD64_401" + }, + "STM32L432KC": { + "OGChipSelectEditMenu": "STM32L432KC\tST STM32L432KC" + }, + "STM32F334R8": { + "OGChipSelectEditMenu": "STM32F334x8\tST STM32F334x8" + }, + "STM32F302R8": { + "OGChipSelectEditMenu": "STM32F302x8\tST STM32F302x8" + }, + "EFM32LG990F256": { + "OGChipSelectEditMenu": "EFM32LG990F256\tSiliconLaboratories EFM32LG990F256" + }, + "STM32F042K6": { + "OGChipSelectEditMenu": "STM32F042x6\tST STM32F042x6" + }, + "stm32l476rg": { + "OGChipSelectEditMenu": "STM32L476RG\tST STM32L476RG" + }, + "STM32L011K4": { + "OGChipSelectEditMenu": "STM32L011x4\tST STM32L011x4" + }, + "EFM32WG990F256": { + "OGChipSelectEditMenu": "EFM32WG990F256\tSiliconLaboratories EFM32WG990F256" + }, + "STM32F401RE": { + "OGChipSelectEditMenu": "STM32F401xE\tST STM32F401xE" + }, + "STM32F070RB": { + "OGChipSelectEditMenu": "STM32F070RB\tST STM32F070RB" + }, + "STM32F767ZI": { + "OGChipSelectEditMenu": "STM32F767ZI\tST STM32F767ZI", + "CoreVariant": 41, + "GFPUCoreSlave2": 41, + "GBECoreSlave": 35 + }, + "MK64FN1M0xxx12": { + "OGChipSelectEditMenu": "MK64FN1M0xxx12\tFreescale MK64FN1M0xxx12" + }, + "STM32F072RB": { + "OGChipSelectEditMenu": "STM32F072RB\tST STM32F072RB" + }, + "nRF51822_xxAA": { + "OGChipSelectEditMenu": "nRF51822-QFAA\tNordicSemi nRF51822-QFAA" + }, + "EFM32GG990F1024": { + "OGChipSelectEditMenu": "EFM32GG990F1024\tSiliconLaboratories EFM32GG990F1024" + }, + "MKL46Z256xxx4": { + "OGChipSelectEditMenu": "MKL46Z256xxx4\tFreescale MKL46Z256xxx4" + }, + "STM32F030R8": { + "OGChipSelectEditMenu": "STM32F030x8\tST STM32F030x8" + }, + "EFM32ZG222F32": { + "OGChipSelectEditMenu": "EFM32ZG220F32\tSiliconLaboratories EFM32ZG220F32" + }, + "STM32F303RE": { + "OGChipSelectEditMenu": "STM32F303xE\tST STM32F303xE" + }, + "STM32L152RE": { + "OGChipSelectEditMenu": "STM32L152xE\tST STM32L152xE" + }, + "STM32F439ZI": { + "OGChipSelectEditMenu": "STM32F439ZI\tST STM32F439ZI" + }, + "LPC1768": { + "OGChipSelectEditMenu": "LPC1768\tNXP LPC1768" + }, + "STM32F446RE": { + "OGChipSelectEditMenu": "STM32F446RE\tST STM32F446RE" + }, + "STM32L073RZ": { + "OGChipSelectEditMenu": "STM32L073xz\tST STM32L073xz" + }, + "stm32ff746zg": { + "OGChipSelectEditMenu": "STM32F746ZG\tST STM32F746ZG", + "CoreVariant": 41, + "GFPUCoreSlave2": 41, + "GBECoreSlave": 41 + }, + "MKL43Z256xxx4": { + "OGChipSelectEditMenu": "MKL43Z256xxx4\tFreescale MKL43Z256xxx4" + }, + "STM32F410RB": { + "OGChipSelectEditMenu": "STM32F410x\tST STM32F410x" + }, + "LPC812M101JDH20": { + "OGChipSelectEditMenu": "LPC812M101\tNXP LPC812M101" + }, + "stm32f746ng": { + "OGChipSelectEditMenu": "STM32F746NG\tST STM32F746NG" + }, + "STM32F411RE": { + "OGChipSelectEditMenu": "STM32F411RE\tST STM32F411RE" + }, + "STM32L053C8": { + "OGChipSelectEditMenu": "STM32L053x8\tST STM32L053x8" + }, + "STM32L031K6": { + "OGChipSelectEditMenu": "STM32L031x6\tST STM32L031x6" + }, + "STM32F469NI": { + "OGChipSelectEditMenu": "STM32F469NI\tST STM32F469NI" + }, + "EFM32HG322F64": { + "OGChipSelectEditMenu": "EFM32HG322F64\tSiliconLaboratories EFM32HG322F64" + }, + "MK20DX256xxx7": { + "OGChipSelectEditMenu": "MK20DX256xxx7\tFreescale MK20DX256xxx7" + }, + "EFM32PG1B100F256GM32": { + "OGChipSelectEditMenu": "EFM32PG1B200F256GM48\tSiliconLaboratories EFM32PG1B200F256GM48", + "CoreVariant": 39, + "GFPUCoreSlave2": 39, + "GBECoreSlave": 39 + }, + "STM32F446ZE": { + "OGChipSelectEditMenu": "STM32F446ZE\tST STM32F446ZE" + }, + "MK22DN512xxx5": { + "OGChipSelectEditMenu": "MK22FN512xxx12\tFreescale MK22FN512xxx12" + }, + "STM32F303K8": { + "OGChipSelectEditMenu": "STM32F303x8\tST STM32F303x8" + }, + "STM32F405RG": { + "OGChipSelectEditMenu": "STM32F405RG\tST STM32F405RG" + }, + "MK20DX128xxx5": { + "OGChipSelectEditMenu": "MK20DX128xxx5\tFreescale MK20DX128xxx5" + }, + "MKL25Z128xxx4": { + "OGChipSelectEditMenu": "MKL25Z128xxx4\tFreescale MKL25Z128xxx4" + }, + "STM32F429ZI": { + "OGChipSelectEditMenu": "STM32F429ZI\tST STM32F429ZI" + }, + "STM32F103RB": { + "OGChipSelectEditMenu": "STM32F103xB\tST STM32F103xB" + }, + "STM32F091RC": { + "OGChipSelectEditMenu": "STM32F091RC\tST STM32F091RC" + }, + "r7s721001": { + "OGChipSelectEditMenu": "R7S721001\tRenesas R7S721001", + "CoreVariant": 37, + "GFPUCoreSlave": 37, + "GBECoreSlave": 37, + "NEON":1 + }, + "MKL05Z32xxx4": { + "OGChipSelectEditMenu": "MKL05Z32xxx4\tFreescale MKL05Z32xxx4" + }, + "STM32F031K6": { + "OGChipSelectEditMenu": "STM32F031x6\tST STM32F031x6" + }, + "max326000x85": { + "OGChipSelectEditMenu": "MAX32600x85\tMaxim MAX32600x85" + }, + "STM32F407VG": { + "OGChipSelectEditMenu": "STM32F407VG\tST STM32F407VG" + } +} diff --git a/tools/export/iar_nucleo_f746zg.ewp.tmpl b/tools/export/iar/iar_nucleo_f746zg.ewp.tmpl similarity index 98% rename from tools/export/iar_nucleo_f746zg.ewp.tmpl rename to tools/export/iar/iar_nucleo_f746zg.ewp.tmpl index 228fbf8b18..be2a678f1c 100644 --- a/tools/export/iar_nucleo_f746zg.ewp.tmpl +++ b/tools/export/iar/iar_nucleo_f746zg.ewp.tmpl @@ -3,7 +3,7 @@ 2 - Debug + {{name}} ARM @@ -16,16 +16,21 @@ 1 1 + - @@ -725,7 +732,7 @@ + {% for group in groups %} + + {{group.name}} + {% for file in group.files %} + + {{file}} + + {% endfor %} + + {% endfor %} + 2 - diff --git a/tools/export/iar_rz_a1h.ewp.tmpl b/tools/export/iar/iar_rz_a1h.ewp.tmpl similarity index 96% rename from tools/export/iar_rz_a1h.ewp.tmpl rename to tools/export/iar/iar_rz_a1h.ewp.tmpl index 4d5338da84..84833e64e7 100644 --- a/tools/export/iar_rz_a1h.ewp.tmpl +++ b/tools/export/iar/iar_rz_a1h.ewp.tmpl @@ -3,7 +3,7 @@ 2 - Debug + {{name}} ARM @@ -16,16 +16,16 @@ 1 1 @@ -689,7 +693,7 @@ - -$PROJ_DIR$/main.cpp - - -env - -$PROJ_DIR$/env\test_env.cpp - - - + {% for group in groups %} + + {{group.name}} + {% for file in group.files %} + + {{file}} + + {% endfor %} + + {% endfor %} + 2 diff --git a/tools/export/iar_template.ewp.tmpl b/tools/export/iar_template.ewp.tmpl deleted file mode 100644 index 332c5814b2..0000000000 --- a/tools/export/iar_template.ewp.tmpl +++ /dev/null @@ -1,995 +0,0 @@ - - - - 2 - - Debug - - ARM - - 1 - - General - 3 - - 22 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ICCARM - 2 - - 30 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AARM - 2 - - 9 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OBJCOPY - 0 - - 1 - 1 - 1 - - - - - - - - - CUSTOM - 3 - - - - - - - BICOMP - 0 - - - - BUILDACTION - 1 - - - - - - - ILINK - 0 - - 16 - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IARCHIVE - 0 - - 0 - 1 - 1 - - - - - - - BILINK - 0 - - - - -$PROJ_DIR$/main.cpp - - -env - -$PROJ_DIR$/env\test_env.cpp - - - - -