Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
gcc.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.path import join, basename, splitext, dirname, exists 00019 from distutils.spawn import find_executable 00020 00021 from tools.toolchains import mbedToolchain, TOOLCHAIN_PATHS 00022 from tools.hooks import hook_tool 00023 00024 class GCC(mbedToolchain): 00025 LINKER_EXT = '.ld' 00026 LIBRARY_EXT = '.a' 00027 00028 STD_LIB_NAME = "lib%s.a" 00029 DIAGNOSTIC_PATTERN = re.compile('((?P<file>[^:]+):(?P<line>\d+):)(\d+:)? (?P<severity>warning|[eE]rror|fatal error): (?P<message>.+)') 00030 INDEX_PATTERN = re.compile('(?P<col>\s*)\^') 00031 00032 def __init__(self, target, notify=None, macros=None, 00033 silent=False, extra_verbose=False, build_profile=None, 00034 build_dir=None): 00035 mbedToolchain.__init__(self, target, notify, macros, silent, 00036 extra_verbose=extra_verbose, 00037 build_profile=build_profile, build_dir=build_dir) 00038 00039 tool_path=TOOLCHAIN_PATHS['GCC_ARM'] 00040 # Add flags for current size setting 00041 default_lib = "std" 00042 if hasattr(target, "default_lib"): 00043 default_lib = target.default_lib 00044 elif hasattr(target, "default_build"): # Legacy 00045 default_lib = target.default_build 00046 00047 if default_lib == "small": 00048 self.flags["common"].append("-DMBED_RTOS_SINGLE_THREAD") 00049 self.flags["ld"].append("--specs=nano.specs") 00050 00051 if target.core == "Cortex-M0+": 00052 cpu = "cortex-m0plus" 00053 elif target.core == "Cortex-M4F": 00054 cpu = "cortex-m4" 00055 elif target.core == "Cortex-M7F": 00056 cpu = "cortex-m7" 00057 elif target.core == "Cortex-M7FD": 00058 cpu = "cortex-m7" 00059 elif target.core == "Cortex-M23-NS": 00060 cpu = "cortex-m23" 00061 elif target.core == "Cortex-M33-NS": 00062 cpu = "cortex-m33" 00063 else: 00064 cpu = target.core.lower() 00065 00066 self.cpu = ["-mcpu=%s" % cpu] 00067 if target.core.startswith("Cortex-M"): 00068 self.cpu.append("-mthumb") 00069 00070 # FPU handling, M7 possibly to have double FPU 00071 if target.core == "Cortex-M4F": 00072 self.cpu.append("-mfpu=fpv4-sp-d16") 00073 self.cpu.append("-mfloat-abi=softfp") 00074 elif target.core == "Cortex-M7F": 00075 self.cpu.append("-mfpu=fpv5-sp-d16") 00076 self.cpu.append("-mfloat-abi=softfp") 00077 elif target.core == "Cortex-M7FD": 00078 self.cpu.append("-mfpu=fpv5-d16") 00079 self.cpu.append("-mfloat-abi=softfp") 00080 00081 if target.core == "Cortex-A9": 00082 self.cpu.append("-mthumb-interwork") 00083 self.cpu.append("-marm") 00084 self.cpu.append("-march=armv7-a") 00085 self.cpu.append("-mfpu=vfpv3") 00086 self.cpu.append("-mfloat-abi=hard") 00087 self.cpu.append("-mno-unaligned-access") 00088 00089 if target.core.startswith("Cortex-M23"): 00090 self.cpu.append("-march=armv8-m.base") 00091 elif target.core.startswith("Cortex-M33"): 00092 self.cpu.append("-march=armv8-m.main") 00093 00094 if target.core == "Cortex-M23" or target.core == "Cortex-M33": 00095 self.cpu.append("-mcmse") 00096 00097 self.flags["common"] += self.cpu 00098 00099 main_cc = join(tool_path, "arm-none-eabi-gcc") 00100 main_cppc = join(tool_path, "arm-none-eabi-g++") 00101 self.asm = [main_cc] + self.flags['asm'] + self.flags["common"] 00102 self.cc = [main_cc] 00103 self.cppc =[main_cppc] 00104 self.cc += self.flags['c'] + self.flags['common'] 00105 self.cppc += self.flags['cxx'] + self.flags['common'] 00106 00107 self.flags['ld'] += self.cpu 00108 self.ld = [join(tool_path, "arm-none-eabi-gcc")] + self.flags['ld'] 00109 self.sys_libs = ["stdc++", "supc++", "m", "c", "gcc", "nosys"] 00110 self.preproc = [join(tool_path, "arm-none-eabi-cpp"), "-E", "-P"] 00111 00112 self.ar = join(tool_path, "arm-none-eabi-ar") 00113 self.elf2bin = join(tool_path, "arm-none-eabi-objcopy") 00114 00115 def is_not_supported_error(self, output): 00116 return "error: #error [NOT_SUPPORTED]" in output 00117 00118 def parse_output(self, output): 00119 # The warning/error notification is multiline 00120 msg = None 00121 for line in output.splitlines(): 00122 match = self.DIAGNOSTIC_PATTERN.search(line) 00123 if match is not None: 00124 if msg is not None: 00125 self.cc_info(msg) 00126 msg = None 00127 msg = { 00128 'severity': match.group('severity').lower(), 00129 'file': match.group('file'), 00130 'line': match.group('line'), 00131 'col': 0, 00132 'message': match.group('message'), 00133 'text': '', 00134 'target_name': self.target.name, 00135 'toolchain_name': self.name 00136 } 00137 elif msg is not None: 00138 # Determine the warning/error column by calculating the ^ position 00139 match = self.INDEX_PATTERN.match(line) 00140 if match is not None: 00141 msg['col'] = len(match.group('col')) 00142 self.cc_info(msg) 00143 msg = None 00144 else: 00145 msg['text'] += line+"\n" 00146 00147 if msg is not None: 00148 self.cc_info(msg) 00149 00150 def get_dep_option(self, object): 00151 base, _ = splitext(object) 00152 dep_path = base + '.d' 00153 return ["-MD", "-MF", dep_path] 00154 00155 def get_config_option(self, config_header): 00156 return ['-include', config_header] 00157 00158 def get_compile_options(self, defines, includes, for_asm=False): 00159 opts = ['-D%s' % d for d in defines] 00160 if self.RESPONSE_FILES: 00161 opts += ['@%s' % self.get_inc_file(includes)] 00162 else: 00163 opts += ["-I%s" % i for i in includes] 00164 00165 if not for_asm: 00166 config_header = self.get_config_header() 00167 if config_header is not None: 00168 opts = opts + self.get_config_option(config_header) 00169 return opts 00170 00171 @hook_tool 00172 def assemble(self, source, object, includes): 00173 # Build assemble command 00174 cmd = self.asm + self.get_compile_options(self.get_symbols(True), includes) + ["-o", object, source] 00175 00176 # Call cmdline hook 00177 cmd = self.hook.get_cmdline_assembler(cmd) 00178 00179 # Return command array, don't execute 00180 return [cmd] 00181 00182 @hook_tool 00183 def compile(self, cc, source, object, includes): 00184 # Build compile command 00185 cmd = cc + self.get_compile_options(self.get_symbols(), includes) 00186 00187 cmd.extend(self.get_dep_option(object)) 00188 00189 cmd.extend(["-o", object, source]) 00190 00191 # Call cmdline hook 00192 cmd = self.hook.get_cmdline_compiler(cmd) 00193 00194 return [cmd] 00195 00196 def compile_c(self, source, object, includes): 00197 return self.compile(self.cc, source, object, includes) 00198 00199 def compile_cpp(self, source, object, includes): 00200 return self.compile(self.cppc, source, object, includes) 00201 00202 @hook_tool 00203 def link(self, output, objects, libraries, lib_dirs, mem_map): 00204 libs = [] 00205 for l in libraries: 00206 name, _ = splitext(basename(l)) 00207 libs.append("-l%s" % name[3:]) 00208 libs.extend(["-l%s" % l for l in self.sys_libs]) 00209 00210 # Preprocess 00211 if mem_map: 00212 preproc_output = join(dirname(output), ".link_script.ld") 00213 cmd = (self.preproc + [mem_map] + self.ld[1:] + 00214 [ "-o", preproc_output]) 00215 self.cc_verbose("Preproc: %s" % ' '.join(cmd)) 00216 self.default_cmd(cmd) 00217 mem_map = preproc_output 00218 00219 # Build linker command 00220 map_file = splitext(output)[0] + ".map" 00221 cmd = self.ld + ["-o", output, "-Wl,-Map=%s" % map_file] + objects + ["-Wl,--start-group"] + libs + ["-Wl,--end-group"] 00222 if mem_map: 00223 cmd.extend(['-T', mem_map]) 00224 00225 for L in lib_dirs: 00226 cmd.extend(['-L', L]) 00227 cmd.extend(libs) 00228 00229 # Call cmdline hook 00230 cmd = self.hook.get_cmdline_linker(cmd) 00231 00232 if self.RESPONSE_FILES: 00233 # Split link command to linker executable + response file 00234 cmd_linker = cmd[0] 00235 link_files = self.get_link_file(cmd[1:]) 00236 cmd = [cmd_linker, "@%s" % link_files] 00237 00238 # Exec command 00239 self.cc_verbose("Link: %s" % ' '.join(cmd)) 00240 self.default_cmd(cmd) 00241 00242 @hook_tool 00243 def archive(self, objects, lib_path): 00244 if self.RESPONSE_FILES: 00245 param = ["@%s" % self.get_arch_file(objects)] 00246 else: 00247 param = objects 00248 00249 # Exec command 00250 self.default_cmd([self.ar, 'rcs', lib_path] + param) 00251 00252 @hook_tool 00253 def binary(self, resources, elf, bin): 00254 # Build binary command 00255 _, fmt = splitext(bin) 00256 bin_arg = {'.bin': 'binary', '.hex': 'ihex'}[fmt] 00257 cmd = [self.elf2bin, "-O", bin_arg, elf, bin] 00258 00259 # Call cmdline hook 00260 cmd = self.hook.get_cmdline_binary(cmd) 00261 00262 # Exec command 00263 self.cc_verbose("FromELF: %s" % ' '.join(cmd)) 00264 self.default_cmd(cmd) 00265 00266 @staticmethod 00267 def name_mangle(name): 00268 return "_Z%i%sv" % (len(name), name) 00269 00270 @staticmethod 00271 def make_ld_define(name, value): 00272 return "-D%s=0x%x" % (name, value) 00273 00274 @staticmethod 00275 def redirect_symbol(source, sync, build_dir): 00276 return "-Wl,--defsym=%s=%s" % (source, sync) 00277 00278 @staticmethod 00279 def check_executable(): 00280 """Returns True if the executable (arm-none-eabi-gcc) location 00281 specified by the user exists OR the executable can be found on the PATH. 00282 Returns False otherwise.""" 00283 if not TOOLCHAIN_PATHS['GCC_ARM'] or not exists(TOOLCHAIN_PATHS['GCC_ARM']): 00284 if find_executable('arm-none-eabi-gcc'): 00285 TOOLCHAIN_PATHS['GCC_ARM'] = '' 00286 return True 00287 else: 00288 return False 00289 else: 00290 exec_name = join(TOOLCHAIN_PATHS['GCC_ARM'], 'arm-none-eabi-gcc') 00291 return exists(exec_name) or exists(exec_name + '.exe') 00292 00293 class GCC_ARM(GCC): 00294 pass
Generated on Sun Jul 17 2022 08:25:23 by 1.7.2