Merge pull request #7569 from theotherjimmy/uvision-armc6

Tools: Add Uvision6 exporter
pull/7903/head
Cruz Monrreal 2018-08-27 10:28:38 -05:00 committed by GitHub
commit 543d6c2ecf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 151 additions and 80 deletions

View File

@ -34,7 +34,8 @@ from . import (lpcxpresso, ds5_5, iar, makefile, embitz, coide, kds, simplicity,
cdt, vscode, gnuarmeclipse, qtcreator, cmake, nb, cces, codeblocks) cdt, vscode, gnuarmeclipse, qtcreator, cmake, nb, cces, codeblocks)
EXPORTERS = { EXPORTERS = {
u'uvision5': uvision.Uvision, u'uvision6': uvision.UvisionArmc6,
u'uvision5': uvision.UvisionArmc5,
u'make_gcc_arm': makefile.GccArm, u'make_gcc_arm': makefile.GccArm,
u'make_armc5': makefile.Armc5, u'make_armc5': makefile.Armc5,
u'make_armc6': makefile.Armc6, u'make_armc6': makefile.Armc6,

View File

@ -98,6 +98,7 @@ class DeviceCMSIS():
cpu = cpu.replace("Cortex-","ARMC") cpu = cpu.replace("Cortex-","ARMC")
cpu = cpu.replace("+","P") cpu = cpu.replace("+","P")
cpu = cpu.replace("F","_FP") cpu = cpu.replace("F","_FP")
cpu = cpu.replace("-NS", "")
return cpu return cpu

View File

@ -112,10 +112,10 @@ class Exporter(object):
flags['cxx_flags'] += c_defines flags['cxx_flags'] += c_defines
config_header = self.config_header_ref config_header = self.config_header_ref
if config_header: if config_header:
flags['c_flags'] += self.toolchain.get_config_option( config_option = self.toolchain.get_config_option(
config_header.name)
flags['cxx_flags'] += self.toolchain.get_config_option(
config_header.name) config_header.name)
flags['c_flags'] += config_option
flags['cxx_flags'] += config_option
return flags return flags
@property @property
@ -150,9 +150,9 @@ class Exporter(object):
if config_header: if config_header:
def is_config_header(f): def is_config_header(f):
return f.path == config_header return f.path == config_header
return filter( return list(filter(
is_config_header, self.resources.get_file_refs(FileType.HEADER) is_config_header, self.resources.get_file_refs(FileType.HEADER)
)[0] ))[0]
else: else:
return None return None

View File

@ -2,7 +2,7 @@ from __future__ import print_function, absolute_import
from builtins import str from builtins import str
import os import os
from os.path import sep, normpath, join, exists, dirname from os.path import normpath, exists, dirname
import ntpath import ntpath
import copy import copy
from collections import namedtuple from collections import namedtuple
@ -11,11 +11,11 @@ from subprocess import Popen, PIPE
import re import re
from tools.resources import FileType from tools.resources import FileType
from tools.arm_pack_manager import Cache
from tools.targets import TARGET_MAP from tools.targets import TARGET_MAP
from tools.export.exporters import Exporter, apply_supported_whitelist from tools.export.exporters import Exporter
from tools.export.cmsis import DeviceCMSIS from tools.export.cmsis import DeviceCMSIS
class DeviceUvision(DeviceCMSIS): class DeviceUvision(DeviceCMSIS):
"""Uvision Device class, inherits CMSIS Device class """Uvision Device class, inherits CMSIS Device class
@ -32,19 +32,23 @@ class DeviceUvision(DeviceCMSIS):
def uv_debug(self): def uv_debug(self):
"""Return a namedtuple of information about uvision debug settings""" """Return a namedtuple of information about uvision debug settings"""
UVDebug = namedtuple('UVDebug',['bin_loc','core_flag', 'key']) UVDebug = namedtuple('UVDebug', ['bin_loc', 'core_flag', 'key'])
# CortexMXn => pCMX # CortexMXn => pCMX
cpu = self.core.replace("Cortex-", "C") cpu = self.core.replace("Cortex-", "C")
cpu = cpu.replace("+", "") cpu = cpu.replace("+", "")
cpu = cpu.replace("F", "") cpu = cpu.replace("F", "")
cpu = cpu.replace("-NS", "")
cpu_flag = "p"+cpu cpu_flag = "p"+cpu
# Locations found in Keil_v5/TOOLS.INI # Locations found in Keil_v5/TOOLS.INI
debuggers = {"st-link": ('STLink\\ST-LINKIII-KEIL_SWO.dll', 'ST-LINKIII-KEIL_SWO'), debuggers = {
"j-link":('Segger\\JL2CM3.dll', 'JL2CM3'), "st-link": ('STLink\\ST-LINKIII-KEIL_SWO.dll',
"cmsis-dap":('BIN\\CMSIS_AGDI.dll', 'CMSIS_AGDI'), 'ST-LINKIII-KEIL_SWO'),
"nulink":('NULink\\Nu_Link.dll','Nu_Link')} "j-link": ('Segger\\JL2CM3.dll', 'JL2CM3'),
"cmsis-dap": ('BIN\\CMSIS_AGDI.dll', 'CMSIS_AGDI'),
"nulink": ('NULink\\Nu_Link.dll', 'Nu_Link')
}
res = debuggers[self.debug.lower()] res = debuggers[self.debug.lower()]
binary = res[0] binary = res[0]
key = res[1] key = res[1]
@ -56,7 +60,7 @@ class DeviceUvision(DeviceCMSIS):
S = SW/JTAG Clock ID S = SW/JTAG Clock ID
C = CPU index in JTAG chain C = CPU index in JTAG chain
P = Access Port P = Access Port
For the Options for Target -> Debug tab -> settings -> "Flash" tab in the dialog: For the Options for Target -> Debug -> settings -> "Flash" dialog:
FD = RAM Start for Flash Functions FD = RAM Start for Flash Functions
FC = RAM Size for Flash Functions FC = RAM Size for Flash Functions
FN = Number of Flash types FN = Number of Flash types
@ -65,44 +69,55 @@ class DeviceUvision(DeviceCMSIS):
FL = Size of the Flash Device FL = Size of the Flash Device
FP = Full path to the Device algorithm (RTE) FP = Full path to the Device algorithm (RTE)
Necessary to flash some targets. Info gathered from algorithms field of pdsc file. Necessary to flash some targets.
''' '''
fl_count = 0 fl_count = 0
def get_mem_no_x(mem_str): def get_mem_no_x(mem_str):
mem_reg = "\dx(\w+)" mem_reg = "\dx(\w+)"
m = re.search(mem_reg, mem_str) m = re.search(mem_reg, mem_str)
return m.group(1) if m else None return m.group(1) if m else None
RAMS = [(get_mem_no_x(info["start"]), get_mem_no_x(info["size"])) RAMS = [
for mem, info in self.target_info["memory"].items() if "RAM" in mem] (get_mem_no_x(info["start"]), get_mem_no_x(info["size"]))
format_str = "UL2CM3(-S0 -C0 -P0 -FD{ramstart}"+" -FC{ramsize} "+"-FN{num_algos} {extra_flags})" for mem, info in self.target_info["memory"].items() if "RAM" in mem
]
format_str = (
"UL2CM3(-S0 -C0 -P0 -FD{ramstart}"
" -FC{ramsize} -FN{num_algos} {extra_flags})"
)
ramstart = '' ramstart = ''
#Default according to Keil developer # Default according to Keil developer
ramsize = '1000' ramsize = '1000'
if len(RAMS)>=1: if len(RAMS) >= 1:
ramstart = RAMS[0][0] ramstart = RAMS[0][0]
extra_flags = [] extra_flags = []
for name, info in self.target_info["algorithm"].items(): for name, info in self.target_info["algorithm"].items():
if not name or not info: if not name or not info:
continue continue
if int(info["default"])==0: if int(info["default"]) == 0:
continue continue
name_reg = "\w*/([\w_]+)\.flm" name_reg = "\w*/([\w_]+)\.flm"
m = re.search(name_reg, name.lower()) m = re.search(name_reg, name.lower())
fl_name = m.group(1) if m else None fl_name = m.group(1) if m else None
name_flag = "-FF" + str(fl_count) + fl_name name_flag = "-FF" + str(fl_count) + fl_name
start, size = get_mem_no_x(info["start"]), get_mem_no_x(info["size"]) start = get_mem_no_x(info["start"])
rom_start_flag = "-FS"+str(fl_count)+str(start) size = get_mem_no_x(info["size"])
rom_start_flag = "-FS" + str(fl_count) + str(start)
rom_size_flag = "-FL" + str(fl_count) + str(size) rom_size_flag = "-FL" + str(fl_count) + str(size)
if info["ramstart"] is not None and info["ramsize"] is not None: if info["ramstart"] is not None and info["ramsize"] is not None:
ramstart = get_mem_no_x(info["ramstart"]) ramstart = get_mem_no_x(info["ramstart"])
ramsize = get_mem_no_x(info["ramsize"]) ramsize = get_mem_no_x(info["ramsize"])
path_flag = "-FP" + str(fl_count) + "($$Device:"+self.dname+"$"+name+")" path_flag = "-FP{}($$Device:{}${})".format(
str(fl_count), self.dname, name
)
extra_flags.extend([name_flag, rom_start_flag, rom_size_flag, path_flag]) extra_flags.extend([
name_flag, rom_start_flag, rom_size_flag, path_flag
])
fl_count += 1 fl_count += 1
extra = " ".join(extra_flags) extra = " ".join(extra_flags)
@ -118,8 +133,6 @@ class Uvision(Exporter):
project file (.uvprojx). project file (.uvprojx).
The needed information can be viewed in uvision.tmpl The needed information can be viewed in uvision.tmpl
""" """
NAME = 'uvision5'
TOOLCHAIN = 'ARM'
POST_BINARY_WHITELIST = set([ POST_BINARY_WHITELIST = set([
"MCU_NRF51Code.binary_hook", "MCU_NRF51Code.binary_hook",
@ -131,24 +144,7 @@ class Uvision(Exporter):
"NCS36510TargetCode.ncs36510_addfib" "NCS36510TargetCode.ncs36510_addfib"
]) ])
@classmethod # File associations within .uvprojx file
def is_target_supported(cls, target_name):
target = TARGET_MAP[target_name]
if not (set(target.supported_toolchains).intersection(
set(["ARM", "uARM"]))):
return False
if not DeviceCMSIS.check_supported(target_name):
return False
if "Cortex-A" in target.core:
return False
if not hasattr(target, "post_binary_hook"):
return True
if target.post_binary_hook['function'] in cls.POST_BINARY_WHITELIST:
return True
else:
return False
#File associations within .uvprojx file
file_types = {'.cpp': 8, '.c': 1, '.s': 2, file_types = {'.cpp': 8, '.c': 1, '.s': 2,
'.obj': 3, '.o': 3, '.lib': 4, '.obj': 3, '.o': 3, '.lib': 4,
'.ar': 4, '.h': 5, '.hpp': 5, '.sct': 4} '.ar': 4, '.h': 5, '.hpp': 5, '.sct': 4}
@ -166,8 +162,8 @@ class Uvision(Exporter):
</File> </File>
""" """
for loc in files: for loc in files:
#Encapsulates the information necessary for template entry above # Encapsulates the information necessary for template entry above
UVFile = namedtuple('UVFile', ['type','loc','name']) UVFile = namedtuple('UVFile', ['type', 'loc', 'name'])
_, ext = os.path.splitext(loc) _, ext = os.path.splitext(loc)
if ext.lower() in self.file_types: if ext.lower() in self.file_types:
type = self.file_types[ext.lower()] type = self.file_types[ext.lower()]
@ -177,22 +173,40 @@ class Uvision(Exporter):
def format_flags(self): def format_flags(self):
"""Format toolchain flags for Uvision""" """Format toolchain flags for Uvision"""
flags = copy.deepcopy(self.flags) flags = copy.deepcopy(self.flags)
# to be preprocessed with armcc
asm_flag_string = ( asm_flag_string = (
'--cpreproc --cpreproc_opts=-D__ASSERT_MSG,' + '--cpreproc --cpreproc_opts=-D__ASSERT_MSG,' +
",".join(filter(lambda f: f.startswith("-D"), flags['asm_flags']))) ",".join("-D{}".format(s) for s in
self.toolchain.get_symbols(for_asm=True)))
flags['asm_flags'] = asm_flag_string flags['asm_flags'] = asm_flag_string
# All non-asm flags are in one template field
c_flags = list(set(flags['c_flags'] + flags['cxx_flags'] +flags['common_flags'])) config_header = self.config_header_ref
ld_flags = list(set(flags['ld_flags'] )) config_option = self.toolchain.get_config_option(config_header.name)
# These flags are in template to be set by user i n IDE c_flags = set(
template = ["--no_vla", "--cpp", "--c99"] flags['c_flags'] + flags['cxx_flags'] + flags['common_flags']
# Flag is invalid if set in template )
# Optimizations are also set in the template in_template = set(
invalid_flag = lambda x: x in template or re.match("-O(\d|time)", x) ["--no_vla", "--cpp", "--c99", "-MMD"] + config_option
flags['c_flags'] = [flag.replace('"','\\"') for flag in c_flags if not invalid_flag(flag)] )
flags['c_flags'] = " ".join(flags['c_flags'])
flags['ld_flags'] = " ".join(flags['ld_flags']) def valid_flag(x):
return (
x not in in_template and
not x.startswith("-O") and
not x.startswith("-std") and
not x.startswith("-D")
)
def is_define(s):
return s.startswith("-D") and "(" not in s
flags['c_flags'] = " ".join(
f.replace('"', '\\"') for f in c_flags if valid_flag(f)
)
flags['c_flags'] += " "
flags['c_flags'] += " ".join(config_option)
flags['c_defines'] = " ".join(f[2:].replace('"', '\\"')
for f in c_flags if is_define(f))
flags['ld_flags'] = " ".join(set(flags['ld_flags']))
return flags return flags
def format_src(self, srcs): def format_src(self, srcs):
@ -215,11 +229,11 @@ class Uvision(Exporter):
def generate(self): def generate(self):
"""Generate the .uvproj file""" """Generate the .uvproj file"""
cache = Cache(True, False) srcs = (
self.resources.headers + self.resources.s_sources +
srcs = self.resources.headers + self.resources.s_sources + \ self.resources.c_sources + self.resources.cpp_sources +
self.resources.c_sources + self.resources.cpp_sources + \
self.resources.objects + self.libraries self.resources.objects + self.libraries
)
ctx = { ctx = {
'name': self.project_name, 'name': self.project_name,
# project_files => dict of generators - file group to generator of # project_files => dict of generators - file group to generator of
@ -230,23 +244,29 @@ class Uvision(Exporter):
self.resources.inc_dirs).encode('utf-8'), self.resources.inc_dirs).encode('utf-8'),
'device': DeviceUvision(self.target), 'device': DeviceUvision(self.target),
} }
sct_name, sct_path = self.resources.get_file_refs(FileType.LD_SCRIPT)[0] sct_name, sct_path = self.resources.get_file_refs(
FileType.LD_SCRIPT)[0]
ctx['linker_script'] = self.toolchain.correct_scatter_shebang( ctx['linker_script'] = self.toolchain.correct_scatter_shebang(
sct_path, dirname(sct_name)) sct_path, dirname(sct_name))
if ctx['linker_script'] != sct_path: if ctx['linker_script'] != sct_path:
self.generated_files.append(ctx['linker_script']) self.generated_files.append(ctx['linker_script'])
core = ctx['device'].core ctx['cputype'] = ctx['device'].core.rstrip("FD").replace("-NS", "")
ctx['cputype'] = core.rstrip("FD") if ctx['device'].core.endswith("FD"):
if core.endswith("FD"):
ctx['fpu_setting'] = 3 ctx['fpu_setting'] = 3
elif core.endswith("F"): elif ctx['device'].core.endswith("F"):
ctx['fpu_setting'] = 2 ctx['fpu_setting'] = 2
else: else:
ctx['fpu_setting'] = 1 ctx['fpu_setting'] = 1
ctx['fputype'] = self.format_fpu(core) ctx['fputype'] = self.format_fpu(ctx['device'].core)
ctx['armc6'] = int(self.TOOLCHAIN is 'ARMC6')
ctx['toolchain_name'] = self.TOOLCHAIN_NAME
ctx.update(self.format_flags()) ctx.update(self.format_flags())
self.gen_file('uvision/uvision.tmpl', ctx, self.project_name+".uvprojx") self.gen_file(
self.gen_file('uvision/uvision_debug.tmpl', ctx, self.project_name + ".uvoptx") 'uvision/uvision.tmpl', ctx, self.project_name + ".uvprojx"
)
self.gen_file(
'uvision/uvision_debug.tmpl', ctx, self.project_name + ".uvoptx"
)
@staticmethod @staticmethod
def clean(project_name): def clean(project_name):
@ -285,3 +305,49 @@ class Uvision(Exporter):
return -1 return -1
else: else:
return 0 return 0
class UvisionArmc5(Uvision):
NAME = 'uvision5-armc5'
TOOLCHAIN = 'ARM'
TOOLCHAIN_NAME = ''
@classmethod
def is_target_supported(cls, target_name):
target = TARGET_MAP[target_name]
if not (set(target.supported_toolchains).intersection(
set(["ARM", "uARM"]))):
return False
if not DeviceCMSIS.check_supported(target_name):
return False
if "Cortex-A" in target.core:
return False
if not hasattr(target, "post_binary_hook"):
return True
if target.post_binary_hook['function'] in cls.POST_BINARY_WHITELIST:
return True
else:
return False
class UvisionArmc6(Uvision):
NAME = 'uvision5-armc6'
TOOLCHAIN = 'ARMC6'
TOOLCHAIN_NAME = '6070000::V6.7::.\ARMCLANG'
@classmethod
def is_target_supported(cls, target_name):
target = TARGET_MAP[target_name]
if not (set(target.supported_toolchains).intersection(
set(["ARMC6"]))):
return False
if not DeviceCMSIS.check_supported(target_name):
return False
if "Cortex-A" in target.core:
return False
if not hasattr(target, "post_binary_hook"):
return True
if target.post_binary_hook['function'] in cls.POST_BINARY_WHITELIST:
return True
else:
return False

