2
2
from builtins import str
3
3
4
4
import os
5
- from os .path import sep , normpath , join , exists , dirname
5
+ from os .path import normpath , exists , dirname
6
6
import ntpath
7
7
import copy
8
8
from collections import namedtuple
11
11
import re
12
12
13
13
from tools .resources import FileType
14
- from tools .arm_pack_manager import Cache
15
14
from tools .targets import TARGET_MAP
16
- from tools .export .exporters import Exporter , apply_supported_whitelist
15
+ from tools .export .exporters import Exporter
17
16
from tools .export .cmsis import DeviceCMSIS
18
17
18
+
19
19
class DeviceUvision (DeviceCMSIS ):
20
20
"""Uvision Device class, inherits CMSIS Device class
21
21
@@ -32,19 +32,23 @@ def __init__(self, target):
32
32
33
33
def uv_debug (self ):
34
34
"""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' ])
36
36
37
37
# CortexMXn => pCMX
38
38
cpu = self .core .replace ("Cortex-" , "C" )
39
39
cpu = cpu .replace ("+" , "" )
40
40
cpu = cpu .replace ("F" , "" )
41
+ cpu = cpu .replace ("-NS" , "" )
41
42
cpu_flag = "p" + cpu
42
43
43
44
# 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
+ }
48
52
res = debuggers [self .debug .lower ()]
49
53
binary = res [0 ]
50
54
key = res [1 ]
@@ -56,7 +60,7 @@ def generate_flash_dll(self):
56
60
S = SW/JTAG Clock ID
57
61
C = CPU index in JTAG chain
58
62
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:
60
64
FD = RAM Start for Flash Functions
61
65
FC = RAM Size for Flash Functions
62
66
FN = Number of Flash types
@@ -65,44 +69,55 @@ def generate_flash_dll(self):
65
69
FL = Size of the Flash Device
66
70
FP = Full path to the Device algorithm (RTE)
67
71
68
- Necessary to flash some targets. Info gathered from algorithms field of pdsc file.
72
+ Necessary to flash some targets.
69
73
'''
70
74
fl_count = 0
75
+
71
76
def get_mem_no_x (mem_str ):
72
77
mem_reg = "\dx(\w+)"
73
78
m = re .search (mem_reg , mem_str )
74
79
return m .group (1 ) if m else None
75
80
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
+ )
79
89
ramstart = ''
80
- #Default according to Keil developer
90
+ # Default according to Keil developer
81
91
ramsize = '1000'
82
- if len (RAMS )>= 1 :
92
+ if len (RAMS ) >= 1 :
83
93
ramstart = RAMS [0 ][0 ]
84
94
extra_flags = []
85
95
for name , info in self .target_info ["algorithm" ].items ():
86
96
if not name or not info :
87
97
continue
88
- if int (info ["default" ])== 0 :
98
+ if int (info ["default" ]) == 0 :
89
99
continue
90
100
name_reg = "\w*/([\w_]+)\.flm"
91
101
m = re .search (name_reg , name .lower ())
92
102
fl_name = m .group (1 ) if m else None
93
103
name_flag = "-FF" + str (fl_count ) + fl_name
94
104
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 )
97
108
rom_size_flag = "-FL" + str (fl_count ) + str (size )
98
109
99
110
if info ["ramstart" ] is not None and info ["ramsize" ] is not None :
100
111
ramstart = get_mem_no_x (info ["ramstart" ])
101
112
ramsize = get_mem_no_x (info ["ramsize" ])
102
113
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
+ )
104
117
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
+ ])
106
121
fl_count += 1
107
122
108
123
extra = " " .join (extra_flags )
@@ -118,8 +133,6 @@ class Uvision(Exporter):
118
133
project file (.uvprojx).
119
134
The needed information can be viewed in uvision.tmpl
120
135
"""
121
- NAME = 'uvision5'
122
- TOOLCHAIN = 'ARM'
123
136
124
137
POST_BINARY_WHITELIST = set ([
125
138
"MCU_NRF51Code.binary_hook" ,
@@ -131,24 +144,7 @@ class Uvision(Exporter):
131
144
"NCS36510TargetCode.ncs36510_addfib"
132
145
])
133
146
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
152
148
file_types = {'.cpp' : 8 , '.c' : 1 , '.s' : 2 ,
153
149
'.obj' : 3 , '.o' : 3 , '.lib' : 4 ,
154
150
'.ar' : 4 , '.h' : 5 , '.hpp' : 5 , '.sct' : 4 }
@@ -166,8 +162,8 @@ def uv_files(self, files):
166
162
</File>
167
163
"""
168
164
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' ])
171
167
_ , ext = os .path .splitext (loc )
172
168
if ext .lower () in self .file_types :
173
169
type = self .file_types [ext .lower ()]
@@ -177,22 +173,40 @@ def uv_files(self, files):
177
173
def format_flags (self ):
178
174
"""Format toolchain flags for Uvision"""
179
175
flags = copy .deepcopy (self .flags )
180
- # to be preprocessed with armcc
181
176
asm_flag_string = (
182
177
'--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 )))
184
180
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' ]))
196
210
return flags
197
211
198
212
def format_src (self , srcs ):
@@ -215,11 +229,11 @@ def format_fpu(core):
215
229
216
230
def generate (self ):
217
231
"""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
+ )
223
237
ctx = {
224
238
'name' : self .project_name ,
225
239
# project_files => dict of generators - file group to generator of
@@ -230,23 +244,29 @@ def generate(self):
230
244
self .resources .inc_dirs ).encode ('utf-8' ),
231
245
'device' : DeviceUvision (self .target ),
232
246
}
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 ]
234
249
ctx ['linker_script' ] = self .toolchain .correct_scatter_shebang (
235
250
sct_path , dirname (sct_name ))
236
251
if ctx ['linker_script' ] != sct_path :
237
252
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" ):
241
255
ctx ['fpu_setting' ] = 3
242
- elif core .endswith ("F" ):
256
+ elif ctx [ 'device' ]. core .endswith ("F" ):
243
257
ctx ['fpu_setting' ] = 2
244
258
else :
245
259
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
247
263
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
+ )
250
270
251
271
@staticmethod
252
272
def clean (project_name ):
@@ -285,3 +305,49 @@ def build(project_name, log_name='build_log.txt', cleanup=True):
285
305
return - 1
286
306
else :
287
307
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