Greg Steiert / pegasus_dev

Dependents:   blinky_max32630fthr

Committer:
switches
Date:
Fri Nov 11 20:59:50 2016 +0000
Revision:
0:5c4d7b2438d3
Initial commit

Who changed what in which revision?

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