View File

@ -10,6 +10,10 @@
<TargetName>{{name}}</TargetName> <TargetName>{{name}}</TargetName>
<ToolsetNumber>0x4</ToolsetNumber> <ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName> <ToolsetName>ARM-ADS</ToolsetName>
{% if toolchain_name %}
<pCCUsed>{{toolchain_name}}</pCCUsed>
{% endif %}
<uAC6>{{armc6}}</uAC6>
<TargetOption> <TargetOption>
<TargetCommonOption> <TargetCommonOption>
<Device>{{device.dname}}</Device> <Device>{{device.dname}}</Device>
@ -213,7 +217,7 @@
<AdsLsxf>1</AdsLsxf> <AdsLsxf>1</AdsLsxf>
<RvctClst>0</RvctClst> <RvctClst>0</RvctClst>
<GenPPlst>0</GenPPlst> <GenPPlst>0</GenPPlst>
<AdsCpuType>"{{device.core.replace("D","").replace("F","")}}"</AdsCpuType> <AdsCpuType>"{{cputype}}"</AdsCpuType>
<RvctDeviceName></RvctDeviceName> <RvctDeviceName></RvctDeviceName>
<mOS>0</mOS> <mOS>0</mOS>
<uocRom>0</uocRom> <uocRom>0</uocRom>
@ -354,7 +358,7 @@
<Optim>1</Optim> <Optim>1</Optim>
<oTime>0</oTime> <oTime>0</oTime>
<SplitLS>0</SplitLS> <SplitLS>0</SplitLS>
<OneElfS>0</OneElfS> <OneElfS>1</OneElfS>
<Strict>0</Strict> <Strict>0</Strict>
<EnumInt>0</EnumInt> <EnumInt>0</EnumInt>
<PlainCh>0</PlainCh> <PlainCh>0</PlainCh>
@ -365,8 +369,8 @@
<uSurpInc>0</uSurpInc> <uSurpInc>0</uSurpInc>
<uC99>1</uC99> <uC99>1</uC99>
<useXO>0</useXO> <useXO>0</useXO>
<v6Lang>1</v6Lang> <v6Lang>4</v6Lang>
<v6LangP>1</v6LangP> <v6LangP>2</v6LangP>
<vShortEn>1</vShortEn> <vShortEn>1</vShortEn>
<vShortWch>1</vShortWch> <vShortWch>1</vShortWch>
<v6Lto>0</v6Lto> <v6Lto>0</v6Lto>
@ -374,7 +378,7 @@
<v6Rtti>0</v6Rtti> <v6Rtti>0</v6Rtti>
<VariousControls> <VariousControls>
<MiscControls>{{c_flags}}</MiscControls> <MiscControls>{{c_flags}}</MiscControls>
<Define></Define> <Define>{{c_defines}}</Define>
<Undefine></Undefine> <Undefine></Undefine>
<IncludePath>{{include_paths}}</IncludePath> <IncludePath>{{include_paths}}</IncludePath>
</VariousControls> </VariousControls>
@ -434,5 +438,4 @@
</Groups> </Groups>
</Target> </Target>
</Targets> </Targets>
</Project> </Project>