mbed os with nrf51 internal bandgap enabled to read battery level
Dependents: BLE_file_test BLE_Blink ExternalEncoder
tools/export/cmsis/__init__.py@0:f269e3021894, 2016-10-23 (annotated)
- Committer:
- elessair
- Date:
- Sun Oct 23 15:10:02 2016 +0000
- Revision:
- 0:f269e3021894
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
elessair | 0:f269e3021894 | 1 | import os |
elessair | 0:f269e3021894 | 2 | from os.path import sep, join, exists |
elessair | 0:f269e3021894 | 3 | from itertools import groupby |
elessair | 0:f269e3021894 | 4 | from xml.etree.ElementTree import Element, tostring |
elessair | 0:f269e3021894 | 5 | import ntpath |
elessair | 0:f269e3021894 | 6 | import re |
elessair | 0:f269e3021894 | 7 | import json |
elessair | 0:f269e3021894 | 8 | |
elessair | 0:f269e3021894 | 9 | from tools.arm_pack_manager import Cache |
elessair | 0:f269e3021894 | 10 | from tools.targets import TARGET_MAP |
elessair | 0:f269e3021894 | 11 | from tools.export.exporters import Exporter, TargetNotSupportedException |
elessair | 0:f269e3021894 | 12 | |
elessair | 0:f269e3021894 | 13 | class fileCMSIS(): |
elessair | 0:f269e3021894 | 14 | """CMSIS file class. |
elessair | 0:f269e3021894 | 15 | |
elessair | 0:f269e3021894 | 16 | Encapsulates information necessary for files in cpdsc project file""" |
elessair | 0:f269e3021894 | 17 | file_types = {'.cpp': 'sourceCpp', '.c': 'sourceC', '.s': 'sourceAsm', |
elessair | 0:f269e3021894 | 18 | '.obj': 'object', '.o': 'object', '.lib': 'library', |
elessair | 0:f269e3021894 | 19 | '.ar': 'linkerScript', '.h': 'header', '.sct': 'linkerScript'} |
elessair | 0:f269e3021894 | 20 | |
elessair | 0:f269e3021894 | 21 | def __init__(self, loc, name): |
elessair | 0:f269e3021894 | 22 | #print loc |
elessair | 0:f269e3021894 | 23 | _, ext = os.path.splitext(loc) |
elessair | 0:f269e3021894 | 24 | self.type = self.file_types[ext.lower()] |
elessair | 0:f269e3021894 | 25 | self.loc = loc |
elessair | 0:f269e3021894 | 26 | self.name = name |
elessair | 0:f269e3021894 | 27 | |
elessair | 0:f269e3021894 | 28 | |
elessair | 0:f269e3021894 | 29 | class DeviceCMSIS(): |
elessair | 0:f269e3021894 | 30 | """CMSIS Device class |
elessair | 0:f269e3021894 | 31 | |
elessair | 0:f269e3021894 | 32 | Encapsulates target information retrieved by arm-pack-manager""" |
elessair | 0:f269e3021894 | 33 | def __init__(self, target): |
elessair | 0:f269e3021894 | 34 | cache = Cache(True, False) |
elessair | 0:f269e3021894 | 35 | |
elessair | 0:f269e3021894 | 36 | t = TARGET_MAP[target] |
elessair | 0:f269e3021894 | 37 | self.core = t.core |
elessair | 0:f269e3021894 | 38 | try: |
elessair | 0:f269e3021894 | 39 | cpu_name = t.device_name |
elessair | 0:f269e3021894 | 40 | target_info = cache.index[cpu_name] |
elessair | 0:f269e3021894 | 41 | # Target does not have device name or pdsc file |
elessair | 0:f269e3021894 | 42 | except: |
elessair | 0:f269e3021894 | 43 | try: |
elessair | 0:f269e3021894 | 44 | # Try to find the core as a generic CMSIS target |
elessair | 0:f269e3021894 | 45 | cpu_name = self.cpu_cmsis() |
elessair | 0:f269e3021894 | 46 | target_info = cache.index[cpu_name] |
elessair | 0:f269e3021894 | 47 | except: |
elessair | 0:f269e3021894 | 48 | raise TargetNotSupportedException("Target not in CMSIS packs") |
elessair | 0:f269e3021894 | 49 | |
elessair | 0:f269e3021894 | 50 | self.target_info = target_info |
elessair | 0:f269e3021894 | 51 | |
elessair | 0:f269e3021894 | 52 | self.url = target_info['pdsc_file'] |
elessair | 0:f269e3021894 | 53 | self.pack_url, self.pack_id = ntpath.split(self.url) |
elessair | 0:f269e3021894 | 54 | self.dname = cpu_name |
elessair | 0:f269e3021894 | 55 | self.dfpu = target_info['processor']['fpu'] |
elessair | 0:f269e3021894 | 56 | self.debug, self.dvendor = self.vendor_debug(target_info['vendor']) |
elessair | 0:f269e3021894 | 57 | self.dendian = target_info['processor'].get('endianness','Little-endian') |
elessair | 0:f269e3021894 | 58 | self.debug_svd = target_info.get('debug', '') |
elessair | 0:f269e3021894 | 59 | self.compile_header = target_info['compile']['header'] |
elessair | 0:f269e3021894 | 60 | |
elessair | 0:f269e3021894 | 61 | def check_version(self, filename): |
elessair | 0:f269e3021894 | 62 | with open(filename) as data_file: |
elessair | 0:f269e3021894 | 63 | data = json.load(data_file) |
elessair | 0:f269e3021894 | 64 | return data.get("version", "0") == "0.1.0" |
elessair | 0:f269e3021894 | 65 | |
elessair | 0:f269e3021894 | 66 | def vendor_debug(self, vendor): |
elessair | 0:f269e3021894 | 67 | reg = "([\w\s]+):?\d*?" |
elessair | 0:f269e3021894 | 68 | m = re.search(reg, vendor) |
elessair | 0:f269e3021894 | 69 | vendor_match = m.group(1) if m else None |
elessair | 0:f269e3021894 | 70 | debug_map ={ |
elessair | 0:f269e3021894 | 71 | 'STMicroelectronics':'ST-Link', |
elessair | 0:f269e3021894 | 72 | 'Silicon Labs':'J-LINK', |
elessair | 0:f269e3021894 | 73 | 'Nuvoton':'NULink' |
elessair | 0:f269e3021894 | 74 | } |
elessair | 0:f269e3021894 | 75 | return debug_map.get(vendor_match, "CMSIS-DAP"), vendor_match |
elessair | 0:f269e3021894 | 76 | |
elessair | 0:f269e3021894 | 77 | def cpu_cmsis(self): |
elessair | 0:f269e3021894 | 78 | #Cortex-M4F => ARMCM4_FP, Cortex-M0+ => ARMCM0P |
elessair | 0:f269e3021894 | 79 | cpu = self.core |
elessair | 0:f269e3021894 | 80 | cpu = cpu.replace("Cortex-","ARMC") |
elessair | 0:f269e3021894 | 81 | cpu = cpu.replace("+","P") |
elessair | 0:f269e3021894 | 82 | cpu = cpu.replace("F","_FP") |
elessair | 0:f269e3021894 | 83 | return cpu |
elessair | 0:f269e3021894 | 84 | |
elessair | 0:f269e3021894 | 85 | |
elessair | 0:f269e3021894 | 86 | class CMSIS(Exporter): |
elessair | 0:f269e3021894 | 87 | NAME = 'cmsis' |
elessair | 0:f269e3021894 | 88 | TOOLCHAIN = 'ARM' |
elessair | 0:f269e3021894 | 89 | TARGETS = [target for target, obj in TARGET_MAP.iteritems() |
elessair | 0:f269e3021894 | 90 | if "ARM" in obj.supported_toolchains] |
elessair | 0:f269e3021894 | 91 | |
elessair | 0:f269e3021894 | 92 | def make_key(self, src): |
elessair | 0:f269e3021894 | 93 | """turn a source file into its group name""" |
elessair | 0:f269e3021894 | 94 | key = src.name.split(sep)[0] |
elessair | 0:f269e3021894 | 95 | if key == ".": |
elessair | 0:f269e3021894 | 96 | key = os.path.basename(os.path.realpath(self.export_dir)) |
elessair | 0:f269e3021894 | 97 | return key |
elessair | 0:f269e3021894 | 98 | |
elessair | 0:f269e3021894 | 99 | def group_project_files(self, sources, root_element): |
elessair | 0:f269e3021894 | 100 | """Recursively group the source files by their encompassing directory""" |
elessair | 0:f269e3021894 | 101 | |
elessair | 0:f269e3021894 | 102 | data = sorted(sources, key=self.make_key) |
elessair | 0:f269e3021894 | 103 | for group, files in groupby(data, self.make_key): |
elessair | 0:f269e3021894 | 104 | new_srcs = [] |
elessair | 0:f269e3021894 | 105 | for f in list(files): |
elessair | 0:f269e3021894 | 106 | spl = f.name.split(sep) |
elessair | 0:f269e3021894 | 107 | if len(spl)==2: |
elessair | 0:f269e3021894 | 108 | file_element = Element('file', |
elessair | 0:f269e3021894 | 109 | attrib={ |
elessair | 0:f269e3021894 | 110 | 'category':f.type, |
elessair | 0:f269e3021894 | 111 | 'name': f.loc}) |
elessair | 0:f269e3021894 | 112 | root_element.append(file_element) |
elessair | 0:f269e3021894 | 113 | else: |
elessair | 0:f269e3021894 | 114 | f.name = os.path.join(*spl[1:]) |
elessair | 0:f269e3021894 | 115 | new_srcs.append(f) |
elessair | 0:f269e3021894 | 116 | if new_srcs: |
elessair | 0:f269e3021894 | 117 | group_element = Element('group',attrib={'name':group}) |
elessair | 0:f269e3021894 | 118 | root_element.append(self.group_project_files(new_srcs, |
elessair | 0:f269e3021894 | 119 | group_element)) |
elessair | 0:f269e3021894 | 120 | return root_element |
elessair | 0:f269e3021894 | 121 | |
elessair | 0:f269e3021894 | 122 | def generate(self): |
elessair | 0:f269e3021894 | 123 | |
elessair | 0:f269e3021894 | 124 | srcs = self.resources.headers + self.resources.s_sources + \ |
elessair | 0:f269e3021894 | 125 | self.resources.c_sources + self.resources.cpp_sources + \ |
elessair | 0:f269e3021894 | 126 | self.resources.objects + self.resources.libraries + \ |
elessair | 0:f269e3021894 | 127 | [self.resources.linker_script] |
elessair | 0:f269e3021894 | 128 | srcs = [fileCMSIS(src, src) for src in srcs if src] |
elessair | 0:f269e3021894 | 129 | ctx = { |
elessair | 0:f269e3021894 | 130 | 'name': self.project_name, |
elessair | 0:f269e3021894 | 131 | 'project_files': tostring(self.group_project_files(srcs, Element('files'))), |
elessair | 0:f269e3021894 | 132 | 'device': DeviceCMSIS(self.target), |
elessair | 0:f269e3021894 | 133 | 'date': '' |
elessair | 0:f269e3021894 | 134 | } |
elessair | 0:f269e3021894 | 135 | # TODO: find how to keep prettyxml from adding xml version to this blob |
elessair | 0:f269e3021894 | 136 | #dom = parseString(ctx['project_files']) |
elessair | 0:f269e3021894 | 137 | #ctx['project_files'] = dom.toprettyxml(indent="\t") |
elessair | 0:f269e3021894 | 138 | |
elessair | 0:f269e3021894 | 139 | self.gen_file('cmsis/cpdsc.tmpl', ctx, 'project.cpdsc') |