5 from argparse import ArgumentParser
6 from datetime import datetime
7 from subprocess import call, Popen
9 sys.path.append('buildutils')
11 from rtecmd import RteCmd
12 from uv4cmd import Uv4Cmd
13 from dscmd import DsCmd
14 from fvpcmd import FvpCmd
15 from iarcmd import IarCmd
16 from testresult import TestResult
18 DEVICE_CM0 = 'Cortex-M0'
19 DEVICE_CM0PLUS = 'Cortex-M0plus'
20 DEVICE_CM3 = 'Cortex-M3'
21 DEVICE_CM4 = 'Cortex-M4'
22 DEVICE_CM4FP = 'Cortex-M4FP'
23 DEVICE_CM7 = 'Cortex-M7'
24 DEVICE_CM7SP = 'Cortex-M7SP'
25 DEVICE_CM7DP = 'Cortex-M7DP'
26 DEVICE_CM23 = 'Cortex-M23'
27 DEVICE_CM33 = 'Cortex-M33'
28 DEVICE_CM23NS = 'Cortex-M23NS'
29 DEVICE_CM33NS = 'Cortex-M33NS'
30 DEVICE_CM23S = 'Cortex-M23S'
31 DEVICE_CM33S = 'Cortex-M33S'
32 DEVICE_CA5 = 'Cortex-A5'
33 DEVICE_CA7 = 'Cortex-A7'
34 DEVICE_CA9 = 'Cortex-A9'
35 DEVICE_CA5NEON = 'Cortex-A5neon'
36 DEVICE_CA7NEON = 'Cortex-A7neon'
37 DEVICE_CA9NEON = 'Cortex-A9neon'
45 'uVision' : [ DEVICE_CM0, DEVICE_CM0PLUS, DEVICE_CM3, DEVICE_CM4, DEVICE_CM4FP, DEVICE_CM7, DEVICE_CM7SP, DEVICE_CM7DP, DEVICE_CM23, DEVICE_CM33, DEVICE_CM23NS, DEVICE_CM33NS, DEVICE_CM23S, DEVICE_CM33S ],
47 'RTE' : [ DEVICE_CA5, DEVICE_CA7, DEVICE_CA9, DEVICE_CA5NEON, DEVICE_CA7NEON, DEVICE_CA9NEON ]
54 DEVICE_CM0PLUS : 'CM0plus',
57 DEVICE_CM4FP : 'CM4FP',
59 DEVICE_CM7SP : 'CM7SP',
60 DEVICE_CM7DP : 'CM7DP',
63 DEVICE_CM23S : 'CM23S',
64 DEVICE_CM33S : 'CM33S',
65 DEVICE_CM33NS : 'CM33NS',
66 DEVICE_CM23NS : 'CM23NS',
70 DEVICE_CA5NEON : 'CA5neon',
71 DEVICE_CA7NEON : 'CA7neon',
72 DEVICE_CA9NEON : 'CA9neon'
75 DEVICES = [ DEVICE_CM0, DEVICE_CM0PLUS, DEVICE_CM3, DEVICE_CM4, DEVICE_CM4FP, DEVICE_CM7, DEVICE_CM7SP, DEVICE_CM7DP, DEVICE_CM23, DEVICE_CM33, DEVICE_CM23NS, DEVICE_CM33NS, DEVICE_CM23S, DEVICE_CM33S, DEVICE_CA5, DEVICE_CA7, DEVICE_CA9, DEVICE_CA5NEON, DEVICE_CA7NEON, DEVICE_CA9NEON ]
76 COMPILERS = [ CC_AC5, CC_AC6, CC_GCC, CC_IAR ]
77 TARGETS = [ TARGET_FVP ]
80 [ DEVICE_CM23, CC_AC5, None ],
81 [ DEVICE_CM33, CC_AC5, None ],
82 [ DEVICE_CM23NS, CC_AC5, None ],
83 [ DEVICE_CM33NS, CC_AC5, None ],
84 [ DEVICE_CM23S, CC_AC5, None ],
85 [ DEVICE_CM33S, CC_AC5, None ],
89 DEVICE_CM0 : { 'cmd': "FVP_MPS2_Cortex-M0_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM0_config.txt" } },
90 DEVICE_CM0PLUS : { 'cmd': "FVP_MPS2_Cortex-M0plus_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM0plus_config.txt" } },
91 DEVICE_CM3 : { 'cmd': "FVP_MPS2_Cortex-M3_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM3_config.txt" } },
92 DEVICE_CM4 : { 'cmd': "FVP_MPS2_Cortex-M4_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM4_config.txt" } },
93 DEVICE_CM4FP : { 'cmd': "FVP_MPS2_Cortex-M4_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM4FP_config.txt" } },
94 DEVICE_CM7 : { 'cmd': "FVP_MPS2_Cortex-M7_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM7_config.txt" } },
95 DEVICE_CM7SP : { 'cmd': "FVP_MPS2_Cortex-M7_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM7SP_config.txt" } },
96 DEVICE_CM7DP : { 'cmd': "FVP_MPS2_Cortex-M7_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM7DP_config.txt" } },
97 DEVICE_CM23 : { 'cmd': "FVP_MPS2_Cortex-M23_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM23_config.txt", 'target': "cpu0" } },
98 DEVICE_CM33 : { 'cmd': "FVP_MPS2_Cortex-M33_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM33_config.txt", 'target': "cpu0" } },
99 DEVICE_CM23NS : { 'cmd': "FVP_MPS2_Cortex-M23_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM23_TZ_config.txt", 'target': "cpu0" } },
100 DEVICE_CM33NS : { 'cmd': "FVP_MPS2_Cortex-M33_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM33_DSP_FP_TZ_config.txt", 'target': "cpu0" } },
101 DEVICE_CM23S : { 'cmd': "FVP_MPS2_Cortex-M23_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM23_TZ_config.txt", 'target': "cpu0" } },
102 DEVICE_CM33S : { 'cmd': "FVP_MPS2_Cortex-M33_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM33_DSP_FP_TZ_config.txt", 'target': "cpu0" } },
103 DEVICE_CA5 : { 'cmd': "fvp_ve_cortex-a5x1.exe", 'args': { 'limit': "70000000", 'config': "ARMCA5_config.txt" } },
104 DEVICE_CA7 : { 'cmd': "fvp_ve_cortex-a7x1.exe", 'args': { 'limit': "170000000", 'config': "ARMCA7_config.txt" } },
105 DEVICE_CA9 : { 'cmd': "fvp_ve_cortex-a9x1.exe", 'args': { 'limit': "70000000", 'config': "ARMCA9_config.txt" } },
106 DEVICE_CA5NEON : { 'cmd': "fvp_ve_cortex-a5x1.exe", 'args': { 'limit': "70000000", 'config': "ARMCA5neon_config.txt" } },
107 DEVICE_CA7NEON : { 'cmd': "fvp_ve_cortex-a7x1.exe", 'args': { 'limit': "170000000", 'config': "ARMCA7neon_config.txt" } },
108 DEVICE_CA9NEON : { 'cmd': "fvp_ve_cortex-a9x1.exe", 'args': { 'limit': "70000000", 'config': "ARMCA9neon_config.txt" } }
111 def isSkipped(dev, cc, target):
113 skipDev = (skip[0] == None or skip[0] == dev)
114 skipCc = (skip[1] == None or skip[1] == cc)
115 skipTarget = (skip[2] == None or skip[2] == target)
116 if skipDev and skipCc and skipTarget:
120 def testProject(dev, cc, target):
121 rtebuild = "{dev}/{cc}/default.rtebuild".format(dev = dev, cc = cc, target=target)
122 if os.path.exists(rtebuild):
125 "{dev}/{cc}/build/{target}.elf".format(dev = dev, cc = cc, target=target)
127 elif (cc == CC_AC5) or (cc == CC_AC6):
128 if dev in MDK_ENV['DS']:
130 "{dev}/{cc}/.project".format(dev = dev, cc = cc),
131 "{dev}/{cc}/Debug/CMSIS_CV_{adev}_{cc}.axf".format(dev = dev, adev=ADEVICES[dev], cc = cc)
133 elif dev in MDK_ENV['RTE']:
135 "{dev}/{cc}/default.rtebuild".format(dev = dev, cc = cc, target=target),
136 "{dev}/{cc}/build/{target}.elf".format(dev = dev, cc = cc, target=target)
140 "{dev}/{cc}/CMSIS_CV.uvprojx".format(dev = dev, cc = cc),
141 "{dev}/{cc}/Objects/CMSIS_CV.axf".format(dev = dev, cc = cc)
144 if dev in MDK_ENV['DS']:
146 "{dev}/{cc}/.project".format(dev = dev, cc = cc),
147 "{dev}/{cc}/Debug/CMSIS_CV_{adev}_{cc}.elf".format(dev = dev, adev=ADEVICES[dev], cc = cc)
149 elif dev in MDK_ENV['RTE']:
151 "{dev}/{cc}/default.rtebuild".format(dev = dev, cc = cc, target=target),
152 "{dev}/{cc}/build/{target}.elf".format(dev = dev, cc = cc, target=target)
156 "{dev}/{cc}/CMSIS_CV.uvprojx".format(dev = dev, cc = cc),
157 "{dev}/{cc}/Objects/CMSIS_CV.elf".format(dev = dev, cc = cc)
160 if dev in MDK_ENV['RTE']:
162 "{dev}/{cc}/default.rtebuild".format(dev = dev, cc = cc, target=target),
163 "{dev}/{cc}/build/{target}.elf".format(dev = dev, cc = cc, target=target)
167 "{dev}/{cc}/CMSIS_CV.ewp".format(dev = dev, cc = cc),
168 "{dev}/{cc}/{target}/Exe/CMSIS_CV.out".format(dev = dev, cc = cc, target = target)
170 raise "Unknown compiler!"
172 def bootloaderProject(dev, cc, target):
173 rtebuild = "{dev}/{cc}/Bootloader/default.rtebuild".format(dev = dev, cc = cc, target=target)
174 if os.path.exists(rtebuild):
177 "{dev}/{cc}/Bootloader/build/{target}.elf".format(dev = dev, cc = cc, target=target)
179 elif (cc == CC_AC5) or (cc == CC_AC6):
181 "{dev}/{cc}/Bootloader/Bootloader.uvprojx".format(dev = dev, cc = cc),
182 "{dev}/{cc}/Bootloader/Objects/Bootloader.axf".format(dev = dev, cc = cc)
186 "{dev}/{cc}/Bootloader/Bootloader.uvprojx".format(dev = dev, cc = cc),
187 "{dev}/{cc}/Bootloader/Objects/Bootloader.elf".format(dev = dev, cc = cc)
191 "{dev}/{cc}/Bootloader/Bootloader.ewp".format(dev = dev, cc = cc),
192 "{dev}/{cc}/Bootloader/{target}/Exe/Bootloader.out".format(dev = dev, cc = cc, target = target)
194 raise "Unknown compiler!"
196 def buildStep(dev, cc, target, project):
203 projectfile, projectext = os.path.splitext(project)
205 if not projectext in STEP_TYPES:
206 raise "Unknown project type '"+projectext+"'!"
208 return STEP_TYPES[projectext](project, target)
210 def prepare(steps, args):
211 for dev in args.devices:
212 for cc in args.compilers:
213 for target in args.targets:
214 if not isSkipped(dev, cc, target):
215 config = "{dev} ({cc}, {target})".format(dev = dev, cc = cc, target = target)
216 prefix = "{dev}_{cc}_{target}".format(dev = dev, cc = cc, target = target)
218 rv = testProject(dev, cc, target)
219 build = [ buildStep(dev, cc, target, rv[0]) ]
222 bl = bootloaderProject(dev, cc, target)
223 if os.path.isfile(bl[0]):
224 build = [ buildStep(dev, cc, target, bl[0]) ] + build
225 binary = [ bl[1] ] + binary
227 if target == TARGET_FVP:
228 test = FvpCmd(FVP_MODELS[dev]['cmd'], binary, **FVP_MODELS[dev]['args'])
229 steps += [ { 'name': config, 'prefix': prefix, 'build': build, 'test': test } ]
231 def execute(steps, args):
234 if step['build'] and not args.execute_only:
235 for b in step['build']:
238 print("Skipping build")
239 # step['build'].skip()
241 if step['test'] and not args.build_only:
243 step['result'] = TestResult(step['test'].getOutput())
244 step['result'].saveXml("result_{0}_{1}.xml".format(step['prefix'], datetime.now().strftime("%Y%m%d%H%M%S")))
246 print("Skipping test")
249 def printSummary(steps):
251 print("Test Summary")
252 print("============")
254 print("Test run Total Exec Pass Fail ")
255 print("-------------------------------------------------------")
258 print("{0:30} {1:>4} {2:>4} {3:>4} {4:>4}".format(step['name'], *step['result'].getSummary()))
260 print("{0:30} ------ NO RESULTS ------".format(step['name']))
263 parser = ArgumentParser()
264 parser.add_argument('--genconfig', action='store_true')
265 parser.add_argument('-b', '--build-only', action='store_true')
266 parser.add_argument('-e', '--execute-only', action='store_true')
267 parser.add_argument('-d', '--devices', nargs='*', choices=(DEVICES+list(ADEVICES.values())), default=DEVICES, help = 'Devices to be considered.')
268 parser.add_argument('-c', '--compilers', nargs='*', choices=COMPILERS, default=COMPILERS, help = 'Compilers to be considered.')
269 parser.add_argument('-t', '--targets', nargs='*', choices=TARGETS, default=TARGETS, help = 'Targets to be considered.')
270 args = parser.parse_args()
273 for d in args.devices:
274 if d in ADEVICES.values():
275 d = list(ADEVICES.keys())[list(ADEVICES.values()).index(d)]
278 args.devices = list(devices)
281 for dev in args.devices:
282 model = FVP_MODELS[dev]
283 cmd = [ model['cmd'], '-l', '-o', model['args']['config'] ]
296 if __name__ == "__main__":