Skip to content

Commit 543d6c2

Browse files
author
Cruz Monrreal
authored
Merge pull request #7569 from theotherjimmy/uvision-armc6
Tools: Add Uvision6 exporter
2 parents bf2da48 + c8f1e1f commit 543d6c2

File tree

5 files changed

+151
-80
lines changed

5 files changed

+151
-80
lines changed

tools/export/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434
cdt, vscode, gnuarmeclipse, qtcreator, cmake, nb, cces, codeblocks)
3535

3636
EXPORTERS = {
37-
u'uvision5': uvision.Uvision,
37+
u'uvision6': uvision.UvisionArmc6,
38+
u'uvision5': uvision.UvisionArmc5,
3839
u'make_gcc_arm': makefile.GccArm,
3940
u'make_armc5': makefile.Armc5,
4041
u'make_armc6': makefile.Armc6,

tools/export/cmsis/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ def cpu_cmsis(cpu):
9898
cpu = cpu.replace("Cortex-","ARMC")
9999
cpu = cpu.replace("+","P")
100100
cpu = cpu.replace("F","_FP")
101+
cpu = cpu.replace("-NS", "")
101102
return cpu
102103

103104

tools/export/exporters.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,10 @@ def flags(self):
112112
flags['cxx_flags'] += c_defines
113113
config_header = self.config_header_ref
114114
if config_header:
115-
flags['c_flags'] += self.toolchain.get_config_option(
116-
config_header.name)
117-
flags['cxx_flags'] += self.toolchain.get_config_option(
115+
config_option = self.toolchain.get_config_option(
118116
config_header.name)
117+
flags['c_flags'] += config_option
118+
flags['cxx_flags'] += config_option
119119
return flags
120120

121121
@property
@@ -150,9 +150,9 @@ def config_header_ref(self):
150150
if config_header:
151151
def is_config_header(f):
152152
return f.path == config_header
153-
return filter(
153+
return list(filter(
154154
is_config_header, self.resources.get_file_refs(FileType.HEADER)
155-
)[0]
155+
))[0]
156156
else:
157157
return None
158158

tools/export/uvision/__init__.py

Lines changed: 134 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from builtins import str
33

44
import os
5-
from os.path import sep, normpath, join, exists, dirname
5+
from os.path import normpath, exists, dirname
66
import ntpath
77
import copy
88
from collections import namedtuple
@@ -11,11 +11,11 @@
1111
import re
1212

1313
from tools.resources import FileType
14-
from tools.arm_pack_manager import Cache
1514
from tools.targets import TARGET_MAP
16-
from tools.export.exporters import Exporter, apply_supported_whitelist
15+
from tools.export.exporters import Exporter
1716
from tools.export.cmsis import DeviceCMSIS
1817

18+
1919
class DeviceUvision(DeviceCMSIS):
2020
"""Uvision Device class, inherits CMSIS Device class
2121
@@ -32,19 +32,23 @@ def __init__(self, target):
3232

3333
def uv_debug(self):
3434
"""Return a namedtuple of information about uvision debug settings"""
35-
UVDebug = namedtuple('UVDebug',['bin_loc','core_flag', 'key'])
35+
UVDebug = namedtuple('UVDebug', ['bin_loc', 'core_flag', 'key'])
3636

3737
# CortexMXn => pCMX
3838
cpu = self.core.replace("Cortex-", "C")
3939
cpu = cpu.replace("+", "")
4040
cpu = cpu.replace("F", "")
41+
cpu = cpu.replace("-NS", "")
4142
cpu_flag = "p"+cpu
4243

4344
# Locations found in Keil_v5/TOOLS.INI
44-
debuggers = {"st-link": ('STLink\\ST-LINKIII-KEIL_SWO.dll', 'ST-LINKIII-KEIL_SWO'),
45-
"j-link":('Segger\\JL2CM3.dll', 'JL2CM3'),
46-
"cmsis-dap":('BIN\\CMSIS_AGDI.dll', 'CMSIS_AGDI'),
47-
"nulink":('NULink\\Nu_Link.dll','Nu_Link')}
45+
debuggers = {
46+
"st-link": ('STLink\\ST-LINKIII-KEIL_SWO.dll',
47+
'ST-LINKIII-KEIL_SWO'),
48+
"j-link": ('Segger\\JL2CM3.dll', 'JL2CM3'),
49+
"cmsis-dap": ('BIN\\CMSIS_AGDI.dll', 'CMSIS_AGDI'),
50+
"nulink": ('NULink\\Nu_Link.dll', 'Nu_Link')
51+
}
4852
res = debuggers[self.debug.lower()]
4953
binary = res[0]
5054
key = res[1]
@@ -56,7 +60,7 @@ def generate_flash_dll(self):
5660
S = SW/JTAG Clock ID
5761
C = CPU index in JTAG chain
5862
P = Access Port
59-
For the Options for Target -> Debug tab -> settings -> "Flash" tab in the dialog:
63+
For the Options for Target -> Debug -> settings -> "Flash" dialog:
6064
FD = RAM Start for Flash Functions
6165
FC = RAM Size for Flash Functions
6266
FN = Number of Flash types
@@ -65,44 +69,55 @@ def generate_flash_dll(self):
6569
FL = Size of the Flash Device
6670
FP = Full path to the Device algorithm (RTE)
6771
68-
Necessary to flash some targets. Info gathered from algorithms field of pdsc file.
72+
Necessary to flash some targets.
6973
'''
7074
fl_count = 0
75+
7176
def get_mem_no_x(mem_str):
7277
mem_reg = "\dx(\w+)"
7378
m = re.search(mem_reg, mem_str)
7479
return m.group(1) if m else None
7580

76-
RAMS = [(get_mem_no_x(info["start"]), get_mem_no_x(info["size"]))
77-
for mem, info in self.target_info["memory"].items() if "RAM" in mem]
78-
format_str = "UL2CM3(-S0 -C0 -P0 -FD{ramstart}"+" -FC{ramsize} "+"-FN{num_algos} {extra_flags})"
81+
RAMS = [
82+
(get_mem_no_x(info["start"]), get_mem_no_x(info["size"]))
83+
for mem, info in self.target_info["memory"].items() if "RAM" in mem
84+
]
85+
format_str = (
86+
"UL2CM3(-S0 -C0 -P0 -FD{ramstart}"
87+
" -FC{ramsize} -FN{num_algos} {extra_flags})"
88+
)
7989
ramstart = ''
80-
#Default according to Keil developer
90+
# Default according to Keil developer
8191
ramsize = '1000'
82-
if len(RAMS)>=1:
92+
if len(RAMS) >= 1:
8393
ramstart = RAMS[0][0]
8494
extra_flags = []
8595
for name, info in self.target_info["algorithm"].items():
8696
if not name or not info:
8797
continue
88-
if int(info["default"])==0:
98+
if int(info["default"]) == 0:
8999
continue
90100
name_reg = "\w*/([\w_]+)\.flm"
91101
m = re.search(name_reg, name.lower())
92102
fl_name = m.group(1) if m else None
93103
name_flag = "-FF" + str(fl_count) + fl_name
94104

95-
start, size = get_mem_no_x(info["start"]), get_mem_no_x(info["size"])
96-
rom_start_flag = "-FS"+str(fl_count)+str(start)
105+
start = get_mem_no_x(info["start"])
106+
size = get_mem_no_x(info["size"])
107+
rom_start_flag = "-FS" + str(fl_count) + str(start)
97108
rom_size_flag = "-FL" + str(fl_count) + str(size)
98109

99110
if info["ramstart"] is not None and info["ramsize"] is not None:
100111
ramstart = get_mem_no_x(info["ramstart"])
101112
ramsize = get_mem_no_x(info["ramsize"])
102113

103-
path_flag = "-FP" + str(fl_count) + "($$Device:"+self.dname+"$"+name+")"
114+
path_flag = "-FP{}($$Device:{}${})".format(
115+
str(fl_count), self.dname, name
116+
)
104117

105-
extra_flags.extend([name_flag, rom_start_flag, rom_size_flag, path_flag])
118+
extra_flags.extend([
119+
name_flag, rom_start_flag, rom_size_flag, path_flag
120+
])
106121
fl_count += 1
107122

108123
extra = " ".join(extra_flags)
@@ -118,8 +133,6 @@ class Uvision(Exporter):
118133
project file (.uvprojx).
119134
The needed information can be viewed in uvision.tmpl
120135
"""
121-
NAME = 'uvision5'
122-
TOOLCHAIN = 'ARM'
123136

124137
POST_BINARY_WHITELIST = set([
125138
"MCU_NRF51Code.binary_hook",
@@ -131,24 +144,7 @@ class Uvision(Exporter):
131144
"NCS36510TargetCode.ncs36510_addfib"
132145
])
133146

134-
@classmethod
135-
def is_target_supported(cls, target_name):
136-
target = TARGET_MAP[target_name]
137-
if not (set(target.supported_toolchains).intersection(
138-
set(["ARM", "uARM"]))):
139-
return False
140-
if not DeviceCMSIS.check_supported(target_name):
141-
return False
142-
if "Cortex-A" in target.core:
143-
return False
144-
if not hasattr(target, "post_binary_hook"):
145-
return True
146-
if target.post_binary_hook['function'] in cls.POST_BINARY_WHITELIST:
147-
return True
148-
else:
149-
return False
150-
151-
#File associations within .uvprojx file
147+
# File associations within .uvprojx file
152148
file_types = {'.cpp': 8, '.c': 1, '.s': 2,
153149
'.obj': 3, '.o': 3, '.lib': 4,
154150
'.ar': 4, '.h': 5, '.hpp': 5, '.sct': 4}
@@ -166,8 +162,8 @@ def uv_files(self, files):
166162
</File>
167163
"""
168164
for loc in files:
169-
#Encapsulates the information necessary for template entry above
170-
UVFile = namedtuple('UVFile', ['type','loc','name'])
165+
# Encapsulates the information necessary for template entry above
166+
UVFile = namedtuple('UVFile', ['type', 'loc', 'name'])
171167
_, ext = os.path.splitext(loc)
172168
if ext.lower() in self.file_types:
173169
type = self.file_types[ext.lower()]
@@ -177,22 +173,40 @@ def uv_files(self, files):
177173
def format_flags(self):
178174
"""Format toolchain flags for Uvision"""
179175
flags = copy.deepcopy(self.flags)
180-
# to be preprocessed with armcc
181176
asm_flag_string = (
182177
'--cpreproc --cpreproc_opts=-D__ASSERT_MSG,' +
183-
",".join(filter(lambda f: f.startswith("-D"), flags['asm_flags'])))
178+
",".join("-D{}".format(s) for s in
179+
self.toolchain.get_symbols(for_asm=True)))
184180
flags['asm_flags'] = asm_flag_string
185-
# All non-asm flags are in one template field
186-
c_flags = list(set(flags['c_flags'] + flags['cxx_flags'] +flags['common_flags']))
187-
ld_flags = list(set(flags['ld_flags'] ))
188-
# These flags are in template to be set by user i n IDE
189-
template = ["--no_vla", "--cpp", "--c99"]
190-
# Flag is invalid if set in template
191-
# Optimizations are also set in the template
192-
invalid_flag = lambda x: x in template or re.match("-O(\d|time)", x)
193-
flags['c_flags'] = [flag.replace('"','\\"') for flag in c_flags if not invalid_flag(flag)]
194-
flags['c_flags'] = " ".join(flags['c_flags'])
195-
flags['ld_flags'] = " ".join(flags['ld_flags'])
181+
182+
config_header = self.config_header_ref
183+
config_option = self.toolchain.get_config_option(config_header.name)
184+
c_flags = set(
185+
flags['c_flags'] + flags['cxx_flags'] + flags['common_flags']
186+
)
187+
in_template = set(
188+
["--no_vla", "--cpp", "--c99", "-MMD"] + config_option
189+
)
190+
191+
def valid_flag(x):
192+
return (
193+
x not in in_template and
194+
not x.startswith("-O") and
195+
not x.startswith("-std") and
196+
not x.startswith("-D")
197+
)
198+
199+
def is_define(s):
200+
return s.startswith("-D") and "(" not in s
201+
202+
flags['c_flags'] = " ".join(
203+
f.replace('"', '\\"') for f in c_flags if valid_flag(f)
204+
)
205+
flags['c_flags'] += " "
206+
flags['c_flags'] += " ".join(config_option)
207+
flags['c_defines'] = " ".join(f[2:].replace('"', '\\"')
208+
for f in c_flags if is_define(f))
209+
flags['ld_flags'] = " ".join(set(flags['ld_flags']))
196210
return flags
197211

198212
def format_src(self, srcs):
@@ -215,11 +229,11 @@ def format_fpu(core):
215229

216230
def generate(self):
217231
"""Generate the .uvproj file"""
218-
cache = Cache(True, False)
219-
220-
srcs = self.resources.headers + self.resources.s_sources + \
221-
self.resources.c_sources + self.resources.cpp_sources + \
222-
self.resources.objects + self.libraries
232+
srcs = (
233+
self.resources.headers + self.resources.s_sources +
234+
self.resources.c_sources + self.resources.cpp_sources +
235+
self.resources.objects + self.libraries
236+
)
223237
ctx = {
224238
'name': self.project_name,
225239
# project_files => dict of generators - file group to generator of
@@ -230,23 +244,29 @@ def generate(self):
230244
self.resources.inc_dirs).encode('utf-8'),
231245
'device': DeviceUvision(self.target),
232246
}
233-
sct_name, sct_path = self.resources.get_file_refs(FileType.LD_SCRIPT)[0]
247+
sct_name, sct_path = self.resources.get_file_refs(
248+
FileType.LD_SCRIPT)[0]
234249
ctx['linker_script'] = self.toolchain.correct_scatter_shebang(
235250
sct_path, dirname(sct_name))
236251
if ctx['linker_script'] != sct_path:
237252
self.generated_files.append(ctx['linker_script'])
238-
core = ctx['device'].core
239-
ctx['cputype'] = core.rstrip("FD")
240-
if core.endswith("FD"):
253+
ctx['cputype'] = ctx['device'].core.rstrip("FD").replace("-NS", "")
254+
if ctx['device'].core.endswith("FD"):
241255
ctx['fpu_setting'] = 3
242-
elif core.endswith("F"):
256+
elif ctx['device'].core.endswith("F"):
243257
ctx['fpu_setting'] = 2
244258
else:
245259
ctx['fpu_setting'] = 1
246-
ctx['fputype'] = self.format_fpu(core)
260+
ctx['fputype'] = self.format_fpu(ctx['device'].core)
261+
ctx['armc6'] = int(self.TOOLCHAIN is 'ARMC6')
262+
ctx['toolchain_name'] = self.TOOLCHAIN_NAME
247263
ctx.update(self.format_flags())
248-
self.gen_file('uvision/uvision.tmpl', ctx, self.project_name+".uvprojx")
249-
self.gen_file('uvision/uvision_debug.tmpl', ctx, self.project_name + ".uvoptx")
264+
self.gen_file(
265+
'uvision/uvision.tmpl', ctx, self.project_name + ".uvprojx"
266+
)
267+
self.gen_file(
268+
'uvision/uvision_debug.tmpl', ctx, self.project_name + ".uvoptx"
269+
)
250270

251271
@staticmethod
252272
def clean(project_name):
@@ -285,3 +305,49 @@ def build(project_name, log_name='build_log.txt', cleanup=True):
285305
return -1
286306
else:
287307
return 0
308+
309+
310+
class UvisionArmc5(Uvision):
311+
NAME = 'uvision5-armc5'
312+
TOOLCHAIN = 'ARM'
313+
TOOLCHAIN_NAME = ''
314+
315+
@classmethod
316+
def is_target_supported(cls, target_name):
317+
target = TARGET_MAP[target_name]
318+
if not (set(target.supported_toolchains).intersection(
319+
set(["ARM", "uARM"]))):
320+
return False
321+
if not DeviceCMSIS.check_supported(target_name):
322+
return False
323+
if "Cortex-A" in target.core:
324+
return False
325+
if not hasattr(target, "post_binary_hook"):
326+
return True
327+
if target.post_binary_hook['function'] in cls.POST_BINARY_WHITELIST:
328+
return True
329+
else:
330+
return False
331+
332+
333+
class UvisionArmc6(Uvision):
334+
NAME = 'uvision5-armc6'
335+
TOOLCHAIN = 'ARMC6'
336+
TOOLCHAIN_NAME = '6070000::V6.7::.\ARMCLANG'
337+
338+
@classmethod
339+
def is_target_supported(cls, target_name):
340+
target = TARGET_MAP[target_name]
341+
if not (set(target.supported_toolchains).intersection(
342+
set(["ARMC6"]))):
343+
return False
344+
if not DeviceCMSIS.check_supported(target_name):
345+
return False
346+
if "Cortex-A" in target.core:
347+
return False
348+
if not hasattr(target, "post_binary_hook"):
349+
return True
350+
if target.post_binary_hook['function'] in cls.POST_BINARY_WHITELIST:
351+
return True
352+
else:
353+
return False

0 commit comments

Comments
 (0)