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}/{target}.elf".format(dev = dev, cc = cc, target=target)
127 elif (cc == CC_AC5) or (cc == CC_AC6):
129 "{dev}/{cc}/CMSIS_CV.uvprojx".format(dev = dev, cc = cc),
130 "{dev}/{cc}/Objects/CMSIS_CV.axf".format(dev = dev, cc = cc)
134 "{dev}/{cc}/CMSIS_CV.uvprojx".format(dev = dev, cc = cc),
135 "{dev}/{cc}/Objects/CMSIS_CV.elf".format(dev = dev, cc = cc)
139 "{dev}/{cc}/CMSIS_CV.ewp".format(dev = dev, cc = cc),
140 "{dev}/{cc}/{target}/Exe/CMSIS_CV.out".format(dev = dev, cc = cc, target = target)
142 raise "Unknown compiler!"
144 def bootloaderProject(dev, cc, target):
145 rtebuild = "{dev}/{cc}/Bootloader/default.rtebuild".format(dev = dev, cc = cc, target=target)
146 if os.path.exists(rtebuild):
149 "{dev}/{cc}/Bootloader/build/{target}/{target}.elf".format(dev = dev, cc = cc, target=target)
151 elif (cc == CC_AC5) or (cc == CC_AC6):
153 "{dev}/{cc}/Bootloader/Bootloader.uvprojx".format(dev = dev, cc = cc),
154 "{dev}/{cc}/Bootloader/Objects/Bootloader.axf".format(dev = dev, cc = cc)
158 "{dev}/{cc}/Bootloader/Bootloader.uvprojx".format(dev = dev, cc = cc),
159 "{dev}/{cc}/Bootloader/Objects/Bootloader.elf".format(dev = dev, cc = cc)
163 "{dev}/{cc}/Bootloader/Bootloader.ewp".format(dev = dev, cc = cc),
164 "{dev}/{cc}/Bootloader/{target}/Exe/Bootloader.out".format(dev = dev, cc = cc, target = target)
166 raise "Unknown compiler!"
168 def buildStep(dev, cc, target, project):
175 projectfile, projectext = os.path.splitext(project)
177 if not projectext in STEP_TYPES:
178 raise "Unknown project type '"+projectext+"'!"
180 return STEP_TYPES[projectext](project, target)
182 def prepare(steps, args):
183 for dev in args.devices:
184 for cc in args.compilers:
185 for target in args.targets:
186 if not isSkipped(dev, cc, target):
187 config = "{dev} ({cc}, {target})".format(dev = dev, cc = cc, target = target)
188 prefix = "{dev}_{cc}_{target}".format(dev = dev, cc = cc, target = target)
190 rv = testProject(dev, cc, target)
191 build = [ buildStep(dev, cc, target, rv[0]) ]
194 bl = bootloaderProject(dev, cc, target)
195 if os.path.isfile(bl[0]):
196 build = [ buildStep(dev, cc, target, bl[0]) ] + build
197 binary = [ bl[1] ] + binary
199 if target == TARGET_FVP:
200 test = FvpCmd(FVP_MODELS[dev]['cmd'], binary, **FVP_MODELS[dev]['args'])
201 steps += [ { 'name': config, 'prefix': prefix, 'build': build, 'test': test } ]
203 def execute(steps, args):
206 if step['build'] and not args.execute_only:
207 for b in step['build']:
210 print("Skipping build")
211 # step['build'].skip()
213 if step['test'] and not args.build_only:
215 step['result'] = TestResult(step['test'].getOutput())
216 step['result'].saveXml("result_{0}_{1}.xml".format(step['prefix'], datetime.now().strftime("%Y%m%d%H%M%S")))
218 print("Skipping test")
221 def printSummary(steps):
223 print("Test Summary")
224 print("============")
226 print("Test run Total Exec Pass Fail ")
227 print("-------------------------------------------------------")
230 print("{0:30} {1:>4} {2:>4} {3:>4} {4:>4}".format(step['name'], *step['result'].getSummary()))
232 print("{0:30} ------ NO RESULTS ------".format(step['name']))
235 parser = ArgumentParser()
236 parser.add_argument('--genconfig', action='store_true')
237 parser.add_argument('-b', '--build-only', action='store_true')
238 parser.add_argument('-e', '--execute-only', action='store_true')
239 parser.add_argument('-d', '--devices', nargs='*', choices=(DEVICES+list(ADEVICES.values())), default=DEVICES, help = 'Devices to be considered.')
240 parser.add_argument('-c', '--compilers', nargs='*', choices=COMPILERS, default=COMPILERS, help = 'Compilers to be considered.')
241 parser.add_argument('-t', '--targets', nargs='*', choices=TARGETS, default=TARGETS, help = 'Targets to be considered.')
242 args = parser.parse_args()
245 for d in args.devices:
246 if d in ADEVICES.values():
247 d = list(ADEVICES.keys())[list(ADEVICES.values()).index(d)]
250 args.devices = list(devices)
253 for dev in args.devices:
254 model = FVP_MODELS[dev]
255 cmd = [ model['cmd'], '-l', '-o', model['args']['config'] ]
268 if __name__ == "__main__":