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-sdk-tools 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 import shutil 00007 from subprocess import Popen, PIPE 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 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 = 'uvision5' 00121 TOOLCHAIN = 'ARM' 00122 TARGETS = [] 00123 for target, obj in TARGET_MAP.iteritems(): 00124 if not ("ARM" in obj.supported_toolchains and hasattr(obj, "device_name")): 00125 continue 00126 if not DeviceCMSIS.check_supported(target): 00127 continue 00128 TARGETS.append(target) 00129 #File associations within .uvprojx file 00130 file_types = {'.cpp': 8, '.c': 1, '.s': 2, 00131 '.obj': 3, '.o': 3, '.lib': 4, 00132 '.ar': 4, '.h': 5, '.hpp': 5, '.sct': 4} 00133 00134 def uv_files (self, files): 00135 """An generator containing Uvision specific information about project files 00136 Positional Arguments: 00137 files - the location of source files 00138 00139 .uvprojx XML for project file: 00140 <File> 00141 <FileType>{{file.type}}</FileType> 00142 <FileName>{{file.name}}</FileName> 00143 <FilePath>{{file.loc}}</FilePath> 00144 </File> 00145 """ 00146 for loc in files: 00147 #Encapsulates the information necessary for template entry above 00148 UVFile = namedtuple('UVFile', ['type','loc','name']) 00149 _, ext = os.path.splitext(loc) 00150 if ext.lower() in self.file_types : 00151 type = self.file_types [ext.lower()] 00152 name = ntpath.basename(normpath(loc)) 00153 yield UVFile(type, loc, name) 00154 00155 def format_flags (self): 00156 """Format toolchain flags for Uvision""" 00157 flags = copy.deepcopy(self.flags) 00158 asm_flag_string = '--cpreproc --cpreproc_opts=-D__ASSERT_MSG,' + \ 00159 ",".join(flags['asm_flags']) 00160 # asm flags only, common are not valid within uvision project, 00161 # they are armcc specific 00162 flags['asm_flags'] = asm_flag_string 00163 # cxx flags included, as uvision have them all in one tab 00164 flags['c_flags'] = list(set(['-D__ASSERT_MSG'] 00165 + flags['common_flags'] 00166 + flags['c_flags'] 00167 + flags['cxx_flags'])) 00168 # not compatible with c99 flag set in the template 00169 try: flags['c_flags'].remove("--c99") 00170 except ValueError: pass 00171 # cpp is not required as it's implicit for cpp files 00172 try: flags['c_flags'].remove("--cpp") 00173 except ValueError: pass 00174 # we want no-vla for only cxx, but it's also applied for C in IDE, 00175 # thus we remove it 00176 try: flags['c_flags'].remove("--no_vla") 00177 except ValueError: pass 00178 flags['c_flags'] =" ".join(flags['c_flags']) 00179 return flags 00180 00181 def format_src (self, srcs): 00182 """Make sources into the named tuple for use in the template""" 00183 grouped = self.group_project_files(srcs) 00184 for group, files in grouped.items(): 00185 grouped[group] = self.uv_files (files) 00186 return grouped 00187 00188 def generate (self): 00189 """Generate the .uvproj file""" 00190 cache = Cache(True, False) 00191 if cache_d: 00192 cache.cache_descriptors() 00193 00194 srcs = self.resources.headers + self.resources.s_sources + \ 00195 self.resources.c_sources + self.resources.cpp_sources + \ 00196 self.resources.objects + self.resources.libraries 00197 ctx = { 00198 'name': self.project_name, 00199 # project_files => dict of generators - file group to generator of 00200 # UVFile tuples defined above 00201 'project_files': self.format_src (srcs), 00202 'linker_script':self.resources.linker_script, 00203 'include_paths': '; '.join(self.resources.inc_dirs).encode('utf-8'), 00204 'device': DeviceUvision(self.target), 00205 } 00206 # Turn on FPU optimizations if the core has an FPU 00207 ctx['fpu_setting'] = 1 if 'f' not in ctx['device'].core.lower() \ 00208 or 'd' in ctx['device'].core.lower() else 2 00209 ctx.update(self.format_flags ()) 00210 self.gen_file('uvision/uvision.tmpl', ctx, self.project_name+".uvprojx") 00211 self.gen_file('uvision/uvision_debug.tmpl', ctx, self.project_name + ".uvoptx") 00212 00213 @staticmethod 00214 def build (project_name, log_name='build_log.txt', cleanup=True): 00215 """ Build Uvision project """ 00216 # > UV4 -r -j0 -o [log_name] [project_name].uvprojx 00217 proj_file = project_name + ".uvprojx" 00218 cmd = ['UV4', '-r', '-j0', '-o', log_name, proj_file] 00219 00220 # Build the project 00221 p = Popen(cmd, stdout=PIPE, stderr=PIPE) 00222 out, err = p.communicate() 00223 ret_code = p.returncode 00224 00225 # Print the log file to stdout 00226 with open(log_name, 'r') as f: 00227 print f.read() 00228 00229 # Cleanup the exported and built files 00230 if cleanup: 00231 os.remove(log_name) 00232 os.remove(project_name+".uvprojx") 00233 os.remove(project_name+".uvoptx") 00234 # legacy .build directory cleaned if exists 00235 if exists('.build'): 00236 shutil.rmtree('.build') 00237 if exists('BUILD'): 00238 shutil.rmtree('BUILD') 00239 00240 # Returns 0 upon success, 1 upon a warning, and neither upon an error 00241 if ret_code != 0 and ret_code != 1: 00242 # Seems like something went wrong. 00243 return -1 00244 else: 00245 return 0
Generated on Tue Jul 12 2022 21:14:58 by
1.7.2
