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-M0_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 if (cc == CC_AC5) or (cc == CC_AC6):
122 if dev in MDK_ENV['DS']:
124 "{dev}/{cc}/.project".format(dev = dev, cc = cc),
125 "{dev}/{cc}/Debug/CMSIS_CV_{adev}_{cc}.axf".format(dev = dev, adev=ADEVICES[dev], cc = cc)
127 elif dev in MDK_ENV['RTE']:
129 "{dev}/{cc}/default.rtebuild".format(dev = dev, cc = cc, target=target),
130 "{dev}/{cc}/build/{target}.elf".format(dev = dev, cc = cc, target=target)
134 "{dev}/{cc}/CMSIS_CV.uvprojx".format(dev = dev, cc = cc),
135 "{dev}/{cc}/Objects/CMSIS_CV.axf".format(dev = dev, cc = cc)
138 if dev in MDK_ENV['DS']:
140 "{dev}/{cc}/.project".format(dev = dev, cc = cc),
141 "{dev}/{cc}/Debug/CMSIS_CV_{adev}_{cc}.elf".format(dev = dev, adev=ADEVICES[dev], cc = cc)
143 elif dev in MDK_ENV['RTE']:
145 "{dev}/{cc}/default.rtebuild".format(dev = dev, cc = cc, target=target),
146 "{dev}/{cc}/build/{target}.elf".format(dev = dev, cc = cc, target=target)
150 "{dev}/{cc}/CMSIS_CV.uvprojx".format(dev = dev, cc = cc),
151 "{dev}/{cc}/Objects/CMSIS_CV.elf".format(dev = dev, cc = cc)
155 "{dev}/{cc}/CMSIS_CV.ewp".format(dev = dev, cc = cc),
156 "{dev}/{cc}/{target}/Exe/CMSIS_CV.out".format(dev = dev, cc = cc, target = target)
158 raise "Unknown compiler!"
160 def bootloaderProject(dev, cc, target):
161 if (cc == CC_AC5) or (cc == CC_AC6):
163 "{dev}/{cc}/Bootloader/Bootloader.uvprojx".format(dev = dev, cc = cc),
164 "{dev}/{cc}/Bootloader/Objects/Bootloader.axf".format(dev = dev, cc = cc)
168 "{dev}/{cc}/Bootloader/Bootloader.uvprojx".format(dev = dev, cc = cc),
169 "{dev}/{cc}/Bootloader/Objects/Bootloader.elf".format(dev = dev, cc = cc)
173 "{dev}/{cc}/Bootloader/Bootloader.ewp".format(dev = dev, cc = cc),
174 "{dev}/{cc}/Bootloader/{target}/Exe/Bootloader.out".format(dev = dev, cc = cc, target = target)
176 raise "Unknown compiler!"
178 def buildStep(dev, cc, target, project):
179 if (cc == CC_AC5) or (cc == CC_AC6):
180 if dev in MDK_ENV['DS']:
181 return DsCmd(project, "CMSIS_CV_{adev}_{cc}".format(adev=ADEVICES[dev], cc = cc))
182 elif dev in MDK_ENV['RTE']:
183 return RteCmd(project, target)
185 return Uv4Cmd(project, target)
187 if dev in MDK_ENV['DS']:
188 return DsCmd(project, target)
189 elif dev in MDK_ENV['RTE']:
190 return RteCmd(project, target)
192 return Uv4Cmd(project, target)
194 return IarCmd(project, target)
195 raise "Unknown compiler!"
197 def prepare(steps, args):
198 for dev in args.devices:
199 for cc in args.compilers:
200 for target in args.targets:
201 if not isSkipped(dev, cc, target):
202 config = "{dev} ({cc}, {target})".format(dev = dev, cc = cc, target = target)
203 prefix = "{dev}_{cc}_{target}".format(dev = dev, cc = cc, target = target)
205 rv = testProject(dev, cc, target)
206 build = [ buildStep(dev, cc, target, rv[0]) ]
209 bl = bootloaderProject(dev, cc, target)
210 if os.path.isfile(bl[0]):
211 build = [ buildStep(dev, cc, target, bl[0]) ] + build
212 binary = [ bl[1] ] + binary
214 if target == TARGET_FVP:
215 test = FvpCmd(FVP_MODELS[dev]['cmd'], binary, **FVP_MODELS[dev]['args'])
216 steps += [ { 'name': config, 'prefix': prefix, 'build': build, 'test': test } ]
218 def execute(steps, args):
221 if step['build'] and not args.execute_only:
222 for b in step['build']:
225 print("Skipping build")
226 # step['build'].skip()
228 if step['test'] and not args.build_only:
230 step['result'] = TestResult(step['test'].getOutput())
231 step['result'].saveXml("result_{0}_{1}.xml".format(step['prefix'], datetime.now().strftime("%Y%m%d%H%M%S")))
233 print("Skipping test")
236 def printSummary(steps):
238 print("Test Summary")
239 print("============")
241 print("Test run Total Exec Pass Fail ")
242 print("-------------------------------------------------------")
245 print("{0:30} {1:>4} {2:>4} {3:>4} {4:>4}".format(step['name'], *step['result'].getSummary()))
247 print("{0:30} ------ NO RESULTS ------".format(step['name']))
250 parser = ArgumentParser()
251 parser.add_argument('--genconfig', action='store_true')
252 parser.add_argument('-b', '--build-only', action='store_true')
253 parser.add_argument('-e', '--execute-only', action='store_true')
254 parser.add_argument('-d', '--devices', nargs='*', choices=(DEVICES+list(ADEVICES.values())), default=DEVICES, help = 'Devices to be considered.')
255 parser.add_argument('-c', '--compilers', nargs='*', choices=COMPILERS, default=COMPILERS, help = 'Compilers to be considered.')
256 parser.add_argument('-t', '--targets', nargs='*', choices=TARGETS, default=TARGETS, help = 'Targets to be considered.')
257 args = parser.parse_args()
260 for d in args.devices:
261 if d in ADEVICES.values():
262 d = list(ADEVICES.keys())[list(ADEVICES.values()).index(d)]
265 args.devices = list(devices)
268 for dev in args.devices:
269 model = FVP_MODELS[dev]
270 cmd = [ model['cmd'], '-l', '-o', model['args']['config'] ]
283 if __name__ == "__main__":