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.
Dependents: BLE_file_test BLE_Blink ExternalEncoder
__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 15:19:13 by
