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)
154 if dev in MDK_ENV['RTE']:
156 "{dev}/{cc}/default.rtebuild".format(dev = dev, cc = cc, target=target),
157 "{dev}/{cc}/build/{target}.elf".format(dev = dev, cc = cc, target=target)
161 "{dev}/{cc}/CMSIS_CV.ewp".format(dev = dev, cc = cc),
162 "{dev}/{cc}/{target}/Exe/CMSIS_CV.out".format(dev = dev, cc = cc, target = target)
164 raise "Unknown compiler!"
166 def bootloaderProject(dev, cc, target):
167 if (cc == CC_AC5) or (cc == CC_AC6):
169 "{dev}/{cc}/Bootloader/Bootloader.uvprojx".format(dev = dev, cc = cc),
170 "{dev}/{cc}/Bootloader/Objects/Bootloader.axf".format(dev = dev, cc = cc)
174 "{dev}/{cc}/Bootloader/Bootloader.uvprojx".format(dev = dev, cc = cc),
175 "{dev}/{cc}/Bootloader/Objects/Bootloader.elf".format(dev = dev, cc = cc)
179 "{dev}/{cc}/Bootloader/Bootloader.ewp".format(dev = dev, cc = cc),
180 "{dev}/{cc}/Bootloader/{target}/Exe/Bootloader.out".format(dev = dev, cc = cc, target = target)
182 raise "Unknown compiler!"
184 def buildStep(dev, cc, target, project):
185 if (cc == CC_AC5) or (cc == CC_AC6):
186 if dev in MDK_ENV['DS']:
187 return DsCmd(project, "CMSIS_CV_{adev}_{cc}".format(adev=ADEVICES[dev], cc = cc))
188 elif dev in MDK_ENV['RTE']:
189 return RteCmd(project, target)
191 return Uv4Cmd(project, target)
193 if dev in MDK_ENV['DS']:
194 return DsCmd(project, target)
195 elif dev in MDK_ENV['RTE']:
196 return RteCmd(project, target)
198 return Uv4Cmd(project, target)
200 if dev in MDK_ENV['RTE']:
201 return RteCmd(project, target)
203 return IarCmd(project, target)
204 raise "Unknown compiler!"
206 def prepare(steps, args):
207 for dev in args.devices:
208 for cc in args.compilers:
209 for target in args.targets:
210 if not isSkipped(dev, cc, target):
211 config = "{dev} ({cc}, {target})".format(dev = dev, cc = cc, target = target)
212 prefix = "{dev}_{cc}_{target}".format(dev = dev, cc = cc, target = target)
214 rv = testProject(dev, cc, target)
215 build = [ buildStep(dev, cc, target, rv[0]) ]
218 bl = bootloaderProject(dev, cc, target)
219 if os.path.isfile(bl[0]):
220 build = [ buildStep(dev, cc, target, bl[0]) ] + build
221 binary = [ bl[1] ] + binary
223 if target == TARGET_FVP:
224 test = FvpCmd(FVP_MODELS[dev]['cmd'], binary, **FVP_MODELS[dev]['args'])
225 steps += [ { 'name': config, 'prefix': prefix, 'build': build, 'test': test } ]
227 def execute(steps, args):
230 if step['build'] and not args.execute_only:
231 for b in step['build']:
234 print("Skipping build")
235 # step['build'].skip()
237 if step['test'] and not args.build_only:
239 step['result'] = TestResult(step['test'].getOutput())
240 step['result'].saveXml("result_{0}_{1}.xml".format(step['prefix'], datetime.now().strftime("%Y%m%d%H%M%S")))
242 print("Skipping test")
245 def printSummary(steps):
247 print("Test Summary")
248 print("============")
250 print("Test run Total Exec Pass Fail ")
251 print("-------------------------------------------------------")
254 print("{0:30} {1:>4} {2:>4} {3:>4} {4:>4}".format(step['name'], *step['result'].getSummary()))
256 print("{0:30} ------ NO RESULTS ------".format(step['name']))
259 parser = ArgumentParser()
260 parser.add_argument('--genconfig', action='store_true')
261 parser.add_argument('-b', '--build-only', action='store_true')
262 parser.add_argument('-e', '--execute-only', action='store_true')
263 parser.add_argument('-d', '--devices', nargs='*', choices=(DEVICES+list(ADEVICES.values())), default=DEVICES, help = 'Devices to be considered.')
264 parser.add_argument('-c', '--compilers', nargs='*', choices=COMPILERS, default=COMPILERS, help = 'Compilers to be considered.')
265 parser.add_argument('-t', '--targets', nargs='*', choices=TARGETS, default=TARGETS, help = 'Targets to be considered.')
266 args = parser.parse_args()
269 for d in args.devices:
270 if d in ADEVICES.values():
271 d = list(ADEVICES.keys())[list(ADEVICES.values()).index(d)]
274 args.devices = list(devices)
277 for dev in args.devices:
278 model = FVP_MODELS[dev]
279 cmd = [ model['cmd'], '-l', '-o', model['args']['config'] ]
292 if __name__ == "__main__":