]> begriffs open source - cmsis/blob - CMSIS/CoreValidation/Tests/build.py
CoreValidation: Fixed Validation test for Cortex-M33 without DSP on GCC.
[cmsis] / CMSIS / CoreValidation / Tests / build.py
1 #! python
2
3 import sys
4 import os.path
5 from argparse import ArgumentParser
6 from datetime import datetime
7 from subprocess import call, Popen
8
9 sys.path.append('buildutils') 
10
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
17
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'
38
39 CC_AC6 = 'AC6'
40 CC_AC5 = 'AC5'
41 CC_GCC = 'GCC'
42 CC_IAR = 'IAR'
43
44 MDK_ENV = {
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 ],
46   'DS'      : [ ], 
47   'RTE'     : [ DEVICE_CA5, DEVICE_CA7, DEVICE_CA9, DEVICE_CA5NEON, DEVICE_CA7NEON, DEVICE_CA9NEON ]
48 }
49
50 TARGET_FVP = 'FVP'
51
52 ADEVICES = {
53     DEVICE_CM0     : 'CM0',
54     DEVICE_CM0PLUS : 'CM0plus',
55     DEVICE_CM3     : 'CM3',
56     DEVICE_CM4     : 'CM4',
57     DEVICE_CM4FP   : 'CM4FP',
58     DEVICE_CM7     : 'CM7',
59     DEVICE_CM7SP   : 'CM7SP',
60     DEVICE_CM7DP   : 'CM7DP',
61     DEVICE_CM23    : 'CM23',
62     DEVICE_CM33    : 'CM33',
63     DEVICE_CM23S   : 'CM23S',
64     DEVICE_CM33S   : 'CM33S',
65     DEVICE_CM33NS  : 'CM33NS',
66     DEVICE_CM23NS  : 'CM23NS',
67     DEVICE_CA5     : 'CA5',
68     DEVICE_CA7     : 'CA7',
69     DEVICE_CA9     : 'CA9',
70     DEVICE_CA5NEON : 'CA5neon',
71     DEVICE_CA7NEON : 'CA7neon',
72     DEVICE_CA9NEON : 'CA9neon'
73   }
74
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 ]
78
79 SKIP = [ 
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 ],
86   ]
87   
88 FVP_MODELS = { 
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" } }
109   }
110
111 def isSkipped(dev, cc, target):
112   for skip in SKIP:
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:
117       return True
118   return False
119   
120 def testProject(dev, cc, target):
121   if (cc == CC_AC5) or (cc == CC_AC6):
122     if dev in MDK_ENV['DS']:
123       return [
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)
126         ]
127     elif dev in MDK_ENV['RTE']:
128       return [
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)
131         ]
132     else:
133       return [
134           "{dev}/{cc}/CMSIS_CV.uvprojx".format(dev = dev, cc = cc),
135           "{dev}/{cc}/Objects/CMSIS_CV.axf".format(dev = dev, cc = cc)
136         ]
137   elif (cc == CC_GCC):
138     if dev in MDK_ENV['DS']:
139       return [
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)
142         ]
143     elif dev in MDK_ENV['RTE']:
144       return [
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)
147         ]
148     else:
149       return [
150           "{dev}/{cc}/CMSIS_CV.uvprojx".format(dev = dev, cc = cc),
151           "{dev}/{cc}/Objects/CMSIS_CV.elf".format(dev = dev, cc = cc)
152         ]
153   elif (cc == CC_IAR):
154     if dev in MDK_ENV['RTE']:
155       return [
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)
158         ]
159     else:
160       return [
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)
163         ]
164   raise "Unknown compiler!"
165
166 def bootloaderProject(dev, cc, target):
167   if (cc == CC_AC5) or (cc == CC_AC6):
168     return [
169         "{dev}/{cc}/Bootloader/Bootloader.uvprojx".format(dev = dev, cc = cc),
170         "{dev}/{cc}/Bootloader/Objects/Bootloader.axf".format(dev = dev, cc = cc)
171       ] 
172   elif (cc == CC_GCC):
173     return [
174         "{dev}/{cc}/Bootloader/Bootloader.uvprojx".format(dev = dev, cc = cc),
175         "{dev}/{cc}/Bootloader/Objects/Bootloader.elf".format(dev = dev, cc = cc)
176       ] 
177   elif (cc == CC_IAR):
178     return [
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)
181       ]
182   raise "Unknown compiler!"
183   
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)
190     else:
191       return Uv4Cmd(project, target)
192   elif (cc == CC_GCC):
193     if dev in MDK_ENV['DS']:
194       return DsCmd(project, target)
195     elif dev in MDK_ENV['RTE']:
196       return RteCmd(project, target)
197     else:
198       return Uv4Cmd(project, target)
199   elif (cc == CC_IAR):
200     if dev in MDK_ENV['RTE']:
201       return RteCmd(project, target)
202     else:
203       return IarCmd(project, target)
204   raise "Unknown compiler!"
205   
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)
213           
214           rv = testProject(dev, cc, target)
215           build = [ buildStep(dev, cc, target, rv[0]) ]
216           binary = [ rv[1] ]
217           
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
222
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 } ]
226
227 def execute(steps, args):
228   for step in steps:
229     print(step['name'])
230     if step['build'] and not args.execute_only:
231       for b in step['build']:
232         b.run()
233     else:
234       print("Skipping build")
235       # step['build'].skip()
236       
237     if step['test'] and not args.build_only:
238       step['test'].run()
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")))
241     else:
242       print("Skipping test")
243       step['test'].skip()
244       
245 def printSummary(steps):
246   print("")
247   print("Test Summary")
248   print("============")
249   print()
250   print("Test run                       Total Exec  Pass  Fail  ")
251   print("-------------------------------------------------------")
252   for step in steps:
253     try:
254       print("{0:30} {1:>4}  {2:>4}  {3:>4}  {4:>4}".format(step['name'], *step['result'].getSummary()))
255     except:
256       print("{0:30} ------ NO RESULTS ------".format(step['name']))
257
258 def main(argv):
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()
267   
268   devices = set()
269   for d in args.devices:
270     if d in ADEVICES.values():
271       d = list(ADEVICES.keys())[list(ADEVICES.values()).index(d)]
272     devices.add(d)
273   
274   args.devices = list(devices)
275     
276   if args.genconfig:
277     for dev in args.devices:
278       model = FVP_MODELS[dev]
279       cmd = [ model['cmd'], '-l', '-o', model['args']['config'] ]
280       print(" ".join(cmd))
281       call(cmd)
282     return 1
283     
284   steps = []
285
286   prepare(steps, args)
287   
288   execute(steps, args)
289   
290   printSummary(steps)
291   
292 if __name__ == "__main__":
293   main(sys.argv[1:])