]> begriffs open source - cmsis/blob - CMSIS/CoreValidation/Tests/build.py
CoreValidation: Added test functions for MSPLIM and PSPLIM.
[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-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" } }
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   rtebuild = "{dev}/{cc}/default.rtebuild".format(dev = dev, cc = cc, target=target)
122   if os.path.exists(rtebuild):
123     return [
124         rtebuild,
125         "{dev}/{cc}/build/{target}/{target}.elf".format(dev = dev, cc = cc, target=target)
126       ]
127   elif (cc == CC_AC5) or (cc == CC_AC6):
128     return [
129         "{dev}/{cc}/CMSIS_CV.uvprojx".format(dev = dev, cc = cc),
130         "{dev}/{cc}/Objects/CMSIS_CV.axf".format(dev = dev, cc = cc)
131       ]
132   elif (cc == CC_GCC):
133     return [
134         "{dev}/{cc}/CMSIS_CV.uvprojx".format(dev = dev, cc = cc),
135         "{dev}/{cc}/Objects/CMSIS_CV.elf".format(dev = dev, cc = cc)
136       ]
137   elif (cc == CC_IAR):
138     return [
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)
141       ]
142   raise "Unknown compiler!"
143
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):
147     return [
148         rtebuild,
149         "{dev}/{cc}/Bootloader/build/{target}/{target}.elf".format(dev = dev, cc = cc, target=target)
150       ]
151   elif (cc == CC_AC5) or (cc == CC_AC6):
152     return [
153         "{dev}/{cc}/Bootloader/Bootloader.uvprojx".format(dev = dev, cc = cc),
154         "{dev}/{cc}/Bootloader/Objects/Bootloader.axf".format(dev = dev, cc = cc)
155       ] 
156   elif (cc == CC_GCC):
157     return [
158         "{dev}/{cc}/Bootloader/Bootloader.uvprojx".format(dev = dev, cc = cc),
159         "{dev}/{cc}/Bootloader/Objects/Bootloader.elf".format(dev = dev, cc = cc)
160       ] 
161   elif (cc == CC_IAR):
162     return [
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)
165       ]
166   raise "Unknown compiler!"
167   
168 def buildStep(dev, cc, target, project):
169   STEP_TYPES = {
170     ".uvprojx"  : Uv4Cmd,
171     ".ewp"      : IarCmd,
172     ".rtebuild" : RteCmd
173   }
174   
175   projectfile, projectext = os.path.splitext(project)
176   
177   if not projectext in STEP_TYPES:
178     raise "Unknown project type '"+projectext+"'!"
179     
180   return STEP_TYPES[projectext](project, target)
181   
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)
189           
190           rv = testProject(dev, cc, target)
191           build = [ buildStep(dev, cc, target, rv[0]) ]
192           binary = [ rv[1] ]
193           
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
198
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 } ]
202
203 def execute(steps, args):
204   for step in steps:
205     print(step['name'])
206     if step['build'] and not args.execute_only:
207       for b in step['build']:
208         b.run()
209     else:
210       print("Skipping build")
211       # step['build'].skip()
212       
213     if step['test'] and not args.build_only:
214       step['test'].run()
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")))
217     else:
218       print("Skipping test")
219       step['test'].skip()
220       
221 def printSummary(steps):
222   print("")
223   print("Test Summary")
224   print("============")
225   print()
226   print("Test run                       Total Exec  Pass  Fail  ")
227   print("-------------------------------------------------------")
228   for step in steps:
229     try:
230       print("{0:30} {1:>4}  {2:>4}  {3:>4}  {4:>4}".format(step['name'], *step['result'].getSummary()))
231     except:
232       print("{0:30} ------ NO RESULTS ------".format(step['name']))
233
234 def main(argv):
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()
243   
244   devices = set()
245   for d in args.devices:
246     if d in ADEVICES.values():
247       d = list(ADEVICES.keys())[list(ADEVICES.values()).index(d)]
248     devices.add(d)
249   
250   args.devices = list(devices)
251     
252   if args.genconfig:
253     for dev in args.devices:
254       model = FVP_MODELS[dev]
255       cmd = [ model['cmd'], '-l', '-o', model['args']['config'] ]
256       print(" ".join(cmd))
257       call(cmd)
258     return 1
259     
260   steps = []
261
262   prepare(steps, args)
263   
264   execute(steps, args)
265   
266   printSummary(steps)
267   
268 if __name__ == "__main__":
269   main(sys.argv[1:])