Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
__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, apply_supported_whitelist 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 00123 POST_BINARY_WHITELIST = set([ 00124 "MCU_NRF51Code.binary_hook", 00125 "TEENSY3_1Code.binary_hook", 00126 "LPCTargetCode.lpc_patch", 00127 "LPC4088Code.binary_hook", 00128 "MTSCode.combine_bins_mts_dot", 00129 "MTSCode.combine_bins_mts_dragonfly", 00130 "NCS36510TargetCode.ncs36510_addfib" 00131 ]) 00132 00133 @classmethod 00134 def is_target_supported (cls, target_name): 00135 target = TARGET_MAP[target_name] 00136 return apply_supported_whitelist( 00137 cls.TOOLCHAIN, cls.POST_BINARY_WHITELIST, target) and\ 00138 DeviceCMSIS.check_supported(target_name) 00139 00140 #File associations within .uvprojx file 00141 file_types = {'.cpp': 8, '.c': 1, '.s': 2, 00142 '.obj': 3, '.o': 3, '.lib': 4, 00143 '.ar': 4, '.h': 5, '.hpp': 5, '.sct': 4} 00144 00145 def uv_files (self, files): 00146 """An generator containing Uvision specific information about project files 00147 Positional Arguments: 00148 files - the location of source files 00149 00150 .uvprojx XML for project file: 00151 <File> 00152 <FileType>{{file.type}}</FileType> 00153 <FileName>{{file.name}}</FileName> 00154 <FilePath>{{file.loc}}</FilePath> 00155 </File> 00156 """ 00157 for loc in files: 00158 #Encapsulates the information necessary for template entry above 00159 UVFile = namedtuple('UVFile', ['type','loc','name']) 00160 _, ext = os.path.splitext(loc) 00161 if ext.lower() in self.file_types : 00162 type = self.file_types [ext.lower()] 00163 name = ntpath.basename(normpath(loc)) 00164 yield UVFile(type, loc, name) 00165 00166 def format_flags (self): 00167 """Format toolchain flags for Uvision""" 00168 flags = copy.deepcopy(self.flags) 00169 # to be preprocessed with armcc 00170 asm_flag_string = ( 00171 '--cpreproc --cpreproc_opts=-D__ASSERT_MSG,' + 00172 ",".join(filter(lambda f: f.startswith("-D"), flags['asm_flags']))) 00173 flags['asm_flags'] = asm_flag_string 00174 # All non-asm flags are in one template field 00175 c_flags = list(set(flags['c_flags'] + flags['cxx_flags'] +flags['common_flags'])) 00176 ld_flags = list(set(flags['ld_flags'] )) 00177 # These flags are in template to be set by user i n IDE 00178 template = ["--no_vla", "--cpp", "--c99"] 00179 # Flag is invalid if set in template 00180 # Optimizations are also set in the template 00181 invalid_flag = lambda x: x in template or re.match("-O(\d|time)", x) 00182 flags['c_flags'] = [flag.replace('"','\\"') for flag in c_flags if not invalid_flag(flag)] 00183 flags['c_flags'] = " ".join(flags['c_flags']) 00184 flags['ld_flags'] = " ".join(flags['ld_flags']) 00185 return flags 00186 00187 def format_src (self, srcs): 00188 """Make sources into the named tuple for use in the template""" 00189 grouped = self.group_project_files(srcs) 00190 for group, files in grouped.items(): 00191 grouped[group] = sorted(list(self.uv_files (files)), 00192 key=lambda (_, __, name): name.lower()) 00193 return grouped 00194 00195 @staticmethod 00196 def format_fpu (core): 00197 """Generate a core's FPU string""" 00198 if core.endswith("FD"): 00199 return "FPU3(DFPU)" 00200 elif core.endswith("F"): 00201 return "FPU2" 00202 else: 00203 return "" 00204 00205 def generate (self): 00206 """Generate the .uvproj file""" 00207 cache = Cache(True, False) 00208 if cache_d: 00209 cache.cache_descriptors() 00210 00211 srcs = self.resources.headers + self.resources.s_sources + \ 00212 self.resources.c_sources + self.resources.cpp_sources + \ 00213 self.resources.objects + self.resources.libraries 00214 ctx = { 00215 'name': self.project_name, 00216 # project_files => dict of generators - file group to generator of 00217 # UVFile tuples defined above 00218 'project_files': sorted(list(self.format_src (srcs).iteritems()), 00219 key=lambda (group, _): group.lower()), 00220 'linker_script':self.toolchain.correct_scatter_shebang( 00221 self.resources.linker_script), 00222 'include_paths': '; '.join(self.resources.inc_dirs).encode('utf-8'), 00223 'device': DeviceUvision(self.target), 00224 } 00225 self.generated_files.append(ctx['linker_script']) 00226 core = ctx['device'].core 00227 ctx['cputype'] = core.rstrip("FD") 00228 if core.endswith("FD"): 00229 ctx['fpu_setting'] = 3 00230 elif core.endswith("F"): 00231 ctx['fpu_setting'] = 2 00232 else: 00233 ctx['fpu_setting'] = 1 00234 ctx['fputype'] = self.format_fpu (core) 00235 ctx.update(self.format_flags ()) 00236 self.gen_file('uvision/uvision.tmpl', ctx, self.project_name+".uvprojx") 00237 self.gen_file('uvision/uvision_debug.tmpl', ctx, self.project_name + ".uvoptx") 00238 00239 @staticmethod 00240 def build (project_name, log_name='build_log.txt', cleanup=True): 00241 """ Build Uvision project """ 00242 # > UV4 -r -j0 -o [log_name] [project_name].uvprojx 00243 proj_file = project_name + ".uvprojx" 00244 cmd = ['UV4', '-r', '-j0', '-o', log_name, proj_file] 00245 00246 # Build the project 00247 p = Popen(cmd, stdout=PIPE, stderr=PIPE) 00248 out, err = p.communicate() 00249 ret_code = p.returncode 00250 00251 # Print the log file to stdout 00252 with open(log_name, 'r') as f: 00253 print f.read() 00254 00255 # Cleanup the exported and built files 00256 if cleanup: 00257 os.remove(log_name) 00258 os.remove(project_name+".uvprojx") 00259 os.remove(project_name+".uvoptx") 00260 # legacy .build directory cleaned if exists 00261 if exists('.build'): 00262 shutil.rmtree('.build') 00263 if exists('BUILD'): 00264 shutil.rmtree('BUILD') 00265 00266 # Returns 0 upon success, 1 upon a warning, and neither upon an error 00267 if ret_code != 0 and ret_code != 1: 00268 # Seems like something went wrong. 00269 return -1 00270 else: 00271 return 0
Generated on Sun Jul 17 2022 08:25:18 by 1.7.2