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: mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510
__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 # to be preprocessed with armcc 00159 asm_flag_string = '--cpreproc --cpreproc_opts=-D__ASSERT_MSG,' + \ 00160 ",".join(flags['asm_flags']) 00161 flags['asm_flags'] = asm_flag_string 00162 # All non-asm flags are in one template field 00163 c_flags = list(set(flags['c_flags'] + flags['cxx_flags'] +flags['common_flags'])) 00164 # These flags are in template to be set by user i n IDE 00165 template = ["--no_vla", "--cpp", "--c99"] 00166 # Flag is invalid if set in template 00167 # Optimizations are also set in the template 00168 invalid_flag = lambda x: x in template or re.match("-O(\d|time)", x) 00169 flags['c_flags'] = [flag for flag in c_flags if not invalid_flag(flag)] 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] = sorted(list(self.uv_files (files)), 00178 key=lambda (_, __, name): name.lower()) 00179 return grouped 00180 00181 def generate (self): 00182 """Generate the .uvproj file""" 00183 cache = Cache(True, False) 00184 if cache_d: 00185 cache.cache_descriptors() 00186 00187 srcs = self.resources.headers + self.resources.s_sources + \ 00188 self.resources.c_sources + self.resources.cpp_sources + \ 00189 self.resources.objects + self.resources.libraries 00190 ctx = { 00191 'name': self.project_name, 00192 # project_files => dict of generators - file group to generator of 00193 # UVFile tuples defined above 00194 'project_files': sorted(list(self.format_src (srcs).iteritems()), 00195 key=lambda (group, _): group.lower()), 00196 'linker_script':self.resources.linker_script, 00197 'include_paths': '; '.join(self.resources.inc_dirs).encode('utf-8'), 00198 'device': DeviceUvision(self.target), 00199 } 00200 # Turn on FPU optimizations if the core has an FPU 00201 ctx['fpu_setting'] = 1 if 'f' not in ctx['device'].core.lower() \ 00202 or 'd' in ctx['device'].core.lower() else 2 00203 ctx.update(self.format_flags ()) 00204 self.gen_file('uvision/uvision.tmpl', ctx, self.project_name+".uvprojx") 00205 self.gen_file('uvision/uvision_debug.tmpl', ctx, self.project_name + ".uvoptx") 00206 00207 @staticmethod 00208 def build (project_name, log_name='build_log.txt', cleanup=True): 00209 """ Build Uvision project """ 00210 # > UV4 -r -j0 -o [log_name] [project_name].uvprojx 00211 proj_file = project_name + ".uvprojx" 00212 cmd = ['UV4', '-r', '-j0', '-o', log_name, proj_file] 00213 00214 # Build the project 00215 p = Popen(cmd, stdout=PIPE, stderr=PIPE) 00216 out, err = p.communicate() 00217 ret_code = p.returncode 00218 00219 # Print the log file to stdout 00220 with open(log_name, 'r') as f: 00221 print f.read() 00222 00223 # Cleanup the exported and built files 00224 if cleanup: 00225 os.remove(log_name) 00226 os.remove(project_name+".uvprojx") 00227 os.remove(project_name+".uvoptx") 00228 # legacy .build directory cleaned if exists 00229 if exists('.build'): 00230 shutil.rmtree('.build') 00231 if exists('BUILD'): 00232 shutil.rmtree('BUILD') 00233 00234 # Returns 0 upon success, 1 upon a warning, and neither upon an error 00235 if ret_code != 0 and ret_code != 1: 00236 # Seems like something went wrong. 00237 return -1 00238 else: 00239 return 0
Generated on Tue Jul 12 2022 11:02:28 by
1.7.2