Lee Kai Xuan / mbed-os

Fork of mbed-os by erkin yucel

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers __init__.py Source File

__init__.py

00001 import os
00002 from os.path import sep, join, exists
00003 from itertools import groupby
00004 from xml.etree.ElementTree import Element, tostring
00005 import ntpath
00006 import re
00007 import json
00008 
00009 from tools.arm_pack_manager import Cache
00010 from tools.targets import TARGET_MAP
00011 from tools.export.exporters import Exporter, TargetNotSupportedException
00012 
00013 class fileCMSIS ():
00014     """CMSIS file class.
00015 
00016     Encapsulates information necessary for files in cpdsc project file"""
00017     file_types = {'.cpp': 'sourceCpp', '.c': 'sourceC', '.s': 'sourceAsm',
00018                   '.obj': 'object', '.o': 'object', '.lib': 'library',
00019                   '.ar': 'linkerScript', '.h': 'header', '.sct': 'linkerScript'}
00020 
00021     def __init__(self, loc, name):
00022         #print loc
00023         _, ext = os.path.splitext(loc)
00024         self.type  = self.file_types [ext.lower()]
00025         self.loc  = loc
00026         self.name  = name
00027 
00028 
00029 class DeviceCMSIS ():
00030     """CMSIS Device class
00031 
00032     Encapsulates target information retrieved by arm-pack-manager"""
00033     def __init__(self, target):
00034         cache = Cache(True, False)
00035 
00036         t = TARGET_MAP[target]
00037         self.core  = t.core
00038         try:
00039             cpu_name = t.device_name
00040             target_info = cache.index[cpu_name]
00041         # Target does not have device name or pdsc file
00042         except:
00043             try:
00044                 # Try to find the core as a generic CMSIS target
00045                 cpu_name = self.cpu_cmsis ()
00046                 target_info = cache.index[cpu_name]
00047             except:
00048                 raise TargetNotSupportedException("Target not in CMSIS packs")
00049 
00050         self.target_info  = target_info
00051 
00052         self.url  = target_info['pdsc_file']
00053         self.pack_url, self.pack_id  = ntpath.split(self.url )
00054         self.dname  = cpu_name
00055         self.dfpu  = target_info['processor']['fpu']
00056         self.debug, self.dvendor  = self.vendor_debug (target_info['vendor'])
00057         self.dendian  = target_info['processor'].get('endianness','Little-endian')
00058         self.debug_svd  = target_info.get('debug', '')
00059         self.compile_header  = target_info['compile']['header']
00060 
00061     def check_version(self, filename):
00062         with open(filename) as data_file:
00063             data = json.load(data_file)
00064             return data.get("version", "0") == "0.1.0"
00065 
00066     def vendor_debug(self, vendor):
00067         reg = "([\w\s]+):?\d*?"
00068         m = re.search(reg, vendor)
00069         vendor_match = m.group(1) if m else None
00070         debug_map ={
00071             'STMicroelectronics':'ST-Link',
00072             'Silicon Labs':'J-LINK',
00073             'Nuvoton':'NULink'
00074         }
00075         return debug_map.get(vendor_match, "CMSIS-DAP"), vendor_match
00076 
00077     def cpu_cmsis(self):
00078         #Cortex-M4F => ARMCM4_FP, Cortex-M0+ => ARMCM0P
00079         cpu = self.core 
00080         cpu = cpu.replace("Cortex-","ARMC")
00081         cpu = cpu.replace("+","P")
00082         cpu = cpu.replace("F","_FP")
00083         return cpu
00084 
00085 
00086 class CMSIS(Exporter ):
00087     NAME = 'cmsis'
00088     TOOLCHAIN = 'ARM'
00089     TARGETS = [target for target, obj in TARGET_MAP.iteritems()
00090                if "ARM" in obj.supported_toolchains]
00091 
00092     def make_key(self, src):
00093         """turn a source file into its group name"""
00094         key = src.name.split(sep)[0]
00095         if key == ".":
00096             key = os.path.basename(os.path.realpath(self.export_dir))
00097         return key
00098 
00099     def group_project_files(self, sources, root_element):
00100         """Recursively group the source files by their encompassing directory"""
00101 
00102         data = sorted(sources, key=self.make_key)
00103         for group, files in groupby(data, self.make_key):
00104             new_srcs = []
00105             for f in list(files):
00106                 spl = f.name.split(sep)
00107                 if len(spl)==2:
00108                     file_element = Element('file',
00109                                            attrib={
00110                                                'category':f.type,
00111                                                'name': f.loc})
00112                     root_element.append(file_element)
00113                 else:
00114                     f.name = os.path.join(*spl[1:])
00115                     new_srcs.append(f)
00116             if new_srcs:
00117                 group_element = Element('group',attrib={'name':group})
00118                 root_element.append(self.group_project_files(new_srcs,
00119                                                         group_element))
00120         return root_element
00121 
00122     def generate(self):
00123 
00124         srcs = self.resources.headers + self.resources.s_sources + \
00125                self.resources.c_sources + self.resources.cpp_sources + \
00126                self.resources.objects + self.resources.libraries + \
00127                [self.resources.linker_script]
00128         srcs = [fileCMSIS(src, src) for src in srcs if src]
00129         ctx = {
00130             'name': self.project_name,
00131             'project_files': tostring(self.group_project_files(srcs, Element('files'))),
00132             'device': DeviceCMSIS(self.target),
00133             'date': ''
00134         }
00135         # TODO: find how to keep prettyxml from adding xml version to this blob
00136         #dom = parseString(ctx['project_files'])
00137         #ctx['project_files'] = dom.toprettyxml(indent="\t")
00138 
00139         self.gen_file('cmsis/cpdsc.tmpl', ctx, 'project.cpdsc')