mbed os with nrf51 internal bandgap enabled to read battery level

Dependents:   BLE_file_test BLE_Blink ExternalEncoder

Committer:
elessair
Date:
Sun Oct 23 15:10:02 2016 +0000
Revision:
0:f269e3021894
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
elessair 0:f269e3021894 1 import os
elessair 0:f269e3021894 2 from os.path import sep, normpath, join, exists
elessair 0:f269e3021894 3 import ntpath
elessair 0:f269e3021894 4 import copy
elessair 0:f269e3021894 5 from collections import namedtuple
elessair 0:f269e3021894 6 from distutils.spawn import find_executable
elessair 0:f269e3021894 7 import subprocess
elessair 0:f269e3021894 8 import re
elessair 0:f269e3021894 9
elessair 0:f269e3021894 10 from tools.arm_pack_manager import Cache
elessair 0:f269e3021894 11 from tools.targets import TARGET_MAP
elessair 0:f269e3021894 12 from tools.export.exporters import Exporter, FailedBuildException
elessair 0:f269e3021894 13 from tools.export.cmsis import DeviceCMSIS
elessair 0:f269e3021894 14
elessair 0:f269e3021894 15 cache_d = False
elessair 0:f269e3021894 16
elessair 0:f269e3021894 17
elessair 0:f269e3021894 18 class DeviceUvision(DeviceCMSIS):
elessair 0:f269e3021894 19 """Uvision Device class, inherits CMSIS Device class
elessair 0:f269e3021894 20
elessair 0:f269e3021894 21 Encapsulates information necessary for uvision project targets"""
elessair 0:f269e3021894 22 def __init__(self, target):
elessair 0:f269e3021894 23 DeviceCMSIS.__init__(self, target)
elessair 0:f269e3021894 24 dev_format = "$$Device:{0}${1}"
elessair 0:f269e3021894 25 self.svd = ''
elessair 0:f269e3021894 26 if self.debug_svd:
elessair 0:f269e3021894 27 self.svd = dev_format.format(self.dname, self.debug_svd)
elessair 0:f269e3021894 28 self.reg_file = dev_format.format(self.dname, self.compile_header)
elessair 0:f269e3021894 29 self.debug_interface = self.uv_debug()
elessair 0:f269e3021894 30 self.flash_dll = self.generate_flash_dll()
elessair 0:f269e3021894 31
elessair 0:f269e3021894 32 def uv_debug(self):
elessair 0:f269e3021894 33 """Return a namedtuple of information about uvision debug settings"""
elessair 0:f269e3021894 34 UVDebug = namedtuple('UVDebug',['bin_loc','core_flag', 'key'])
elessair 0:f269e3021894 35
elessair 0:f269e3021894 36 # CortexMXn => pCMX
elessair 0:f269e3021894 37 cpu = self.core.replace("Cortex-", "C")
elessair 0:f269e3021894 38 cpu = cpu.replace("+", "")
elessair 0:f269e3021894 39 cpu = cpu.replace("F", "")
elessair 0:f269e3021894 40 cpu_flag = "p"+cpu
elessair 0:f269e3021894 41
elessair 0:f269e3021894 42 # Locations found in Keil_v5/TOOLS.INI
elessair 0:f269e3021894 43 debuggers = {"st-link": ('STLink\\ST-LINKIII-KEIL_SWO.dll', 'ST-LINKIII-KEIL_SWO'),
elessair 0:f269e3021894 44 "j-link":('Segger\\JL2CM3.dll', 'JL2CM3'),
elessair 0:f269e3021894 45 "cmsis-dap":('BIN\\CMSIS_AGDI.dll', 'CMSIS_AGDI'),
elessair 0:f269e3021894 46 "nulink":('NULink\\Nu_Link.dll','Nu_Link')}
elessair 0:f269e3021894 47 res = debuggers[self.debug.lower()]
elessair 0:f269e3021894 48 binary = res[0]
elessair 0:f269e3021894 49 key = res[1]
elessair 0:f269e3021894 50
elessair 0:f269e3021894 51 return UVDebug(binary, cpu_flag, key)
elessair 0:f269e3021894 52
elessair 0:f269e3021894 53 def generate_flash_dll(self):
elessair 0:f269e3021894 54 '''Flash DLL string from uvision
elessair 0:f269e3021894 55 S = SW/JTAG Clock ID
elessair 0:f269e3021894 56 C = CPU index in JTAG chain
elessair 0:f269e3021894 57 P = Access Port
elessair 0:f269e3021894 58 For the Options for Target -> Debug tab -> settings -> "Flash" tab in the dialog:
elessair 0:f269e3021894 59 FD = RAM Start for Flash Functions
elessair 0:f269e3021894 60 FC = RAM Size for Flash Functions
elessair 0:f269e3021894 61 FN = Number of Flash types
elessair 0:f269e3021894 62 FF = Flash File Name (without an extension)
elessair 0:f269e3021894 63 FS = Start Address of the Flash Device
elessair 0:f269e3021894 64 FL = Size of the Flash Device
elessair 0:f269e3021894 65 FP = Full path to the Device algorithm (RTE)
elessair 0:f269e3021894 66
elessair 0:f269e3021894 67 Necessary to flash some targets. Info gathered from algorithms field of pdsc file.
elessair 0:f269e3021894 68 '''
elessair 0:f269e3021894 69 fl_count = 0
elessair 0:f269e3021894 70 def get_mem_no_x(mem_str):
elessair 0:f269e3021894 71 mem_reg = "\dx(\w+)"
elessair 0:f269e3021894 72 m = re.search(mem_reg, mem_str)
elessair 0:f269e3021894 73 return m.group(1) if m else None
elessair 0:f269e3021894 74
elessair 0:f269e3021894 75 RAMS = [(get_mem_no_x(info["start"]), get_mem_no_x(info["size"]))
elessair 0:f269e3021894 76 for mem, info in self.target_info["memory"].items() if "RAM" in mem]
elessair 0:f269e3021894 77 format_str = "UL2CM3(-S0 -C0 -P0 -FD{ramstart}"+" -FC{ramsize} "+"-FN{num_algos} {extra_flags})"
elessair 0:f269e3021894 78 ramstart = ''
elessair 0:f269e3021894 79 #Default according to Keil developer
elessair 0:f269e3021894 80 ramsize = '1000'
elessair 0:f269e3021894 81 if len(RAMS)>=1:
elessair 0:f269e3021894 82 ramstart = RAMS[0][0]
elessair 0:f269e3021894 83 extra_flags = []
elessair 0:f269e3021894 84 for name, info in self.target_info["algorithm"].items():
elessair 0:f269e3021894 85 if not name or not info:
elessair 0:f269e3021894 86 continue
elessair 0:f269e3021894 87 if int(info["default"])==0:
elessair 0:f269e3021894 88 continue
elessair 0:f269e3021894 89 name_reg = "\w*/([\w_]+)\.flm"
elessair 0:f269e3021894 90 m = re.search(name_reg, name.lower())
elessair 0:f269e3021894 91 fl_name = m.group(1) if m else None
elessair 0:f269e3021894 92 name_flag = "-FF" + str(fl_count) + fl_name
elessair 0:f269e3021894 93
elessair 0:f269e3021894 94 start, size = get_mem_no_x(info["start"]), get_mem_no_x(info["size"])
elessair 0:f269e3021894 95 rom_start_flag = "-FS"+str(fl_count)+str(start)
elessair 0:f269e3021894 96 rom_size_flag = "-FL" + str(fl_count) + str(size)
elessair 0:f269e3021894 97
elessair 0:f269e3021894 98 if info["ramstart"] is not None and info["ramsize"] is not None:
elessair 0:f269e3021894 99 ramstart = get_mem_no_x(info["ramstart"])
elessair 0:f269e3021894 100 ramsize = get_mem_no_x(info["ramsize"])
elessair 0:f269e3021894 101
elessair 0:f269e3021894 102 path_flag = "-FP" + str(fl_count) + "($$Device:"+self.dname+"$"+name+")"
elessair 0:f269e3021894 103
elessair 0:f269e3021894 104 extra_flags.extend([name_flag, rom_start_flag, rom_size_flag, path_flag])
elessair 0:f269e3021894 105 fl_count += 1
elessair 0:f269e3021894 106
elessair 0:f269e3021894 107 extra = " ".join(extra_flags)
elessair 0:f269e3021894 108 return format_str.format(ramstart=ramstart,
elessair 0:f269e3021894 109 ramsize=ramsize,
elessair 0:f269e3021894 110 extra_flags=extra, num_algos=fl_count)
elessair 0:f269e3021894 111
elessair 0:f269e3021894 112
elessair 0:f269e3021894 113 class Uvision(Exporter):
elessair 0:f269e3021894 114 """Keil Uvision class
elessair 0:f269e3021894 115
elessair 0:f269e3021894 116 This class encapsulates information to be contained in a Uvision
elessair 0:f269e3021894 117 project file (.uvprojx).
elessair 0:f269e3021894 118 The needed information can be viewed in uvision.tmpl
elessair 0:f269e3021894 119 """
elessair 0:f269e3021894 120 NAME = 'cmsis'
elessair 0:f269e3021894 121 TOOLCHAIN = 'ARM'
elessair 0:f269e3021894 122 TARGETS = [target for target, obj in TARGET_MAP.iteritems()
elessair 0:f269e3021894 123 if "ARM" in obj.supported_toolchains]
elessair 0:f269e3021894 124 #File associations within .uvprojx file
elessair 0:f269e3021894 125 file_types = {'.cpp': 8, '.c': 1, '.s': 2,
elessair 0:f269e3021894 126 '.obj': 3, '.o': 3, '.lib': 4,
elessair 0:f269e3021894 127 '.ar': 4, '.h': 5, '.sct': 4}
elessair 0:f269e3021894 128
elessair 0:f269e3021894 129 def uv_file(self, loc):
elessair 0:f269e3021894 130 """Return a namedtuple of information about project file
elessair 0:f269e3021894 131 Positional Arguments:
elessair 0:f269e3021894 132 loc - the file's location
elessair 0:f269e3021894 133
elessair 0:f269e3021894 134 .uvprojx XML for project file:
elessair 0:f269e3021894 135 <File>
elessair 0:f269e3021894 136 <FileType>{{file.type}}</FileType>
elessair 0:f269e3021894 137 <FileName>{{file.name}}</FileName>
elessair 0:f269e3021894 138 <FilePath>{{file.loc}}</FilePath>
elessair 0:f269e3021894 139 </File>
elessair 0:f269e3021894 140 """
elessair 0:f269e3021894 141 UVFile = namedtuple('UVFile', ['type','loc','name'])
elessair 0:f269e3021894 142 _, ext = os.path.splitext(loc)
elessair 0:f269e3021894 143 type = self.file_types[ext.lower()]
elessair 0:f269e3021894 144 name = ntpath.basename(normpath(loc))
elessair 0:f269e3021894 145 return UVFile(type, loc, name)
elessair 0:f269e3021894 146
elessair 0:f269e3021894 147 def format_flags(self):
elessair 0:f269e3021894 148 """Format toolchain flags for Uvision"""
elessair 0:f269e3021894 149 flags = copy.deepcopy(self.flags)
elessair 0:f269e3021894 150 asm_flag_string = '--cpreproc --cpreproc_opts=-D__ASSERT_MSG,' + \
elessair 0:f269e3021894 151 ",".join(flags['asm_flags'])
elessair 0:f269e3021894 152 # asm flags only, common are not valid within uvision project,
elessair 0:f269e3021894 153 # they are armcc specific
elessair 0:f269e3021894 154 flags['asm_flags'] = asm_flag_string
elessair 0:f269e3021894 155 # cxx flags included, as uvision have them all in one tab
elessair 0:f269e3021894 156 flags['c_flags'] = list(set(['-D__ASSERT_MSG']
elessair 0:f269e3021894 157 + flags['common_flags']
elessair 0:f269e3021894 158 + flags['c_flags']
elessair 0:f269e3021894 159 + flags['cxx_flags']))
elessair 0:f269e3021894 160 # not compatible with c99 flag set in the template
elessair 0:f269e3021894 161 try: flags['c_flags'].remove("--c99")
elessair 0:f269e3021894 162 except ValueError: pass
elessair 0:f269e3021894 163 # cpp is not required as it's implicit for cpp files
elessair 0:f269e3021894 164 try: flags['c_flags'].remove("--cpp")
elessair 0:f269e3021894 165 except ValueError: pass
elessair 0:f269e3021894 166 # we want no-vla for only cxx, but it's also applied for C in IDE,
elessair 0:f269e3021894 167 # thus we remove it
elessair 0:f269e3021894 168 try: flags['c_flags'].remove("--no_vla")
elessair 0:f269e3021894 169 except ValueError: pass
elessair 0:f269e3021894 170 flags['c_flags'] =" ".join(flags['c_flags'])
elessair 0:f269e3021894 171 return flags
elessair 0:f269e3021894 172
elessair 0:f269e3021894 173 def format_src(self, srcs):
elessair 0:f269e3021894 174 """Make sources into the named tuple for use in the template"""
elessair 0:f269e3021894 175 grouped = self.group_project_files(srcs)
elessair 0:f269e3021894 176 for group, files in grouped.items():
elessair 0:f269e3021894 177 grouped[group] = [self.uv_file(src) for src in files]
elessair 0:f269e3021894 178 return grouped
elessair 0:f269e3021894 179
elessair 0:f269e3021894 180 def generate(self):
elessair 0:f269e3021894 181 """Generate the .uvproj file"""
elessair 0:f269e3021894 182 cache = Cache(True, False)
elessair 0:f269e3021894 183 if cache_d:
elessair 0:f269e3021894 184 cache.cache_descriptors()
elessair 0:f269e3021894 185
elessair 0:f269e3021894 186 srcs = self.resources.headers + self.resources.s_sources + \
elessair 0:f269e3021894 187 self.resources.c_sources + self.resources.cpp_sources + \
elessair 0:f269e3021894 188 self.resources.objects + self.resources.libraries
elessair 0:f269e3021894 189 ctx = {
elessair 0:f269e3021894 190 'name': self.project_name,
elessair 0:f269e3021894 191 'project_files': self.format_src(srcs),
elessair 0:f269e3021894 192 'linker_script':self.resources.linker_script,
elessair 0:f269e3021894 193 'include_paths': '; '.join(self.resources.inc_dirs).encode('utf-8'),
elessair 0:f269e3021894 194 'device': DeviceUvision(self.target),
elessair 0:f269e3021894 195 }
elessair 0:f269e3021894 196 # Turn on FPU optimizations if the core has an FPU
elessair 0:f269e3021894 197 ctx['fpu_setting'] = 1 if 'f' not in ctx['device'].core.lower() \
elessair 0:f269e3021894 198 or 'd' in ctx['device'].core.lower() else 2
elessair 0:f269e3021894 199 ctx.update(self.format_flags())
elessair 0:f269e3021894 200 self.gen_file('uvision/uvision.tmpl', ctx, self.project_name+".uvprojx")
elessair 0:f269e3021894 201 self.gen_file('uvision/uvision_debug.tmpl', ctx, self.project_name + ".uvoptx")
elessair 0:f269e3021894 202
elessair 0:f269e3021894 203 def build(self):
elessair 0:f269e3021894 204 ERRORLEVEL = {
elessair 0:f269e3021894 205 0: 'success (0 warnings, 0 errors)',
elessair 0:f269e3021894 206 1: 'warnings',
elessair 0:f269e3021894 207 2: 'errors',
elessair 0:f269e3021894 208 3: 'fatal errors',
elessair 0:f269e3021894 209 11: 'cant write to project file',
elessair 0:f269e3021894 210 12: 'device error',
elessair 0:f269e3021894 211 13: 'error writing',
elessair 0:f269e3021894 212 15: 'error reading xml file',
elessair 0:f269e3021894 213 }
elessair 0:f269e3021894 214 success = 0
elessair 0:f269e3021894 215 warn = 1
elessair 0:f269e3021894 216 if find_executable("UV4"):
elessair 0:f269e3021894 217 uv_exe = "UV4.exe"
elessair 0:f269e3021894 218 else:
elessair 0:f269e3021894 219 uv_exe = join('C:', sep,
elessair 0:f269e3021894 220 'Keil_v5', 'UV4', 'UV4.exe')
elessair 0:f269e3021894 221 if not exists(uv_exe):
elessair 0:f269e3021894 222 raise Exception("UV4.exe not found. Add to path.")
elessair 0:f269e3021894 223 cmd = [uv_exe, '-r', '-j0', '-o', join(self.export_dir,'build_log.txt'), join(self.export_dir,self.project_name+".uvprojx")]
elessair 0:f269e3021894 224 ret_code = subprocess.call(cmd)
elessair 0:f269e3021894 225 with open(join(self.export_dir, 'build_log.txt'), 'r') as build_log:
elessair 0:f269e3021894 226 print build_log.read()
elessair 0:f269e3021894 227
elessair 0:f269e3021894 228 if ret_code != success and ret_code != warn:
elessair 0:f269e3021894 229 # Seems like something went wrong.
elessair 0:f269e3021894 230 raise FailedBuildException("Project: %s build failed with the status: %s" % (
elessair 0:f269e3021894 231 self.project_name, ERRORLEVEL.get(ret_code, "Unknown")))
elessair 0:f269e3021894 232 else:
elessair 0:f269e3021894 233 return "Project: %s build succeeded with the status: %s" % (
elessair 0:f269e3021894 234 self.project_name, ERRORLEVEL.get(ret_code, "Unknown"))