Skip to content

Commit 98b4768

Browse files
committed
Initial toolchain class for ARMC6
While ARMC6 does use the same linker (armlink) as ARM Compiler 5, it is not compatible. The reason for this incompatibility are twofold: * armlink may invoke the C preprocessor by adding a shebang (`#!`) to the top of their input files. * ARMC6 and ARMC5 differ in how you invoke the preprocessor: * ARMC5: `#! armcc -E` * ARMC6: `#! armclang -E` This forces the tools to rewrite the shebang if it's wrong. This does not yet handle dependencies properly
1 parent cab660d commit 98b4768

File tree

7 files changed

+162
-34
lines changed

7 files changed

+162
-34
lines changed

tools/memap.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -769,8 +769,7 @@ def parse(self, mapfile, toolchain):
769769
# Common to all toolchains: first search for objects in BUILD
770770
self.list_dir_obj(os.path.abspath(mapfile))
771771

772-
if toolchain == "ARM" or toolchain == "ARM_STD" or\
773-
toolchain == "ARM_MICRO":
772+
if toolchain in ("ARM", "ARM_STD", "ARM_MICRO", "ARMC6"):
774773
self.parse_map_file_armcc(file_input)
775774
elif toolchain == "GCC_ARM" or toolchain == "GCC_CR":
776775
self.parse_map_file_gcc(file_input)

tools/profiles/debug.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@
1515
"-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit",
1616
"-Wl,-n"]
1717
},
18+
"ARMC6": {
19+
"common": ["-c", "--target=arm-arm-none-eabi", "-mthumb", "-g", "-O0",
20+
"-Wno-armcc-pragma-push-pop", "-Wno-armcc-pragma-anon-unions"],
21+
"asm": [],
22+
"c": ["-D__ASSERT_MSG", "-std=gnu99"],
23+
"cxx": ["-fno-rtti", "-std=gnu++98"],
24+
"ld": ["--verbose", "--remove", "--legacyalign", "--no_strict_wchar_size",
25+
"--no_strict_enum_size"]
26+
},
1827
"ARM": {
1928
"common": ["-c", "--gnu", "-Otime", "--split_sections",
2029
"--apcs=interwork", "--brief_diagnostics", "--restrict",

tools/profiles/develop.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@
1414
"-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit",
1515
"-Wl,-n"]
1616
},
17+
"ARMC6": {
18+
"common": ["-c", "--target=arm-arm-none-eabi", "-mthumb", "-Os",
19+
"-Wno-armcc-pragma-push-pop", "-Wno-armcc-pragma-anon-unions"],
20+
"asm": [],
21+
"c": ["-D__ASSERT_MSG", "-std=gnu99"],
22+
"cxx": ["-fno-rtti", "-std=gnu++98"],
23+
"ld": ["--legacyalign", "--no_strict_wchar_size", "--no_strict_enum_size"]
24+
},
1725
"ARM": {
1826
"common": ["-c", "--gnu", "-Otime", "--split_sections",
1927
"--apcs=interwork", "--brief_diagnostics", "--restrict",

tools/profiles/release.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@
1414
"-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit",
1515
"-Wl,-n"]
1616
},
17+
"ARMC6": {
18+
"common": ["-c", "--target=arm-arm-none-eabi", "-mthumb", "-Oz",
19+
"-Wno-armcc-pragma-push-pop", "-Wno-armcc-pragma-anon-unions"],
20+
"asm": [],
21+
"c": ["-D__ASSERT_MSG", "-std=gnu99"],
22+
"cxx": ["-fno-rtti", "-std=gnu++98"],
23+
"ld": ["--legacyalign", "--no_strict_wchar_size", "--no_strict_enum_size"]
24+
},
1725
"ARM": {
1826
"common": ["-c", "--gnu", "-Ospace", "--split_sections",
1927
"--apcs=interwork", "--brief_diagnostics", "--restrict",

tools/settings.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
# ARM Compiler 5
3131
ARM_PATH = ""
3232

33+
# ARM Compiler 6
34+
ARMC6_PATH = ""
35+
3336
# GCC ARM
3437
GCC_ARM_PATH = ""
3538

@@ -70,7 +73,8 @@
7073
##############################################################################
7174
# User Settings (env vars)
7275
##############################################################################
73-
_ENV_PATHS = ['ARM_PATH', 'GCC_ARM_PATH', 'GCC_CR_PATH', 'IAR_PATH']
76+
_ENV_PATHS = ['ARM_PATH', 'GCC_ARM_PATH', 'GCC_CR_PATH', 'IAR_PATH',
77+
'ARMC6_PATH']
7478

7579
for _n in _ENV_PATHS:
7680
if getenv('MBED_'+_n):

tools/toolchains/__init__.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -302,11 +302,13 @@ def __str__(self):
302302
'LPC11U24', 'LPC1768', 'LPC2368', 'LPC4088', 'LPC812', 'KL25Z',
303303
'ARM', 'uARM', 'IAR',
304304
'GCC_ARM', 'GCC_CS', 'GCC_CR', 'GCC_CW', 'GCC_CW_EWL', 'GCC_CW_NEWLIB',
305+
'ARMC6'
305306
])
306307
LEGACY_TOOLCHAIN_NAMES = {
307308
'ARM_STD':'ARM', 'ARM_MICRO': 'uARM',
308309
'GCC_ARM': 'GCC_ARM', 'GCC_CR': 'GCC_CR',
309310
'IAR': 'IAR',
311+
'ARMC6': 'ARMC6',
310312
}
311313

