Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-os by
__init__.py
00001 import os 00002 from os.path import sep, normpath, join, exists 00003 import ntpath 00004 import copy 00005 from collections import namedtuple 00006 from distutils.spawn import find_executable 00007 import subprocess 00008 import re 00009 00010 from tools.arm_pack_manager import Cache 00011 from tools.targets import TARGET_MAP 00012 from tools.export.exporters import Exporter, FailedBuildException 00013 from tools.export.cmsis import DeviceCMSIS 00014 00015 cache_d = False 00016 00017 00018 class DeviceUvision (DeviceCMSIS ): 00019 """Uvision Device class, inherits CMSIS Device class 00020 00021 Encapsulates information necessary for uvision project targets""" 00022 def __init__(self, target): 00023 DeviceCMSIS.__init__(self, target) 00024 dev_format = "$$Device:{0}${1}" 00025 self.svd = '' 00026 if self.debug_svd: 00027 self.svd = dev_format.format(self.dname, self.debug_svd) 00028 self.reg_file = dev_format.format(self.dname, self.compile_header) 00029 self.debug_interface = self.uv_debug () 00030 self.flash_dll = self.generate_flash_dll () 00031 00032 def uv_debug (self): 00033 """Return a namedtuple of information about uvision debug settings""" 00034 UVDebug = namedtuple('UVDebug',['bin_loc','core_flag', 'key']) 00035 00036 # CortexMXn => pCMX 00037 cpu = self.core.replace("Cortex-", "C") 00038 cpu = cpu.replace("+", "") 00039 cpu = cpu.replace("F", "") 00040 cpu_flag = "p"+cpu 00041 00042 # Locations found in Keil_v5/TOOLS.INI 00043 debuggers = {"st-link": ('STLink\\ST-LINKIII-KEIL_SWO.dll', 'ST-LINKIII-KEIL_SWO'), 00044 "j-link":('Segger\\JL2CM3.dll', 'JL2CM3'), 00045 "cmsis-dap":('BIN\\CMSIS_AGDI.dll', 'CMSIS_AGDI'), 00046 "nulink":('NULink\\Nu_Link.dll','Nu_Link')} 00047 res = debuggers[self.debug.lower()] 00048 binary = res[0] 00049 key = res[1] 00050 00051 return UVDebug(binary, cpu_flag, key) 00052 00053 def generate_flash_dll (self): 00054 '''Flash DLL string from uvision 00055 S = SW/JTAG Clock ID 00056 C = CPU index in JTAG chain 00057 P = Access Port 00058 For the Options for Target -> Debug tab -> settings -> "Flash" tab in the dialog: 00059 FD = RAM Start for Flash Functions 00060 FC = RAM Size for Flash Functions 00061 FN = Number of Flash types 00062 FF = Flash File Name (without an extension) 00063 FS = Start Address of the Flash Device 00064 FL = Size of the Flash Device 00065 FP = Full path to the Device algorithm (RTE) 00066 00067 Necessary to flash some targets. Info gathered from algorithms field of pdsc file. 00068 ''' 00069 fl_count = 0 00070 def get_mem_no_x(mem_str): 00071 mem_reg = "\dx(\w+)" 00072 m = re.search(mem_reg, mem_str) 00073 return m.group(1) if m else None 00074 00075 RAMS = [(get_mem_no_x(info["start"]), get_mem_no_x(info["size"])) 00076 for mem, info in self.target_info["memory"].items() if "RAM" in mem] 00077 format_str = "UL2CM3(-S0 -C0 -P0 -FD{ramstart}"+" -FC{ramsize} "+"-FN{num_algos} {extra_flags})" 00078 ramstart = '' 00079 #Default according to Keil developer 00080 ramsize = '1000' 00081 if len(RAMS)>=1: 00082 ramstart = RAMS[0][0] 00083 extra_flags = [] 00084 for name, info in self.target_info["algorithm"].items(): 00085 if not name or not info: 00086 continue 00087 if int(info["default"])==0: 00088 continue 00089 name_reg = "\w*/([\w_]+)\.flm" 00090 m = re.search(name_reg, name.lower()) 00091 fl_name = m.group(1) if m else None 00092 name_flag = "-FF" + str(fl_count) + fl_name 00093 00094 start, size = get_mem_no_x(info["start"]), get_mem_no_x(info["size"]) 00095 rom_start_flag = "-FS"+str(fl_count)+str(start) 00096 rom_size_flag = "-FL" + str(fl_count) + str(size) 00097 00098 if info["ramstart"] is not None and info["ramsize"] is not None: 00099 ramstart = get_mem_no_x(info["ramstart"]) 00100 ramsize = get_mem_no_x(info["ramsize"]) 00101 00102 path_flag = "-FP" + str(fl_count) + "($$Device:"+self.dname+"$"+name+")" 00103 00104 extra_flags.extend([name_flag, rom_start_flag, rom_size_flag, path_flag]) 00105 fl_count += 1 00106 00107 extra = " ".join(extra_flags) 00108 return format_str.format(ramstart=ramstart, 00109 ramsize=ramsize, 00110 extra_flags=extra, num_algos=fl_count) 00111 00112 00113 class Uvision (Exporter ): 00114 """Keil Uvision class 00115 00116 This class encapsulates information to be contained in a Uvision 00117 project file (.uvprojx). 00118 The needed information can be viewed in uvision.tmpl 00119 """ 00120 NAME = 'cmsis' 00121 TOOLCHAIN = 'ARM' 00122 TARGETS = [target for target, obj in TARGET_MAP.iteritems() 00123 if "ARM" in obj.supported_toolchains] 00124 #File associations within .uvprojx file 00125 file_types = {'.cpp': 8, '.c': 1, '.s': 2, 00126 '.obj': 3, '.o': 3, '.lib': 4, 00127 '.ar': 4, '.h': 5, '.sct': 4} 00128 00129 def uv_file (self, loc): 00130 """Return a namedtuple of information about project file 00131 Positional Arguments: 00132 loc - the file's location 00133 00134 .uvprojx XML for project file: 00135 <File> 00136 <FileType>{{file.type}}</FileType> 00137 <FileName>{{file.name}}</FileName> 00138 <FilePath>{{file.loc}}</FilePath> 00139 </File> 00140 """ 00141 UVFile = namedtuple('UVFile', ['type','loc','name']) 00142 _, ext = os.path.splitext(loc) 00143 type = self.file_types [ext.lower()] 00144 name = ntpath.basename(normpath(loc)) 00145 return UVFile(type, loc, name) 00146 00147 def format_flags (self): 00148 """Format toolchain flags for Uvision""" 00149 flags = copy.deepcopy(self.flags) 00150 asm_flag_string = '--cpreproc --cpreproc_opts=-D__ASSERT_MSG,' + \ 00151 ",".join(flags['asm_flags']) 00152 # asm flags only, common are not valid within uvision project, 00153 # they are armcc specific 00154 flags['asm_flags'] = asm_flag_string 00155 # cxx flags included, as uvision have them all in one tab 00156 flags['c_flags'] = list(set(['-D__ASSERT_MSG'] 00157 + flags['common_flags'] 00158 + flags['c_flags'] 00159 + flags['cxx_flags'])) 00160 # not compatible with c99 flag set in the template 00161 try: flags['c_flags'].remove("--c99") 00162 except ValueError: pass 00163 # cpp is not required as it's implicit for cpp files 00164 try: flags['c_flags'].remove("--cpp") 00165 except ValueError: pass 00166 # we want no-vla for only cxx, but it's also applied for C in IDE, 00167 # thus we remove it 00168 try: flags['c_flags'].remove("--no_vla") 00169 except ValueError: pass 00170 flags['c_flags'] =" ".join(flags['c_flags']) 00171 return flags 00172 00173 def format_src (self, srcs): 00174 """Make sources into the named tuple for use in the template""" 00175 grouped = self.group_project_files(srcs) 00176 for group, files in grouped.items(): 00177 grouped[group] = [self.uv_file (src) for src in files] 00178 return grouped 00179 00180 def generate (self): 00181 """Generate the .uvproj file""" 00182 cache = Cache(True, False) 00183 if cache_d: 00184 cache.cache_descriptors() 00185 00186 srcs = self.resources.headers + self.resources.s_sources + \ 00187 self.resources.c_sources + self.resources.cpp_sources + \ 00188 self.resources.objects + self.resources.libraries 00189 ctx = { 00190 'name': self.project_name, 00191 'project_files': self.format_src (srcs), 00192 'linker_script':self.resources.linker_script, 00193 'include_paths': '; '.join(self.resources.inc_dirs).encode('utf-8'), 00194 'device': DeviceUvision(self.target), 00195 } 00196 # Turn on FPU optimizations if the core has an FPU 00197 ctx['fpu_setting'] = 1 if 'f' not in ctx['device'].core.lower() \ 00198 or 'd' in ctx['device'].core.lower() else 2 00199 ctx.update(self.format_flags ()) 00200 self.gen_file('uvision/uvision.tmpl', ctx, self.project_name+".uvprojx") 00201 self.gen_file('uvision/uvision_debug.tmpl', ctx, self.project_name + ".uvoptx") 00202 00203 def build(self): 00204 ERRORLEVEL = { 00205 0: 'success (0 warnings, 0 errors)', 00206 1: 'warnings', 00207 2: 'errors', 00208 3: 'fatal errors', 00209 11: 'cant write to project file', 00210 12: 'device error', 00211 13: 'error writing', 00212 15: 'error reading xml file', 00213 } 00214 success = 0 00215 warn = 1 00216 if find_executable("UV4"): 00217 uv_exe = "UV4.exe" 00218 else: 00219 uv_exe = join('C:', sep, 00220 'Keil_v5', 'UV4', 'UV4.exe') 00221 if not exists(uv_exe): 00222 raise Exception("UV4.exe not found. Add to path.") 00223 cmd = [uv_exe, '-r', '-j0', '-o', join(self.export_dir,'build_log.txt'), join(self.export_dir,self.project_name+".uvprojx")] 00224 ret_code = subprocess.call(cmd) 00225 with open(join(self.export_dir, 'build_log.txt'), 'r') as build_log: 00226 print build_log.read() 00227 00228 if ret_code != success and ret_code != warn: 00229 # Seems like something went wrong. 00230 raise FailedBuildException("Project: %s build failed with the status: %s" % ( 00231 self.project_name, ERRORLEVEL.get(ret_code, "Unknown"))) 00232 else: 00233 return "Project: %s build succeeded with the status: %s" % ( 00234 self.project_name, ERRORLEVEL.get(ret_code, "Unknown"))
Generated on Tue Jul 12 2022 13:15:13 by
