the other jimmy / mbed-sdk-tools

Fork of mbed-sdk-tools by mbed official

Committer:
The Other Jimmy
Date:
Wed Jan 04 11:58:24 2017 -0600
Revision:
32:8ea194f6145b
Update tools to follow mbed-os tools release 5.3.1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
The Other Jimmy 32:8ea194f6145b 1 import os
The Other Jimmy 32:8ea194f6145b 2 from os.path import sep, join, exists
The Other Jimmy 32:8ea194f6145b 3 from itertools import groupby
The Other Jimmy 32:8ea194f6145b 4 from xml.etree.ElementTree import Element, tostring
The Other Jimmy 32:8ea194f6145b 5 import ntpath
The Other Jimmy 32:8ea194f6145b 6 import re
The Other Jimmy 32:8ea194f6145b 7 import json
The Other Jimmy 32:8ea194f6145b 8
The Other Jimmy 32:8ea194f6145b 9 from tools.arm_pack_manager import Cache
The Other Jimmy 32:8ea194f6145b 10 from tools.targets import TARGET_MAP
The Other Jimmy 32:8ea194f6145b 11 from tools.export.exporters import Exporter, TargetNotSupportedException
The Other Jimmy 32:8ea194f6145b 12
The Other Jimmy 32:8ea194f6145b 13 class fileCMSIS():
The Other Jimmy 32:8ea194f6145b 14 """CMSIS file class.
The Other Jimmy 32:8ea194f6145b 15
The Other Jimmy 32:8ea194f6145b 16 Encapsulates information necessary for files in cpdsc project file"""
The Other Jimmy 32:8ea194f6145b 17 file_types = {'.cpp': 'sourceCpp', '.c': 'sourceC', '.s': 'sourceAsm',
The Other Jimmy 32:8ea194f6145b 18 '.obj': 'object', '.o': 'object', '.lib': 'library',
The Other Jimmy 32:8ea194f6145b 19 '.ar': 'linkerScript', '.h': 'header', '.sct': 'linkerScript'}
The Other Jimmy 32:8ea194f6145b 20
The Other Jimmy 32:8ea194f6145b 21 def __init__(self, loc, name):
The Other Jimmy 32:8ea194f6145b 22 #print loc
The Other Jimmy 32:8ea194f6145b 23 _, ext = os.path.splitext(loc)
The Other Jimmy 32:8ea194f6145b 24 self.type = self.file_types[ext.lower()]
The Other Jimmy 32:8ea194f6145b 25 self.loc = loc
The Other Jimmy 32:8ea194f6145b 26 self.name = name
The Other Jimmy 32:8ea194f6145b 27
The Other Jimmy 32:8ea194f6145b 28
The Other Jimmy 32:8ea194f6145b 29 class DeviceCMSIS():
The Other Jimmy 32:8ea194f6145b 30 """CMSIS Device class
The Other Jimmy 32:8ea194f6145b 31
The Other Jimmy 32:8ea194f6145b 32 Encapsulates target information retrieved by arm-pack-manager"""
The Other Jimmy 32:8ea194f6145b 33
The Other Jimmy 32:8ea194f6145b 34 CACHE = Cache(True, False)
The Other Jimmy 32:8ea194f6145b 35 def __init__(self, target):
The Other Jimmy 32:8ea194f6145b 36 target_info = self.check_supported(target)
The Other Jimmy 32:8ea194f6145b 37 if not target_info:
The Other Jimmy 32:8ea194f6145b 38 raise TargetNotSupportedException("Target not supported in CMSIS pack")
The Other Jimmy 32:8ea194f6145b 39 self.url = target_info['pdsc_file']
The Other Jimmy 32:8ea194f6145b 40 self.pack_url, self.pack_id = ntpath.split(self.url)
The Other Jimmy 32:8ea194f6145b 41 self.dname = target_info["_cpu_name"]
The Other Jimmy 32:8ea194f6145b 42 self.core = target_info["_core"]
The Other Jimmy 32:8ea194f6145b 43 self.dfpu = target_info['processor']['fpu']
The Other Jimmy 32:8ea194f6145b 44 self.debug, self.dvendor = self.vendor_debug(target_info['vendor'])
The Other Jimmy 32:8ea194f6145b 45 self.dendian = target_info['processor'].get('endianness','Little-endian')
The Other Jimmy 32:8ea194f6145b 46 self.debug_svd = target_info.get('debug', '')
The Other Jimmy 32:8ea194f6145b 47 self.compile_header = target_info['compile']['header']
The Other Jimmy 32:8ea194f6145b 48 self.target_info = target_info
The Other Jimmy 32:8ea194f6145b 49
The Other Jimmy 32:8ea194f6145b 50 @staticmethod
The Other Jimmy 32:8ea194f6145b 51 def check_supported(target):
The Other Jimmy 32:8ea194f6145b 52 t = TARGET_MAP[target]
The Other Jimmy 32:8ea194f6145b 53 try:
The Other Jimmy 32:8ea194f6145b 54 cpu_name = t.device_name
The Other Jimmy 32:8ea194f6145b 55 target_info = DeviceCMSIS.CACHE.index[cpu_name]
The Other Jimmy 32:8ea194f6145b 56 # Target does not have device name or pdsc file
The Other Jimmy 32:8ea194f6145b 57 except:
The Other Jimmy 32:8ea194f6145b 58 try:
The Other Jimmy 32:8ea194f6145b 59 # Try to find the core as a generic CMSIS target
The Other Jimmy 32:8ea194f6145b 60 cpu_name = DeviceCMSIS.cpu_cmsis(t.core)
The Other Jimmy 32:8ea194f6145b 61 target_info = DeviceCMSIS.CACHE.index[cpu_name]
The Other Jimmy 32:8ea194f6145b 62 except:
The Other Jimmy 32:8ea194f6145b 63 return False
The Other Jimmy 32:8ea194f6145b 64 target_info["_cpu_name"] = cpu_name
The Other Jimmy 32:8ea194f6145b 65 target_info["_core"] = t.core
The Other Jimmy 32:8ea194f6145b 66 return target_info
The Other Jimmy 32:8ea194f6145b 67
The Other Jimmy 32:8ea194f6145b 68 def vendor_debug(self, vendor):
The Other Jimmy 32:8ea194f6145b 69 """Reads the vendor from a PDSC <dvendor> tag.
The Other Jimmy 32:8ea194f6145b 70 This tag contains some additional numeric information that is meaningless
The Other Jimmy 32:8ea194f6145b 71 for our purposes, so we use a regex to filter.
The Other Jimmy 32:8ea194f6145b 72
The Other Jimmy 32:8ea194f6145b 73 Positional arguments:
The Other Jimmy 32:8ea194f6145b 74 Vendor - information in <dvendor> tag scraped from ArmPackManager
The Other Jimmy 32:8ea194f6145b 75
The Other Jimmy 32:8ea194f6145b 76 Returns a tuple of (debugger, vendor)
The Other Jimmy 32:8ea194f6145b 77 """
The Other Jimmy 32:8ea194f6145b 78 reg = "([\w\s]+):?\d*?"
The Other Jimmy 32:8ea194f6145b 79 m = re.search(reg, vendor)
The Other Jimmy 32:8ea194f6145b 80 vendor_match = m.group(1) if m else None
The Other Jimmy 32:8ea194f6145b 81 debug_map ={
The Other Jimmy 32:8ea194f6145b 82 'STMicroelectronics':'ST-Link',
The Other Jimmy 32:8ea194f6145b 83 'Silicon Labs':'J-LINK',
The Other Jimmy 32:8ea194f6145b 84 'Nuvoton':'NULink'
The Other Jimmy 32:8ea194f6145b 85 }
The Other Jimmy 32:8ea194f6145b 86 return debug_map.get(vendor_match, "CMSIS-DAP"), vendor_match
The Other Jimmy 32:8ea194f6145b 87
The Other Jimmy 32:8ea194f6145b 88 @staticmethod
The Other Jimmy 32:8ea194f6145b 89 def cpu_cmsis(cpu):
The Other Jimmy 32:8ea194f6145b 90 """
The Other Jimmy 32:8ea194f6145b 91 Transforms information from targets.json to the way the generic cores are named
The Other Jimmy 32:8ea194f6145b 92 in CMSIS PDSC files.
The Other Jimmy 32:8ea194f6145b 93 Ex:
The Other Jimmy 32:8ea194f6145b 94 Cortex-M4F => ARMCM4_FP, Cortex-M0+ => ARMCM0P
The Other Jimmy 32:8ea194f6145b 95 Returns formatted CPU
The Other Jimmy 32:8ea194f6145b 96 """
The Other Jimmy 32:8ea194f6145b 97 cpu = cpu.replace("Cortex-","ARMC")
The Other Jimmy 32:8ea194f6145b 98 cpu = cpu.replace("+","P")
The Other Jimmy 32:8ea194f6145b 99 cpu = cpu.replace("F","_FP")
The Other Jimmy 32:8ea194f6145b 100 return cpu
The Other Jimmy 32:8ea194f6145b 101
The Other Jimmy 32:8ea194f6145b 102
The Other Jimmy 32:8ea194f6145b 103 class CMSIS(Exporter):
The Other Jimmy 32:8ea194f6145b 104 NAME = 'cmsis'
The Other Jimmy 32:8ea194f6145b 105 TOOLCHAIN = 'ARM'
The Other Jimmy 32:8ea194f6145b 106 TARGETS = [target for target, obj in TARGET_MAP.iteritems()
The Other Jimmy 32:8ea194f6145b 107 if "ARM" in obj.supported_toolchains]
The Other Jimmy 32:8ea194f6145b 108
The Other Jimmy 32:8ea194f6145b 109 def make_key(self, src):
The Other Jimmy 32:8ea194f6145b 110 """turn a source file into its group name"""
The Other Jimmy 32:8ea194f6145b 111 key = src.name.split(sep)[0]
The Other Jimmy 32:8ea194f6145b 112 if key == ".":
The Other Jimmy 32:8ea194f6145b 113 key = os.path.basename(os.path.realpath(self.export_dir))
The Other Jimmy 32:8ea194f6145b 114 return key
The Other Jimmy 32:8ea194f6145b 115
The Other Jimmy 32:8ea194f6145b 116 def group_project_files(self, sources, root_element):
The Other Jimmy 32:8ea194f6145b 117 """Recursively group the source files by their encompassing directory"""
The Other Jimmy 32:8ea194f6145b 118
The Other Jimmy 32:8ea194f6145b 119 data = sorted(sources, key=self.make_key)
The Other Jimmy 32:8ea194f6145b 120 for group, files in groupby(data, self.make_key):
The Other Jimmy 32:8ea194f6145b 121 new_srcs = []
The Other Jimmy 32:8ea194f6145b 122 for f in list(files):
The Other Jimmy 32:8ea194f6145b 123 spl = f.name.split(sep)
The Other Jimmy 32:8ea194f6145b 124 if len(spl)==2:
The Other Jimmy 32:8ea194f6145b 125 file_element = Element('file',
The Other Jimmy 32:8ea194f6145b 126 attrib={
The Other Jimmy 32:8ea194f6145b 127 'category':f.type,
The Other Jimmy 32:8ea194f6145b 128 'name': f.loc})
The Other Jimmy 32:8ea194f6145b 129 root_element.append(file_element)
The Other Jimmy 32:8ea194f6145b 130 else:
The Other Jimmy 32:8ea194f6145b 131 f.name = os.path.join(*spl[1:])
The Other Jimmy 32:8ea194f6145b 132 new_srcs.append(f)
The Other Jimmy 32:8ea194f6145b 133 if new_srcs:
The Other Jimmy 32:8ea194f6145b 134 group_element = Element('group',attrib={'name':group})
The Other Jimmy 32:8ea194f6145b 135 root_element.append(self.group_project_files(new_srcs,
The Other Jimmy 32:8ea194f6145b 136 group_element))
The Other Jimmy 32:8ea194f6145b 137 return root_element
The Other Jimmy 32:8ea194f6145b 138
The Other Jimmy 32:8ea194f6145b 139 def generate(self):
The Other Jimmy 32:8ea194f6145b 140 srcs = self.resources.headers + self.resources.s_sources + \
The Other Jimmy 32:8ea194f6145b 141 self.resources.c_sources + self.resources.cpp_sources + \
The Other Jimmy 32:8ea194f6145b 142 self.resources.objects + self.resources.libraries + \
The Other Jimmy 32:8ea194f6145b 143 [self.resources.linker_script]
The Other Jimmy 32:8ea194f6145b 144 srcs = [fileCMSIS(src, src) for src in srcs if src]
The Other Jimmy 32:8ea194f6145b 145 ctx = {
The Other Jimmy 32:8ea194f6145b 146 'name': self.project_name,
The Other Jimmy 32:8ea194f6145b 147 'project_files': tostring(self.group_project_files(srcs, Element('files'))),
The Other Jimmy 32:8ea194f6145b 148 'device': DeviceCMSIS(self.target),
The Other Jimmy 32:8ea194f6145b 149 'date': ''
The Other Jimmy 32:8ea194f6145b 150 }
The Other Jimmy 32:8ea194f6145b 151 # TODO: find how to keep prettyxml from adding xml version to this blob
The Other Jimmy 32:8ea194f6145b 152 #dom = parseString(ctx['project_files'])
The Other Jimmy 32:8ea194f6145b 153 #ctx['project_files'] = dom.toprettyxml(indent="\t")
The Other Jimmy 32:8ea194f6145b 154
The Other Jimmy 32:8ea194f6145b 155 self.gen_file('cmsis/cpdsc.tmpl', ctx, 'project.cpdsc')