Knight KE / Mbed OS Game_Master
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers iar.py Source File

iar.py

00001 """
00002 mbed SDK
00003 Copyright (c) 2011-2013 ARM Limited
00004 
00005 Licensed under the Apache License, Version 2.0 (the "License");
00006 you may not use this file except in compliance with the License.
00007 You may obtain a copy of the License at
00008 
00009     http://www.apache.org/licenses/LICENSE-2.0
00010 
00011 Unless required by applicable law or agreed to in writing, software
00012 distributed under the License is distributed on an "AS IS" BASIS,
00013 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014 See the License for the specific language governing permissions and
00015 limitations under the License.
00016 """
00017 import re
00018 from os import remove
00019 from os.path import join, splitext, exists
00020 
00021 from tools.toolchains import mbedToolchain, TOOLCHAIN_PATHS
00022 from tools.hooks import hook_tool
00023 
00024 class IAR(mbedToolchain):
00025     LIBRARY_EXT = '.a'
00026     LINKER_EXT = '.icf'
00027     STD_LIB_NAME = "%s.a"
00028 
00029     DIAGNOSTIC_PATTERN = re.compile('"(?P<file>[^"]+)",(?P<line>[\d]+)\s+(?P<severity>Warning|Error|Fatal error)(?P<message>.+)')
00030     INDEX_PATTERN  = re.compile('(?P<col>\s*)\^')
00031 
00032     @staticmethod
00033     def check_executable():
00034         """Returns True if the executable (arm-none-eabi-gcc) location
00035         specified by the user exists OR the executable can be found on the PATH.
00036         Returns False otherwise."""
00037         return mbedToolchain.generic_check_executable("IAR", 'iccarm', 2, "bin")
00038 
00039     def __init__(self, target, notify=None, macros=None, build_profile=None,
00040                  build_dir=None):
00041         mbedToolchain.__init__(self, target, notify, macros, build_dir=build_dir,
00042                                build_profile=build_profile)
00043         if target.core == "Cortex-M7F" or target.core == "Cortex-M7FD":
00044             cpuchoice = "Cortex-M7"
00045         elif target.core.startswith("Cortex-M23"):
00046             cpuchoice = "8-M.baseline"
00047         elif target.core.startswith("Cortex-M33"):
00048             cpuchoice = "8-M.mainline"
00049         else:
00050             cpuchoice = target.core
00051 
00052         # flags_cmd are used only by our scripts, the project files have them already defined,
00053         # using this flags results in the errors (duplication)
00054         # asm accepts --cpu Core or --fpu FPU, not like c/c++ --cpu=Core
00055         asm_flags_cmd = ["--cpu", cpuchoice]
00056         # custom c flags
00057         c_flags_cmd = ["--cpu", cpuchoice]
00058 
00059         c_flags_cmd.extend([
00060             "--thumb", "--dlib_config", "DLib_Config_Full.h"
00061         ])
00062         # custom c++ cmd flags
00063         cxx_flags_cmd = [
00064             "--c++", "--no_rtti", "--no_exceptions"
00065         ]
00066         if target.core == "Cortex-M7FD":
00067             asm_flags_cmd += ["--fpu", "VFPv5"]
00068             c_flags_cmd.append("--fpu=VFPv5")
00069         elif target.core == "Cortex-M7F":
00070             asm_flags_cmd += ["--fpu", "VFPv5_sp"]
00071             c_flags_cmd.append("--fpu=VFPv5_sp")
00072         elif target.core == "Cortex-M23" or target.core == "Cortex-M33":
00073             self.flags["asm"] += ["--cmse"]
00074             self.flags["common"] += ["--cmse"]
00075 
00076         # Create Secure library
00077         if target.core == "Cortex-M23" or self.target.core == "Cortex-M33":
00078             secure_file = join(build_dir, "cmse_lib.o")
00079             self.flags["ld"] += ["--import_cmse_lib_out=%s" % secure_file]
00080 
00081         IAR_BIN = join(TOOLCHAIN_PATHS['IAR'], "bin")
00082         main_cc = join(IAR_BIN, "iccarm")
00083 
00084         self.asm  = [join(IAR_BIN, "iasmarm")] + asm_flags_cmd + self.flags["asm"]
00085         self.cc   = [main_cc]
00086         self.cppc = [main_cc]
00087         self.cc += self.flags["common"] + c_flags_cmd + self.flags["c"]
00088         self.cppc += self.flags["common"] + c_flags_cmd + cxx_flags_cmd + self.flags["cxx"]
00089         
00090         self.ld   = [join(IAR_BIN, "ilinkarm")] + self.flags['ld']
00091         self.ar = join(IAR_BIN, "iarchive")
00092         self.elf2bin = join(IAR_BIN, "ielftool")
00093 
00094     def parse_dependencies(self, dep_path):
00095         return [(self.CHROOT if self.CHROOT else '')+path.strip() for path in open(dep_path).readlines()
00096                 if (path and not path.isspace())]
00097 
00098     def parse_output(self, output):
00099         msg = None
00100         for line in output.splitlines():
00101             match = IAR.DIAGNOSTIC_PATTERN.match(line)
00102             if match is not None:
00103                 if msg is not None:
00104                     self.notify.cc_info(msg)
00105                     msg = None
00106                 msg = {
00107                     'severity': match.group('severity').lower(),
00108                     'file': match.group('file'),
00109                     'line': match.group('line'),
00110                     'col': 0,
00111                     'message': match.group('message'),
00112                     'text': '',
00113                     'target_name': self.target.name,
00114                     'toolchain_name': self.name
00115                 }
00116             elif msg is not None:
00117                 # Determine the warning/error column by calculating the ^ position
00118                 match = IAR.INDEX_PATTERN.match(line)
00119                 if match is not None:
00120                     msg['col'] = len(match.group('col'))
00121                     self.notify.cc_info(msg)
00122                     msg = None
00123                 else:
00124                     msg['text'] += line+"\n"
00125 
00126         if msg is not None:
00127             self.notify.cc_info(msg)
00128 
00129     def get_dep_option(self, object):
00130         base, _ = splitext(object)
00131         dep_path = base + '.d'
00132         return ["--dependencies", dep_path]
00133 
00134     def cc_extra(self, object):
00135         base, _ = splitext(object)
00136         return ["-l", base + '.s.txt']
00137 
00138     def get_config_option(self, config_header):
00139         return ['--preinclude=' + config_header]
00140 
00141     def get_compile_options(self, defines, includes, for_asm=False):
00142         opts = ['-D%s' % d for d in defines]
00143         if for_asm :
00144             return opts
00145         if self.RESPONSE_FILES:
00146             opts += ['-f', self.get_inc_file(includes)]
00147         else:
00148             opts += ["-I%s" % i for i in includes]
00149 
00150         config_header = self.get_config_header()
00151         if config_header is not None:
00152             opts = opts + self.get_config_option(config_header)
00153         return opts
00154 
00155     @hook_tool
00156     def assemble(self, source, object, includes):
00157         # Build assemble command
00158         cmd = self.asm + self.get_compile_options(self.get_symbols(True), includes, True) + ["-o", object, source]
00159 
00160         # Call cmdline hook
00161         cmd = self.hook.get_cmdline_assembler(cmd)
00162 
00163         # Return command array, don't execute
00164         return [cmd]
00165 
00166     @hook_tool
00167     def compile(self, cc, source, object, includes):
00168         # Build compile command
00169         cmd = cc +  self.get_compile_options(self.get_symbols(), includes)
00170 
00171         cmd.extend(self.get_dep_option(object))
00172 
00173         cmd.extend(self.cc_extra(object))
00174         
00175         cmd.extend(["-o", object, source])
00176 
00177         # Call cmdline hook
00178         cmd = self.hook.get_cmdline_compiler(cmd)
00179 
00180         return [cmd]
00181 
00182     def compile_c(self, source, object, includes):
00183         return self.compile(self.cc, source, object, includes)
00184 
00185     def compile_cpp(self, source, object, includes):
00186         return self.compile(self.cppc, source, object, includes)
00187 
00188     @hook_tool
00189     def link(self, output, objects, libraries, lib_dirs, mem_map):
00190         # Build linker command
00191         map_file = splitext(output)[0] + ".map"
00192         cmd = self.ld + [ "-o", output, "--map=%s" % map_file] + objects + libraries
00193 
00194         if mem_map:
00195             cmd.extend(["--config", mem_map])
00196 
00197         # Call cmdline hook
00198         cmd = self.hook.get_cmdline_linker(cmd)
00199 
00200         if self.RESPONSE_FILES:
00201             # Split link command to linker executable + response file
00202             cmd_linker = cmd[0]
00203             link_files = self.get_link_file(cmd[1:])
00204             cmd = [cmd_linker, '-f', link_files]
00205 
00206         # Exec command
00207         self.notify.cc_verbose("Link: %s" % ' '.join(cmd))
00208         self.default_cmd(cmd)
00209 
00210     @hook_tool
00211     def archive(self, objects, lib_path):
00212         if self.RESPONSE_FILES:
00213             param = ['-f', self.get_arch_file(objects)]
00214         else:
00215             param = objects
00216 
00217         if exists(lib_path):
00218             remove(lib_path)
00219 
00220         self.default_cmd([self.ar, lib_path] + param)
00221 
00222     @hook_tool
00223     def binary(self, resources, elf, bin):
00224         _, fmt = splitext(bin)
00225         bin_arg = {".bin": "--bin", ".hex": "--ihex"}[fmt]
00226         # Build binary command
00227         cmd = [self.elf2bin, bin_arg, elf, bin]
00228 
00229         # Call cmdline hook
00230         cmd = self.hook.get_cmdline_binary(cmd)
00231 
00232         # Exec command
00233         self.notify.cc_verbose("FromELF: %s" % ' '.join(cmd))
00234         self.default_cmd(cmd)
00235 
00236     @staticmethod
00237     def name_mangle(name):
00238         return "_Z%i%sv" % (len(name), name)
00239 
00240     @staticmethod
00241     def make_ld_define(name, value):
00242         return "--config_def %s=0x%x" % (name, value)
00243 
00244     @staticmethod
00245     def redirect_symbol(source, sync, build_dir):
00246         return "--redirect %s=%s" % (source, sync)