312314

@@ -1531,24 +1533,24 @@ def report(self):
15311533
to_ret.update(self.config.report)
15321534
return to_ret
15331535

1534-
from tools.settings import ARM_PATH
1535-
from tools.settings import GCC_ARM_PATH
1536-
from tools.settings import IAR_PATH
1536+
from tools.settings import ARM_PATH, ARMC6_PATH, GCC_ARM_PATH, IAR_PATH
15371537

15381538
TOOLCHAIN_PATHS = {
15391539
'ARM': ARM_PATH,
15401540
'uARM': ARM_PATH,
1541+
'ARMC6': ARMC6_PATH,
15411542
'GCC_ARM': GCC_ARM_PATH,
15421543
'IAR': IAR_PATH
15431544
}
15441545

1545-
from tools.toolchains.arm import ARM_STD, ARM_MICRO
1546+
from tools.toolchains.arm import ARM_STD, ARM_MICRO, ARMC6
15461547
from tools.toolchains.gcc import GCC_ARM
15471548
from tools.toolchains.iar import IAR
15481549

15491550
TOOLCHAIN_CLASSES = {
15501551
'ARM': ARM_STD,
15511552
'uARM': ARM_MICRO,
1553+
'ARMC6': ARMC6,
15521554
'GCC_ARM': GCC_ARM,
15531555
'IAR': IAR
15541556
}

tools/toolchains/arm.py

