Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
arm.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 copy import copy 00019 from os.path import join, dirname, splitext, basename, exists 00020 from os import makedirs, write 00021 from tempfile import mkstemp 00022 00023 from tools.toolchains import mbedToolchain, TOOLCHAIN_PATHS 00024 from tools.hooks import hook_tool 00025 from tools.utils import mkdir, NotSupportedException 00026 00027 class ARM(mbedToolchain): 00028 LINKER_EXT = '.sct' 00029 LIBRARY_EXT = '.ar' 00030 00031 STD_LIB_NAME = "%s.ar" 00032 DIAGNOSTIC_PATTERN = re.compile('"(?P<file>[^"]+)", line (?P<line>\d+)( \(column (?P<column>\d+)\)|): (?P<severity>Warning|Error|Fatal error): (?P<message>.+)') 00033 INDEX_PATTERN = re.compile('(?P<col>\s*)\^') 00034 DEP_PATTERN = re.compile('\S+:\s(?P<file>.+)\n') 00035 SHEBANG = "#! armcc -E" 00036 SUPPORTED_CORES = ["Cortex-M0", "Cortex-M0+", "Cortex-M3", "Cortex-M4", 00037 "Cortex-M4F", "Cortex-M7", "Cortex-M7F", "Cortex-M7FD"] 00038 00039 @staticmethod 00040 def check_executable(): 00041 """Returns True if the executable (armcc) location specified by the 00042 user exists OR the executable can be found on the PATH. 00043 Returns False otherwise.""" 00044 return mbedToolchain.generic_check_executable("ARM", 'armcc', 2, 'bin') 00045 00046 def __init__(self, target, notify=None, macros=None, 00047 silent=False, extra_verbose=False, build_profile=None, 00048 build_dir=None): 00049 mbedToolchain.__init__(self, target, notify, macros, silent, 00050 build_dir=build_dir, 00051 extra_verbose=extra_verbose, 00052 build_profile=build_profile) 00053 if target.core not in self.SUPPORTED_CORES: 00054 raise NotSupportedException( 00055 "this compiler does not support the core %s" % target.core) 00056 00057 if target.core == "Cortex-M0+": 00058 cpu = "Cortex-M0" 00059 elif target.core == "Cortex-M4F": 00060 cpu = "Cortex-M4.fp" 00061 elif target.core == "Cortex-M7FD": 00062 cpu = "Cortex-M7.fp.dp" 00063 elif target.core == "Cortex-M7F": 00064 cpu = "Cortex-M7.fp.sp" 00065 else: 00066 cpu = target.core 00067 00068 ARM_BIN = join(TOOLCHAIN_PATHS['ARM'], "bin") 00069 ARM_INC = join(TOOLCHAIN_PATHS['ARM'], "include") 00070 00071 main_cc = join(ARM_BIN, "armcc") 00072 00073 self.flags['common'] += ["--cpu=%s" % cpu] 00074 00075 self.asm = [main_cc] + self.flags['common'] + self.flags['asm'] 00076 self.cc = [main_cc] + self.flags['common'] + self.flags['c'] 00077 self.cppc = [main_cc] + self.flags['common'] + self.flags['c'] + self.flags['cxx'] 00078 00079 self.ld = [join(ARM_BIN, "armlink")] + self.flags['ld'] 00080 00081 self.ar = join(ARM_BIN, "armar") 00082 self.elf2bin = join(ARM_BIN, "fromelf") 00083 00084 def parse_dependencies(self, dep_path): 00085 dependencies = [] 00086 for line in open(dep_path).readlines(): 00087 match = ARM.DEP_PATTERN.match(line) 00088 if match is not None: 00089 #we need to append chroot, because when the .d files are generated the compiler is chrooted 00090 dependencies.append((self.CHROOT if self.CHROOT else '') + match.group('file')) 00091 return dependencies 00092 00093 def parse_output(self, output): 00094 msg = None 00095 for line in output.splitlines(): 00096 match = ARM.DIAGNOSTIC_PATTERN.match(line) 00097 if match is not None: 00098 if msg is not None: 00099 self.cc_info(msg) 00100 msg = None 00101 msg = { 00102 'severity': match.group('severity').lower(), 00103 'file': match.group('file'), 00104 'line': match.group('line'), 00105 'col': match.group('column') if match.group('column') else 0, 00106 'message': match.group('message'), 00107 'text': '', 00108 'target_name': self.target.name, 00109 'toolchain_name': self.name 00110 } 00111 elif msg is not None: 00112 # Determine the warning/error column by calculating the ^ position 00113 match = ARM.INDEX_PATTERN.match(line) 00114 if match is not None: 00115 msg['col'] = len(match.group('col')) 00116 self.cc_info(msg) 00117 msg = None 00118 else: 00119 msg['text'] += line+"\n" 00120 00121 if msg is not None: 00122 self.cc_info(msg) 00123 00124 def get_dep_option(self, object): 00125 base, _ = splitext(object) 00126 dep_path = base + '.d' 00127 return ["--depend", dep_path] 00128 00129 def get_config_option(self, config_header): 00130 return ['--preinclude=' + config_header] 00131 00132 def get_compile_options(self, defines, includes, for_asm=False): 00133 opts = ['-D%s' % d for d in defines] 00134 if self.RESPONSE_FILES: 00135 opts += ['--via', self.get_inc_file(includes)] 00136 else: 00137 opts += ["-I%s" % i for i in includes] 00138 00139 if not for_asm: 00140 config_header = self.get_config_header() 00141 if config_header is not None: 00142 opts = opts + self.get_config_option(config_header) 00143 return opts 00144 00145 @hook_tool 00146 def assemble(self, source, object, includes): 00147 # Preprocess first, then assemble 00148 dir = join(dirname(object), '.temp') 00149 mkdir(dir) 00150 tempfile = join(dir, basename(object) + '.E.s') 00151 00152 # Build preprocess assemble command 00153 cmd_pre = self.asm + self.get_compile_options(self.get_symbols(True), includes) + ["-E", "-o", tempfile, source] 00154 00155 # Build main assemble command 00156 cmd = self.asm + ["-o", object, tempfile] 00157 00158 # Call cmdline hook 00159 cmd_pre = self.hook.get_cmdline_assembler(cmd_pre) 00160 cmd = self.hook.get_cmdline_assembler(cmd) 00161 00162 # Return command array, don't execute 00163 return [cmd_pre, cmd] 00164 00165 @hook_tool 00166 def compile(self, cc, source, object, includes): 00167 # Build compile command 00168 cmd = cc + self.get_compile_options(self.get_symbols(), includes) 00169 00170 cmd.extend(self.get_dep_option(object)) 00171 00172 cmd.extend(["-o", object, source]) 00173 00174 # Call cmdline hook 00175 cmd = self.hook.get_cmdline_compiler(cmd) 00176 00177 return [cmd] 00178 00179 def compile_c(self, source, object, includes): 00180 return self.compile(self.cc, source, object, includes) 00181 00182 def compile_cpp(self, source, object, includes): 00183 return self.compile(self.cppc, source, object, includes) 00184 00185 def correct_scatter_shebang(self, scatter_file): 00186 """Correct the shebang at the top of a scatter file. 00187 00188 Positional arguments: 00189 scatter_file -- the scatter file to correct 00190 00191 Return: 00192 The location of the correct scatter file 00193 00194 Side Effects: 00195 This method MAY write a new scatter file to disk 00196 """ 00197 with open(scatter_file, "rb") as input: 00198 lines = input.readlines() 00199 if (lines[0].startswith(self.SHEBANG) or 00200 not lines[0].startswith("#!")): 00201 return scatter_file 00202 else: 00203 new_scatter = join(self.build_dir, ".link_script.sct") 00204 if self.need_update(new_scatter, [scatter_file]): 00205 with open(new_scatter, "wb") as out: 00206 out.write(self.SHEBANG) 00207 out.write("\n") 00208 out.write("".join(lines[1:])) 00209 return new_scatter 00210 00211 @hook_tool 00212 def link(self, output, objects, libraries, lib_dirs, scatter_file): 00213 base, _ = splitext(output) 00214 map_file = base + ".map" 00215 args = ["-o", output, "--info=totals", "--map", "--list=%s" % map_file] 00216 args.extend(objects) 00217 args.extend(libraries) 00218 if lib_dirs: 00219 args.extend(["--userlibpath", ",".join(lib_dirs)]) 00220 if scatter_file: 00221 new_scatter = self.correct_scatter_shebang(scatter_file) 00222 args.extend(["--scatter", new_scatter]) 00223 00224 cmd_pre = self.ld + args 00225 cmd = self.hook.get_cmdline_linker(cmd_pre) 00226 00227 if self.RESPONSE_FILES: 00228 cmd_linker = cmd[0] 00229 link_files = self.get_link_file(cmd[1:]) 00230 cmd = [cmd_linker, '--via', link_files] 00231 00232 self.cc_verbose("Link: %s" % ' '.join(cmd)) 00233 self.default_cmd(cmd) 00234 00235 @hook_tool 00236 def archive(self, objects, lib_path): 00237 if self.RESPONSE_FILES: 00238 param = ['--via', self.get_arch_file(objects)] 00239 else: 00240 param = objects 00241 self.default_cmd([self.ar, '-r', lib_path] + param) 00242 00243 @hook_tool 00244 def binary(self, resources, elf, bin): 00245 _, fmt = splitext(bin) 00246 bin_arg = {".bin": "--bin", ".hex": "--i32"}[fmt] 00247 cmd = [self.elf2bin, bin_arg, '-o', bin, elf] 00248 cmd = self.hook.get_cmdline_binary(cmd) 00249 self.cc_verbose("FromELF: %s" % ' '.join(cmd)) 00250 self.default_cmd(cmd) 00251 00252 @staticmethod 00253 def name_mangle(name): 00254 return "_Z%i%sv" % (len(name), name) 00255 00256 @staticmethod 00257 def make_ld_define(name, value): 00258 return "--predefine=\"-D%s=0x%x\"" % (name, value) 00259 00260 @staticmethod 00261 def redirect_symbol(source, sync, build_dir): 00262 if not exists(build_dir): 00263 makedirs(build_dir) 00264 handle, filename = mkstemp(prefix=".redirect-symbol.", dir=build_dir) 00265 write(handle, "RESOLVE %s AS %s\n" % (source, sync)) 00266 return "--edit=%s" % filename 00267 00268 00269 class ARM_STD(ARM): 00270 def __init__(self, target, notify=None, macros=None, 00271 silent=False, extra_verbose=False, build_profile=None, 00272 build_dir=None): 00273 ARM.__init__(self, target, notify, macros, silent, 00274 build_dir=build_dir, extra_verbose=extra_verbose, 00275 build_profile=build_profile) 00276 if "ARM" not in target.supported_toolchains: 00277 raise NotSupportedException("ARM compiler support is required for ARM build") 00278 00279 00280 class ARM_MICRO(ARM): 00281 PATCHED_LIBRARY = False 00282 def __init__(self, target, notify=None, macros=None, 00283 silent=False, extra_verbose=False, build_profile=None, 00284 build_dir=None): 00285 ARM.__init__(self, target, notify, macros, silent, 00286 build_dir=build_dir, extra_verbose=extra_verbose, 00287 build_profile=build_profile) 00288 if not set(("ARM", "uARM")).intersection(set(target.supported_toolchains)): 00289 raise NotSupportedException("ARM/uARM compiler support is required for ARM build") 00290 00291 class ARMC6(ARM_STD): 00292 SHEBANG = "#! armclang -E --target=arm-arm-none-eabi -x c" 00293 SUPPORTED_CORES = ["Cortex-M0", "Cortex-M0+", "Cortex-M3", "Cortex-M4", 00294 "Cortex-M4F", "Cortex-M7", "Cortex-M7F", "Cortex-M7FD", 00295 "Cortex-M23", "Cortex-M23-NS", "Cortex-M33", 00296 "CortexM33-NS"] 00297 @staticmethod 00298 def check_executable(): 00299 return mbedToolchain.generic_check_executable("ARMC6", "armclang", 1) 00300 00301 def __init__(self, target, *args, **kwargs): 00302 mbedToolchain.__init__(self, target, *args, **kwargs) 00303 if target.core not in self.SUPPORTED_CORES: 00304 raise NotSupportedException( 00305 "this compiler does not support the core %s" % target.core) 00306 00307 if not set(("ARM", "ARMC6")).intersection(set(target.supported_toolchains)): 00308 raise NotSupportedException("ARM/ARMC6 compiler support is required for ARMC6 build") 00309 00310 if target.core.lower().endswith("fd"): 00311 self.flags['common'].append("-mcpu=%s" % target.core.lower()[:-2]) 00312 self.flags['ld'].append("--cpu=%s" % target.core.lower()[:-2]) 00313 elif target.core.lower().endswith("f"): 00314 self.flags['common'].append("-mcpu=%s" % target.core.lower()[:-1]) 00315 self.flags['ld'].append("--cpu=%s" % target.core.lower()[:-1]) 00316 elif target.core.lower().endswith("ns"): 00317 self.flags['common'].append("-mcpu=%s" % target.core.lower()[:-3]) 00318 self.flags['ld'].append("--cpu=%s" % target.core.lower()[:-3]) 00319 else: 00320 self.flags['common'].append("-mcpu=%s" % target.core.lower()) 00321 self.flags['ld'].append("--cpu=%s" % target.core.lower()) 00322 00323 if target.core == "Cortex-M4F": 00324 self.flags['common'].append("-mfpu=fpv4-sp-d16") 00325 self.flags['common'].append("-mfloat-abi=hard") 00326 elif target.core == "Cortex-M7F": 00327 self.flags['common'].append("-mfpu=fpv5-sp-d16") 00328 self.flags['common'].append("-mfloat-abi=softfp") 00329 elif target.core == "Cortex-M7FD": 00330 self.flags['common'].append("-mfpu=fpv5-d16") 00331 self.flags['common'].append("-mfloat-abi=softfp") 00332 elif target.core.startswith("Cortex-M23"): 00333 self.flags['common'].append("-march=armv8-m.base") 00334 elif target.core.startswith("Cortex-M33"): 00335 self.flags['common'].append("-march=armv8-m.main") 00336 00337 if target.core == "Cortex-M23" or target.core == "Cortex-M33": 00338 self.flags['common'].append("-mcmse") 00339 00340 asm_cpu = { 00341 "Cortex-M0+": "Cortex-M0", 00342 "Cortex-M4F": "Cortex-M4.fp", 00343 "Cortex-M7F": "Cortex-M7.fp.sp", 00344 "Cortex-M7FD": "Cortex-M7.fp.dp", 00345 "Cortex-M23-NS": "Cortex-M23", 00346 "Cortex-M33-NS": "Cortex-M33" }.get(target.core, target.core) 00347 00348 self.flags['asm'].append("--cpu=%s" % asm_cpu) 00349 00350 self.cc = ([join(TOOLCHAIN_PATHS["ARMC6"], "armclang")] + 00351 self.flags['common'] + self.flags['c']) 00352 self.cppc = ([join(TOOLCHAIN_PATHS["ARMC6"], "armclang")] + 00353 self.flags['common'] + self.flags['cxx']) 00354 self.asm = [join(TOOLCHAIN_PATHS["ARMC6"], "armasm")] + self.flags['asm'] 00355 self.ld = [join(TOOLCHAIN_PATHS["ARMC6"], "armlink")] + self.flags['ld'] 00356 self.ar = [join(TOOLCHAIN_PATHS["ARMC6"], "armar")] 00357 self.elf2bin = join(TOOLCHAIN_PATHS["ARMC6"], "fromelf") 00358 00359 00360 def parse_dependencies(self, dep_path): 00361 return mbedToolchain.parse_dependencies(self, dep_path) 00362 00363 def is_not_supported_error(self, output): 00364 return "#error [NOT_SUPPORTED]" in output 00365 00366 def parse_output(self, output): 00367 pass 00368 00369 def get_config_option(self, config_header): 00370 return ["-include", config_header] 00371 00372 def get_compile_options(self, defines, includes, for_asm=False): 00373 opts = ['-D%s' % d for d in defines] 00374 opts.extend(["-I%s" % i for i in includes]) 00375 if for_asm: 00376 return ["--cpreproc", 00377 "--cpreproc_opts=%s" % ",".join(self.flags['common'] + opts)] 00378 else: 00379 config_header = self.get_config_header() 00380 if config_header: 00381 opts.extend(self.get_config_option(config_header)) 00382 return opts 00383 00384 @hook_tool 00385 def assemble(self, source, object, includes): 00386 cmd_pre = copy(self.asm) 00387 cmd_pre.extend(self.get_compile_options( 00388 self.get_symbols(True), includes, for_asm=True)) 00389 cmd_pre.extend(["-o", object, source]) 00390 return [self.hook.get_cmdline_assembler(cmd_pre)] 00391 00392 @hook_tool 00393 def compile(self, cc, source, object, includes): 00394 cmd = copy(cc) 00395 cmd.extend(self.get_compile_options(self.get_symbols(), includes)) 00396 cmd.extend(["-o", object, source]) 00397 cmd = self.hook.get_cmdline_compiler(cmd) 00398 return [cmd]
Generated on Sun Jul 17 2022 08:25:18 by 1.7.2