]> begriffs open source - cmsis/blob - CMSIS/CoreValidation/Tests/build.py
CoreValidation: Added validation projects for ARMv8-M.
[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 uv4cmd import Uv4Cmd 
12 from fvpcmd import FvpCmd 
13 from iarcmd import IarCmd 
14 from testresult import TestResult
15
16 DEVICE_CM0     = 'Cortex-M0'
17 DEVICE_CM0PLUS = 'Cortex-M0plus'
18 DEVICE_CM3     = 'Cortex-M3'
19 DEVICE_CM4     = 'Cortex-M4'
20 DEVICE_CM4FP   = 'Cortex-M4FP'
21 DEVICE_CM7     = 'Cortex-M7'
22 DEVICE_CM7SP   = 'Cortex-M7SP'
23 DEVICE_CM7DP   = 'Cortex-M7DP'
24 DEVICE_CM23    = 'Cortex-M23'
25 DEVICE_CM33    = 'Cortex-M33'
26 DEVICE_CM23NS  = 'Cortex-M23NS'
27 DEVICE_CM33NS  = 'Cortex-M33NS'
28 DEVICE_CM23S   = 'Cortex-M23S'
29 DEVICE_CM33S   = 'Cortex-M33S'
30 DEVICE_CA5     = 'Cortex-A5'
31 DEVICE_CA7     = 'Cortex-A7'
32 DEVICE_CA9     = 'Cortex-A9'
33 DEVICE_CA5NEON = 'Cortex-A5neon'
34 DEVICE_CA7NEON = 'Cortex-A7neon'
35 DEVICE_CA9NEON = 'Cortex-A9neon'
36
37 CC_AC6 = 'AC6'
38 CC_AC5 = 'AC5'
39 CC_GCC = 'GCC'
40 CC_IAR = 'IAR'
41
42 MDK_ENV = {
43   'uVision' : [ DEVICE_CM0, DEVICE_CM0PLUS, DEVICE_CM3, DEVICE_CM4, DEVICE_CM4FP, DEVICE_CM7, DEVICE_CM7SP, DEVICE_CM7DP, DEVICE_CM23S, DEVICE_CM33S ],
44   'DS' : [ DEVICE_CA5, DEVICE_CA7, DEVICE_CA9, DEVICE_CA5NEON, DEVICE_CA7NEON, DEVICE_CA9NEON ]
45 }
46
47 TARGET_FVP = 'FVP'
48
49 ADEVICES = {
50     DEVICE_CM0     : 'CM0',
51     DEVICE_CM0PLUS : 'CM0plus',
52     DEVICE_CM3     : 'CM3',
53     DEVICE_CM4     : 'CM4',
54     DEVICE_CM4FP   : 'CM4FP',
55     DEVICE_CM7     : 'CM7',
56     DEVICE_CM7SP   : 'CM7SP',
57     DEVICE_CM7DP   : 'CM7DP',
58     DEVICE_CM23S   : 'CM23S',
59     DEVICE_CM33S   : 'CM33S',
60     DEVICE_CA5     : 'CA5',
61     DEVICE_CA7     : 'CA7',
62     DEVICE_CA9     : 'CA9',
63     DEVICE_CA5NEON : 'CA5neon',
64     DEVICE_CA7NEON : 'CA7neon',
65     DEVICE_CA9NEON : 'CA9neon'
66   }
67
68 DEVICES = [ DEVICE_CM0, DEVICE_CM0PLUS, DEVICE_CM3, DEVICE_CM4, DEVICE_CM4FP, DEVICE_CM7, DEVICE_CM7SP, DEVICE_CM7DP, DEVICE_CM23S, DEVICE_CM33S, DEVICE_CA5, DEVICE_CA7, DEVICE_CA9, DEVICE_CA5NEON, DEVICE_CA7NEON, DEVICE_CA9NEON ]
69 COMPILERS = [ CC_AC5, CC_AC6, CC_GCC, CC_IAR ]
70 TARGETS = [ TARGET_FVP ]
71
72 SKIP = [ 
73     [ DEVICE_CM23,   CC_AC5, None ],
74     [ DEVICE_CM33,   CC_AC5, None ],
75     [ DEVICE_CM23NS, CC_AC5, None ],
76     [ DEVICE_CM33NS, CC_AC5, None ],
77     [ DEVICE_CM23S,  CC_AC5, None ],
78     [ DEVICE_CM33S,  CC_AC5, None ],
79   ]
80   
81 FVP_MODELS = { 
82     DEVICE_CM0      : { 'cmd': "FVP_MPS2_Cortex-M0_MDK.exe",  'args': { 'limit': "50000000", 'config': "ARMCM0_config.txt" } },
83     DEVICE_CM0PLUS  : { 'cmd': "FVP_MPS2_Cortex-M0_MDK.exe",  'args': { 'limit': "50000000", 'config': "ARMCM0plus_config.txt" } },
84     DEVICE_CM3      : { 'cmd': "FVP_MPS2_Cortex-M3_MDK.exe",  'args': { 'limit': "50000000", 'config': "ARMCM3_config.txt" } },
85     DEVICE_CM4      : { 'cmd': "FVP_MPS2_Cortex-M4_MDK.exe",  'args': { 'limit': "50000000", 'config': "ARMCM4_config.txt" } },
86     DEVICE_CM4FP    : { 'cmd': "FVP_MPS2_Cortex-M4_MDK.exe",  'args': { 'limit': "50000000", 'config': "ARMCM4FP_config.txt" } },
87     DEVICE_CM7      : { 'cmd': "FVP_MPS2_Cortex-M7_MDK.exe",  'args': { 'limit': "50000000", 'config': "ARMCM7_config.txt" } },
88     DEVICE_CM7SP    : { 'cmd': "FVP_MPS2_Cortex-M7_MDK.exe",  'args': { 'limit': "50000000", 'config': "ARMCM7SP_config.txt" } },
89     DEVICE_CM7DP    : { 'cmd': "FVP_MPS2_Cortex-M7_MDK.exe",  'args': { 'limit': "50000000", 'config': "ARMCM7DP_config.txt" } },
90     DEVICE_CM23     : { 'cmd': "FVP_MPS2_Cortex-M23_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM23_config.txt",        'target': "cpu0" } },
91     DEVICE_CM33     : { 'cmd': "FVP_MPS2_Cortex-M33_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM33_DSP_FP_config.txt", 'target': "cpu0" } },
92     DEVICE_CM23NS   : { 'cmd': "FVP_MPS2_Cortex-M23_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM23_TZ_config.txt",        'target': "cpu0" } },
93     DEVICE_CM33NS   : { 'cmd': "FVP_MPS2_Cortex-M33_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM33_DSP_FP_TZ_config.txt", 'target': "cpu0" } },
94     DEVICE_CM23S    : { 'cmd': "FVP_MPS2_Cortex-M23_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM23_TZ_config.txt",        'target': "cpu0" } },
95     DEVICE_CM33S    : { 'cmd': "FVP_MPS2_Cortex-M33_MDK.exe", 'args': { 'limit': "50000000", 'config': "ARMCM33_DSP_FP_TZ_config.txt", 'target': "cpu0" } },
96     DEVICE_CA5      : { 'cmd': "fvp_ve_cortex-a5x1.exe",      'args': { 'limit': "70000000", 'config': "ARMCA5_config.txt" } },
97     DEVICE_CA7      : { 'cmd': "fvp_ve_cortex-a7x1.exe",      'args': { 'limit': "170000000", 'config': "ARMCA7_config.txt" } },
98     DEVICE_CA9      : { 'cmd': "fvp_ve_cortex-a9x1.exe",      'args': { 'limit': "70000000", 'config': "ARMCA9_config.txt" } },
99     DEVICE_CA5NEON  : { 'cmd': "fvp_ve_cortex-a5x1.exe",      'args': { 'limit': "70000000", 'config': "ARMCA5neon_config.txt" } },
100     DEVICE_CA7NEON  : { 'cmd': "fvp_ve_cortex-a7x1.exe",      'args': { 'limit': "170000000", 'config': "ARMCA7neon_config.txt" } },
101     DEVICE_CA9NEON  : { 'cmd': "fvp_ve_cortex-a9x1.exe",      'args': { 'limit': "70000000", 'config': "ARMCA9neon_config.txt" } }
102   }
103
104 def isSkipped(dev, cc, target):
105   for skip in SKIP:
106     skipDev = (skip[0] == None or skip[0] == dev)
107     skipCc = (skip[1] == None or skip[1] == cc)
108     skipTarget = (skip[2] == None or skip[2] == target)
109     if skipDev and skipCc and skipTarget:
110       return True
111   return False
112   
113 def testProject(dev, cc, target):
114   if (cc == CC_AC5) or (cc == CC_AC6):
115     if dev in MDK_ENV['DS']:
116       return [
117           "{dev}/{cc}/.project".format(dev = dev, cc = cc),
118           "{dev}/{cc}/Debug/CMSIS_CV_{adev}_{cc}.axf".format(dev = dev, adev=ADEVICES[dev], cc = cc)
119         ]
120     else:
121       return [
122           "{dev}/{cc}/CMSIS_CV.uvprojx".format(dev = dev, cc = cc),
123           "{dev}/{cc}/Objects/CMSIS_CV.axf".format(dev = dev, cc = cc)
124         ]
125   elif (cc == CC_GCC):
126     if dev in MDK_ENV['DS']:
127       return [
128           "{dev}/{cc}/.project".format(dev = dev, cc = cc),
129           "{dev}/{cc}/Debug/CMSIS_CV_{adev}_{cc}.elf".format(dev = dev, adev=ADEVICES[dev], cc = cc)
130         ]
131     else:
132       return [
133           "{dev}/{cc}/CMSIS_CV.uvprojx".format(dev = dev, cc = cc),
134           "{dev}/{cc}/Objects/CMSIS_CV.elf".format(dev = dev, cc = cc)
135         ]
136   elif (cc == CC_IAR):
137     return [
138         "{dev}/{cc}/CMSIS_CV.ewp".format(dev = dev, cc = cc),
139         "{dev}/{cc}/{target}/Exe/CMSIS_CV.out".format(dev = dev, cc = cc, target = target)
140       ]
141   raise "Unknown compiler!"
142
143 def bootloaderProject(dev, cc, target):
144   if (cc == CC_AC5) or (cc == CC_AC6):
145     return [
146         "{dev}/{cc}/Bootloader/Bootloader.uvprojx".format(dev = dev, cc = cc),
147         "{dev}/{cc}/Bootloader/Objects/Bootloader.axf".format(dev = dev, cc = cc)
148       ] 
149   elif (cc == CC_GCC):
150     return [
151         "{dev}/{cc}/Bootloader/Bootloader.uvprojx".format(dev = dev, cc = cc),
152         "{dev}/{cc}/Bootloader/Objects/Bootloader.elf".format(dev = dev, cc = cc)
153       ] 
154   elif (cc == CC_IAR):
155     return [
156         "{dev}/{cc}/Bootloader/Bootloader.ewp".format(dev = dev, cc = cc),
157         "{dev}/{cc}/Bootloader/{target}/Exe/Bootloader.out".format(dev = dev, cc = cc, target = target)
158       ]
159   raise "Unknown compiler!"
160   
161 def buildStep(dev, cc, target, project):
162   if (cc == CC_AC5) or (cc == CC_AC6):
163     return Uv4Cmd(project, target)
164   elif (cc == CC_GCC):
165     return Uv4Cmd(project, target)
166   elif (cc == CC_IAR):
167     return IarCmd(project, target)
168   raise "Unknown compiler!"
169   
170 def prepare(steps, args):
171   for dev in args.devices:
172     for cc in args.compilers:
173       for target in args.targets:
174         if not isSkipped(dev, cc, target):
175           config = "{dev} ({cc}, {target})".format(dev = dev, cc = cc, target = target)
176           prefix = "{dev}_{cc}_{target}".format(dev = dev, cc = cc, target = target)
177           
178           rv = testProject(dev, cc, target)
179           build = [ buildStep(dev, cc, target, rv[0]) ]
180           binary = [ rv[1] ]
181           
182           bl = bootloaderProject(dev, cc, target)
183           if os.path.isfile(bl[0]):
184             build = [ buildStep(dev, cc, target, bl[0]) ] + build
185             binary = [ bl[1] ] + binary
186
187           if target == TARGET_FVP:
188             test = FvpCmd(FVP_MODELS[dev]['cmd'], binary, **FVP_MODELS[dev]['args'])
189           steps += [ { 'name': config, 'prefix': prefix, 'build': build, 'test': test } ]
190
191 def execute(steps, args):
192   for step in steps:
193     print(step['name'])
194     if step['build'] and not args.execute_only:
195       for b in step['build']:
196         b.run()
197     else:
198       print("Skipping build")
199       # step['build'].skip()
200       
201     if step['test'] and not args.build_only:
202       step['test'].run()
203       step['result'] = TestResult(step['test'].getOutput())
204       step['result'].saveXml("result_{0}_{1}.xml".format(step['prefix'], datetime.now().strftime("%Y%m%d%H%M%S")))
205     else:
206       print("Skipping test")
207       step['test'].skip()
208       
209 def printSummary(steps):
210   print("")
211   print("Test Summary")
212   print("============")
213   print()
214   print("Test run                       Total Exec  Pass  Fail  ")
215   print("-------------------------------------------------------")
216   for step in steps:
217     try:
218       print("{0:30} {1:>4}  {2:>4}  {3:>4}  {4:>4}".format(step['name'], *step['result'].getSummary()))
219     except:
220       print("{0:30} ------ NO RESULTS ------".format(step['name']))
221
222 def main(argv):
223   parser = ArgumentParser()
224   parser.add_argument('--genconfig', action='store_true')
225   parser.add_argument('-b', '--build-only', action='store_true')
226   parser.add_argument('-e', '--execute-only', action='store_true')
227   parser.add_argument('-d', '--devices', nargs='*', choices=DEVICES, default=DEVICES, help = 'Devices to be considered.')
228   parser.add_argument('-c', '--compilers', nargs='*', choices=COMPILERS, default=COMPILERS, help = 'Compilers to be considered.')
229   parser.add_argument('-t', '--targets', nargs='*', choices=TARGETS, default=TARGETS, help = 'Targets to be considered.')
230   args = parser.parse_args()
231     
232   if args.genconfig:
233     for dev in args.devices:
234       model = FVP_MODELS[dev]
235       cmd = [ model['cmd'], '-l', '-o', model['args']['config'] ]
236       print(" ".join(cmd))
237       call(cmd)
238     return 1
239     
240   steps = []
241
242   prepare(steps, args)
243   
244   execute(steps, args)
245   
246   printSummary(steps)
247   
248 if __name__ == "__main__":
249   main(sys.argv[1:])