]> begriffs open source - cmsis/blob - CMSIS/CoreValidation/Tests/build.py
CoreValidation: Enhanced automated build with rtebuild.
[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_CM23S   : 'CM23S',
62     DEVICE_CM33S   : 'CM33S',
63     DEVICE_CA5     : 'CA5',
64     DEVICE_CA7     : 'CA7',
65     DEVICE_CA9     : 'CA9',
66     DEVICE_CA5NEON : 'CA5neon',
67     DEVICE_CA7NEON : 'CA7neon',
68     DEVICE_CA9NEON : 'CA9neon'
69   }
70
71 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 ]
72 COMPILERS = [ CC_AC5, CC_AC6, CC_GCC, CC_IAR ]
73 TARGETS = [ TARGET_FVP ]
74
75 SKIP = [ 
76     [ DEVICE_CM23,   CC_AC5, None ],
77     [ DEVICE_CM33,   CC_AC5, None ],
78     [ DEVICE_CM23NS, CC_AC5, None ],
79     [ DEVICE_CM33NS, CC_AC5, None ],
80     [ DEVICE_CM23S,  CC_AC5, None ],
81     [ DEVICE_CM33S,  CC_AC5, None ],
82   ]
83   
84 FVP_MODELS = { 
85     DEVICE_CM0      : { 'cmd': "FVP_MPS2_Cortex-M0_MDK.exe",  'args': { 'limit': "50000000", 'config': "ARMCM0_config.txt" } },
86     DEVICE_CM0PLUS  : { 'cmd': "FVP_MPS2_Cortex-M0_MDK.exe",  'args': { 'limit': "50000000", 'config': "ARMCM0plus_config.txt" } },
87     DEVICE_CM3      : { 'cmd': "FVP_MPS2_Cortex-M3_MDK.exe",  'args': { 'limit': "50000000", 'config': "ARMCM3_config.txt" } },
88     DEVICE_CM4      : { 'cmd': "FVP_MPS2_Cortex-M4_MDK.exe",  'args': { 'limit': "50000000", 'config': "ARMCM4_config.txt" } },
89     DEVICE_CM4FP    : { 'cmd': "FVP_MPS2_Cortex-M4_MDK.exe",  'args': { 'limit': "50000000", 'config': "ARMCM4FP_config.txt" } },
90     DEVICE_CM7      : { 'cmd': "FVP_MPS2_Cortex-M7_MDK.exe",  'args': { 'limit': "50000000", 'config': "ARMCM7_config.txt" } },
91     DEVICE_CM7SP    : { 'cmd': "FVP_MPS2_Cortex-M7_MDK.exe",  'args': { 'limit': "50000000", 'config': "ARMCM7SP_config.txt" } },
92     DEVICE_CM7DP    : { 'cmd': "FVP_MPS2_Cortex-M7_MDK.exe",  'args': { 'limit': "50000000", 'config': "ARMCM7DP_config.txt" } },
93     DEVICE_CM23     : { 'cmd': "FVP_MPS2_Cortex-M23_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM23_config.txt",        'target': "cpu0" } },
94     DEVICE_CM33     : { 'cmd': "FVP_MPS2_Cortex-M33_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM33_DSP_FP_config.txt", 'target': "cpu0" } },
95     DEVICE_CM23NS   : { 'cmd': "FVP_MPS2_Cortex-M23_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM23_TZ_config.txt",        'target': "cpu0" } },
96     DEVICE_CM33NS   : { 'cmd': "FVP_MPS2_Cortex-M33_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM33_DSP_FP_TZ_config.txt", 'target': "cpu0" } },
97     DEVICE_CM23S    : { 'cmd': "FVP_MPS2_Cortex-M23_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM23_TZ_config.txt",        'target': "cpu0" } },
98     DEVICE_CM33S    : { 'cmd': "FVP_MPS2_Cortex-M33_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM33_DSP_FP_TZ_config.txt", 'target': "cpu0" } },
99     DEVICE_CA5      : { 'cmd': "fvp_ve_cortex-a5x1.exe",      'args': { 'limit': "70000000", 'config': "ARMCA5_config.txt" } },
100     DEVICE_CA7      : { 'cmd': "fvp_ve_cortex-a7x1.exe",      'args': { 'limit': "170000000", 'config': "ARMCA7_config.txt" } },
101     DEVICE_CA9      : { 'cmd': "fvp_ve_cortex-a9x1.exe",      'args': { 'limit': "70000000", 'config': "ARMCA9_config.txt" } },
102     DEVICE_CA5NEON  : { 'cmd': "fvp_ve_cortex-a5x1.exe",      'args': { 'limit': "70000000", 'config': "ARMCA5neon_config.txt" } },
103     DEVICE_CA7NEON  : { 'cmd': "fvp_ve_cortex-a7x1.exe",      'args': { 'limit': "170000000", 'config': "ARMCA7neon_config.txt" } },
104     DEVICE_CA9NEON  : { 'cmd': "fvp_ve_cortex-a9x1.exe",      'args': { 'limit': "70000000", 'config': "ARMCA9neon_config.txt" } }
105   }
106
107 def isSkipped(dev, cc, target):
108   for skip in SKIP:
109     skipDev = (skip[0] == None or skip[0] == dev)
110     skipCc = (skip[1] == None or skip[1] == cc)
111     skipTarget = (skip[2] == None or skip[2] == target)
112     if skipDev and skipCc and skipTarget:
113       return True
114   return False
115   
116 def testProject(dev, cc, target):
117   if (cc == CC_AC5) or (cc == CC_AC6):
118     if dev in MDK_ENV['DS']:
119       return [
120           "{dev}/{cc}/.project".format(dev = dev, cc = cc),
121           "{dev}/{cc}/Debug/CMSIS_CV_{adev}_{cc}.axf".format(dev = dev, adev=ADEVICES[dev], cc = cc)
122         ]
123     elif dev in MDK_ENV['RTE']:
124       return [
125           "{dev}/{cc}/default.rtebuild".format(dev = dev, cc = cc, target=target),
126           "{dev}/{cc}/build/{target}.elf".format(dev = dev, cc = cc, target=target)
127         ]
128     else:
129       return [
130           "{dev}/{cc}/CMSIS_CV.uvprojx".format(dev = dev, cc = cc),
131           "{dev}/{cc}/Objects/CMSIS_CV.axf".format(dev = dev, cc = cc)
132         ]
133   elif (cc == CC_GCC):
134     if dev in MDK_ENV['DS']:
135       return [
136           "{dev}/{cc}/.project".format(dev = dev, cc = cc),
137           "{dev}/{cc}/Debug/CMSIS_CV_{adev}_{cc}.elf".format(dev = dev, adev=ADEVICES[dev], cc = cc)
138         ]
139     elif dev in MDK_ENV['RTE']:
140       return [
141           "{dev}/{cc}/default.rtebuild".format(dev = dev, cc = cc, target=target),
142           "{dev}/{cc}/build/{target}.elf".format(dev = dev, cc = cc, target=target)
143         ]
144     else:
145       return [
146           "{dev}/{cc}/CMSIS_CV.uvprojx".format(dev = dev, cc = cc),
147           "{dev}/{cc}/Objects/CMSIS_CV.elf".format(dev = dev, cc = cc)
148         ]
149   elif (cc == CC_IAR):
150     return [
151         "{dev}/{cc}/CMSIS_CV.ewp".format(dev = dev, cc = cc),
152         "{dev}/{cc}/{target}/Exe/CMSIS_CV.out".format(dev = dev, cc = cc, target = target)
153       ]
154   raise "Unknown compiler!"
155
156 def bootloaderProject(dev, cc, target):
157   if (cc == CC_AC5) or (cc == CC_AC6):
158     return [
159         "{dev}/{cc}/Bootloader/Bootloader.uvprojx".format(dev = dev, cc = cc),
160         "{dev}/{cc}/Bootloader/Objects/Bootloader.axf".format(dev = dev, cc = cc)
161       ] 
162   elif (cc == CC_GCC):
163     return [
164         "{dev}/{cc}/Bootloader/Bootloader.uvprojx".format(dev = dev, cc = cc),
165         "{dev}/{cc}/Bootloader/Objects/Bootloader.elf".format(dev = dev, cc = cc)
166       ] 
167   elif (cc == CC_IAR):
168     return [
169         "{dev}/{cc}/Bootloader/Bootloader.ewp".format(dev = dev, cc = cc),
170         "{dev}/{cc}/Bootloader/{target}/Exe/Bootloader.out".format(dev = dev, cc = cc, target = target)
171       ]
172   raise "Unknown compiler!"
173   
174 def buildStep(dev, cc, target, project):
175   if (cc == CC_AC5) or (cc == CC_AC6):
176     if dev in MDK_ENV['DS']:
177       return DsCmd(project, "CMSIS_CV_{adev}_{cc}".format(adev=ADEVICES[dev], cc = cc))
178     elif dev in MDK_ENV['RTE']:
179       return RteCmd(project, target)
180     else:
181       return Uv4Cmd(project, target)
182   elif (cc == CC_GCC):
183     if dev in MDK_ENV['DS']:
184       return DsCmd(project, target)
185     elif dev in MDK_ENV['RTE']:
186       return RteCmd(project, target)
187     else:
188       return Uv4Cmd(project, target)
189   elif (cc == CC_IAR):
190     return IarCmd(project, target)
191   raise "Unknown compiler!"
192   
193 def prepare(steps, args):
194   for dev in args.devices:
195     for cc in args.compilers:
196       for target in args.targets:
197         if not isSkipped(dev, cc, target):
198           config = "{dev} ({cc}, {target})".format(dev = dev, cc = cc, target = target)
199           prefix = "{dev}_{cc}_{target}".format(dev = dev, cc = cc, target = target)
200           
201           rv = testProject(dev, cc, target)
202           build = [ buildStep(dev, cc, target, rv[0]) ]
203           binary = [ rv[1] ]
204           
205           bl = bootloaderProject(dev, cc, target)
206           if os.path.isfile(bl[0]):
207             build = [ buildStep(dev, cc, target, bl[0]) ] + build
208             binary = [ bl[1] ] + binary
209
210           if target == TARGET_FVP:
211             test = FvpCmd(FVP_MODELS[dev]['cmd'], binary, **FVP_MODELS[dev]['args'])
212           steps += [ { 'name': config, 'prefix': prefix, 'build': build, 'test': test } ]
213
214 def execute(steps, args):
215   for step in steps:
216     print(step['name'])
217     if step['build'] and not args.execute_only:
218       for b in step['build']:
219         b.run()
220     else:
221       print("Skipping build")
222       # step['build'].skip()
223       
224     if step['test'] and not args.build_only:
225       step['test'].run()
226       step['result'] = TestResult(step['test'].getOutput())
227       step['result'].saveXml("result_{0}_{1}.xml".format(step['prefix'], datetime.now().strftime("%Y%m%d%H%M%S")))
228     else:
229       print("Skipping test")
230       step['test'].skip()
231       
232 def printSummary(steps):
233   print("")
234   print("Test Summary")
235   print("============")
236   print()
237   print("Test run                       Total Exec  Pass  Fail  ")
238   print("-------------------------------------------------------")
239   for step in steps:
240     try:
241       print("{0:30} {1:>4}  {2:>4}  {3:>4}  {4:>4}".format(step['name'], *step['result'].getSummary()))
242     except:
243       print("{0:30} ------ NO RESULTS ------".format(step['name']))
244
245 def main(argv):
246   parser = ArgumentParser()
247   parser.add_argument('--genconfig', action='store_true')
248   parser.add_argument('-b', '--build-only', action='store_true')
249   parser.add_argument('-e', '--execute-only', action='store_true')
250   parser.add_argument('-d', '--devices', nargs='*', choices=DEVICES, default=DEVICES, help = 'Devices to be considered.')
251   parser.add_argument('-c', '--compilers', nargs='*', choices=COMPILERS, default=COMPILERS, help = 'Compilers to be considered.')
252   parser.add_argument('-t', '--targets', nargs='*', choices=TARGETS, default=TARGETS, help = 'Targets to be considered.')
253   args = parser.parse_args()
254     
255   if args.genconfig:
256     for dev in args.devices:
257       model = FVP_MODELS[dev]
258       cmd = [ model['cmd'], '-l', '-o', model['args']['config'] ]
259       print(" ".join(cmd))
260       call(cmd)
261     return 1
262     
263   steps = []
264
265   prepare(steps, args)
266   
267   execute(steps, args)
268   
269   printSummary(steps)
270   
271 if __name__ == "__main__":
272   main(sys.argv[1:])