Lines changed: 125 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
limitations under the License.
1616
"""
1717
import re
18+
from copy import copy
1819
from os.path import join, dirname, splitext, basename, exists
1920
from os import makedirs, write
2021
from tempfile import mkstemp
@@ -31,6 +32,7 @@ class ARM(mbedToolchain):
3132
DIAGNOSTIC_PATTERN = re.compile('"(?P<file>[^"]+)", line (?P<line>\d+)( \(column (?P<column>\d+)\)|): (?P<severity>Warning|Error|Fatal error): (?P<message>.+)')
3233
INDEX_PATTERN = re.compile('(?P<col>\s*)\^')
3334
DEP_PATTERN = re.compile('\S+:\s(?P<file>.+)\n')
35+
SHEBANG = "#! armcc -E"
3436

3537
@staticmethod
3638
def check_executable():
@@ -175,32 +177,52 @@ def compile_c(self, source, object, includes):
175177
def compile_cpp(self, source, object, includes):
176178
return self.compile(self.cppc, source, object, includes)
177179

178-
@hook_tool
179-
def link(self, output, objects, libraries, lib_dirs, mem_map):
180-
map_file = splitext(output)[0] + ".map"
181-
if len(lib_dirs):
182-
args = ["-o", output, "--userlibpath", ",".join(lib_dirs), "--info=totals", "--map", "--list=%s" % map_file]
183-
else:
184-
args = ["-o", output, "--info=totals", "--map", "--list=%s" % map_file]
185-
186-
args.extend(self.flags['ld'])
180+
def correct_scatter_shebang(self, scatter_file):
181+
"""Correct the shebang at the top of a scatter file.
182+
183+
Positional arguments:
184+
scatter_file -- the scatter file to correct
185+
186+
Return:
187+
The location of the correct scatter file
188+
189+
Side Effects:
190+
This method MAY write a new scatter file to disk
191+
"""
192+
with open(scatter_file, "rb") as input:
193+
lines = input.readlines()
194+
if lines[0].startswith(self.SHEBANG):
195+
return scatter_file
196+
else:
197+
new_scatter = join(self.build_dir, ".link_script.sct")
198+
if self.need_update(new_scatter, [scatter_file]):
199+
with open(new_scatter, "wb") as out:
200+
out.write(self.SHEBANG)
201+
out.write("\n")
202+
out.write("".join(lines[1:]))
203+
return new_scatter
187204

188-
if mem_map:
189-
args.extend(["--scatter", mem_map])
190-
191-
# Build linker command
192-
cmd = self.ld + args + objects + libraries + self.sys_libs
193-
194-
# Call cmdline hook
195-
cmd = self.hook.get_cmdline_linker(cmd)
205+
@hook_tool
206+
def link(self, output, objects, libraries, lib_dirs, scatter_file):
207+
base, _ = splitext(output)
208+
map_file = base + ".map"
209+
args = ["-o", output, "--info=totals", "--map", "--list=%s" % map_file]
210+
args.extend(objects)
211+
args.extend(libraries)
212+
if lib_dirs:
213+
args.extend(["--userlibpath", ",".join(lib_dirs)])
214+
if scatter_file:
215+
new_scatter = self.correct_scatter_shebang(scatter_file)
216+
args.extend(["--scatter", new_scatter])
217+
218+
cmd_pre = self.ld + args
219+
cmd = self.hook.get_cmdline_linker(cmd_pre)
196220

197221
if self.RESPONSE_FILES:
198-
# Split link command to linker executable + response file
199222
cmd_linker = cmd[0]
200223
link_files = self.get_link_file(cmd[1:])
201224
cmd = [cmd_linker, '--via', link_files]
202225

203-
# Exec command
204226
self.cc_verbose("Link: %s" % ' '.join(cmd))
205227
self.default_cmd(cmd)
206228

@@ -210,21 +232,14 @@ def archive(self, objects, lib_path):
210232
param = ['--via', self.get_arch_file(objects)]
211233
else:
212234
param = objects
213-
214-
# Exec command
215235
self.default_cmd([self.ar, '-r', lib_path] + param)
216236

217237
@hook_tool
218238
def binary(self, resources, elf, bin):
219239
_, fmt = splitext(bin)
220240
bin_arg = {".bin": "--bin", ".hex": "--i32"}[fmt]
221-
# Build binary command
222241
cmd = [self.elf2bin, bin_arg, '-o', bin, elf]
223-
224-
# Call cmdline hook
225242
cmd = self.hook.get_cmdline_binary(cmd)
226-
227-
# Exec command
228243
self.cc_verbose("FromELF: %s" % ' '.join(cmd))
229244
self.default_cmd(cmd)
230245

@@ -248,6 +263,89 @@ def redirect_symbol(source, sync, build_dir):
248263
class ARM_STD(ARM):
249264
pass
250265

251-
252266
class ARM_MICRO(ARM):
253267
PATCHED_LIBRARY = False
268+
269+
class ARMC6(ARM_STD):
270+
SHEBANG = "#! armclang -E --target=arm-arm-none-eabi -x c"
271+
@staticmethod
272+
def check_executable():
273+
return mbedToolchain.generic_check_executable("ARMC6", "armclang", 1)
274+
275+
def __init__(self, target, *args, **kwargs):
276+
mbedToolchain.__init__(self, target, *args, **kwargs)
277+
278+
if target.core.lower().endswith("fd"):
279+
self.flags['common'].append("-mcpu=%s" % target.core.lower()[:-2])
280+
self.flags['ld'].append("--cpu=%s" % target.core.lower()[:-2])
281+
elif target.core.lower().endswith("f"):
282+
self.flags['common'].append("-mcpu=%s" % target.core.lower()[:-1])
283+
self.flags['ld'].append("--cpu=%s" % target.core.lower()[:-1])
284+
else:
285+
self.flags['common'].append("-mcpu=%s" % target.core.lower())
286+
self.flags['ld'].append("--cpu=%s" % target.core.lower())
287+
288+
if target.core == "Cortex-M4F":
289+
self.flags['common'].append("-mfpu=fpv4-sp-d16")
290+
self.flags['common'].append("-mfloat-abi=hard")
291+
elif target.core == "Cortex-M7F":
292+
self.flags['common'].append("-mfpu=fpv5-sp-d16")
293+
self.flags['common'].append("-mfloat-abi=softfp")
294+
elif target.core == "Cortex-M7FD":
295+
self.flags['common'].append("-mfpu=fpv5-d16")
296+
self.flags['common'].append("-mfloat-abi=softfp")
297+
298+
asm_cpu = {
299+
"Cortex-M0+": "Cortex-M0",
300+
"Cortex-M4F": "Cortex-M4.fp",
301+
"Cortex-M7F": "Cortex-M7.fp.sp",
302+
"Cortex-M7FD": "Cortex-M7.fp.dp"}.get(target.core, target.core)
303+
304+
self.flags['asm'].append("--cpu=%s" % asm_cpu)
305+
306+
self.cc = ([join(TOOLCHAIN_PATHS["ARMC6"], "armclang")] +
307+
self.flags['common'] + self.flags['c'])
308+
self.cppc = ([join(TOOLCHAIN_PATHS["ARMC6"], "armclang")] +
309+
self.flags['common'] + self.flags['cxx'])
310+
self.asm = [join(TOOLCHAIN_PATHS["ARMC6"], "armasm")] + self.flags['asm']
311+
self.ld = [join(TOOLCHAIN_PATHS["ARMC6"], "armlink")] + self.flags['ld']
312+
self.ar = [join(TOOLCHAIN_PATHS["ARMC6"], "armar")]
313+
self.elf2bin = join(TOOLCHAIN_PATHS["ARMC6"], "fromelf")
314+
315+
316+
def parse_dependencies(self, dep_path):
317+
return []
318+
319+
def parse_output(self, output):
320+
pass
321+
322+
def get_config_option(self, config_header):
323+
return ["-include", config_header]
324+
325+
def get_compile_options(self, defines, includes, for_asm=False):
326+
opts = ['-D%s' % d for d in defines]
327+
opts.extend(["-I%s" % i for i in includes])
328+
if for_asm:
329+
return ["--cpreproc",
330+
"--cpreproc_opts=%s" % ",".join(self.flags['common'] + opts)]
331+
else:
332+
config_header = self.get_config_header()
333+
if config_header:
334+
opts.extend(self.get_config_option(config_header))
335+
return opts
336+
337+
@hook_tool
338+
def assemble(self, source, object, includes):
339+
cmd_pre = copy(self.asm)
340+
cmd_pre.extend(self.get_compile_options(
341+
self.get_symbols(True), includes, for_asm=True))
342+
cmd_pre.extend(["-o", object, source])
343+
return [self.hook.get_cmdline_assembler(cmd_pre)]
344+
345+
@hook_tool
346+
def compile(self, cc, source, object, includes):
347+
cmd = copy(cc)
348+
cmd.extend(self.get_compile_options(self.get_symbols(), includes))
349+
cmd.extend(["-o", object, source])
350+
cmd = self.hook.get_cmdline_compiler(cmd)
351+
return [cmd]

0 commit comments

Comments
 (0)