]> begriffs open source - cmsis/blob - CMSIS/CoreValidation/Tests/build.py
CoreValidation: Test projects for Cortex-M23/-M33 without extensions.
[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     return [
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)
157       ]
158   raise "Unknown compiler!"
159
160 def bootloaderProject(dev, cc, target):
161   if (cc == CC_AC5) or (cc == CC_AC6):
162     return [
163         "{dev}/{cc}/Bootloader/Bootloader.uvprojx".format(dev = dev, cc = cc),
164         "{dev}/{cc}/Bootloader/Objects/Bootloader.axf".format(dev = dev, cc = cc)
165       ] 
166   elif (cc == CC_GCC):
167     return [
168         "{dev}/{cc}/Bootloader/Bootloader.uvprojx".format(dev = dev, cc = cc),
169         "{dev}/{cc}/Bootloader/Objects/Bootloader.elf".format(dev = dev, cc = cc)
170       ] 
171   elif (cc == CC_IAR):
172     return [
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)
175       ]
176   raise "Unknown compiler!"
177   
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)
184     else:
185       return Uv4Cmd(project, target)
186   elif (cc == CC_GCC):
187     if dev in MDK_ENV['DS']:
188       return DsCmd(project, target)
189     elif dev in MDK_ENV['RTE']:
190       return RteCmd(project, target)
191     else:
192       return Uv4Cmd(project, target)
193   elif (cc == CC_IAR):
194     return IarCmd(project, target)
195   raise "Unknown compiler!"
196   
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)
204           
205           rv = testProject(dev, cc, target)
206           build = [ buildStep(dev, cc, target, rv[0]) ]
207           binary = [ rv[1] ]
208           
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
213
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 } ]
217
218 def execute(steps, args):
219   for step in steps:
220     print(step['name'])
221     if step['build'] and not args.execute_only:
222       for b in step['build']:
223         b.run()
224     else:
225       print("Skipping build")
226       # step['build'].skip()
227       
228     if step['test'] and not args.build_only:
229       step['test'].run()
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")))
232     else:
233       print("Skipping test")
234       step['test'].skip()
235       
236 def printSummary(steps):
237   print("")
238   print("Test Summary")
239   print("============")
240   print()
241   print("Test run                       Total Exec  Pass  Fail  ")
242   print("-------------------------------------------------------")
243   for step in steps:
244     try:
245       print("{0:30} {1:>4}  {2:>4}  {3:>4}  {4:>4}".format(step['name'], *step['result'].getSummary()))
246     except:
247       print("{0:30} ------ NO RESULTS ------".format(step['name']))
248
249 def main(argv):
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()
258   
259   devices = set()
260   for d in args.devices:
261     if d in ADEVICES.values():
262       d = list(ADEVICES.keys())[list(ADEVICES.values()).index(d)]
263     devices.add(d)
264   
265   args.devices = list(devices)
266     
267   if args.genconfig:
268     for dev in args.devices:
269       model = FVP_MODELS[dev]
270       cmd = [ model['cmd'], '-l', '-o', model['args']['config'] ]
271       print(" ".join(cmd))
272       call(cmd)
273     return 1
274     
275   steps = []
276
277   prepare(steps, args)
278   
279   execute(steps, args)
280   
281   printSummary(steps)
282   
283 if __name__ == "__main__":
284   main(sys.argv[1:])