winIDEA SDK
profiler_controller.py
1# This script is licensed under BSD License, see file LICENSE.txt.
2#
3# (c) TASKING Germany GmbH, 2023
4
5"""
6This script demonstrates usage of profiler with isystem.connect API.
7"""
8
9from __future__ import print_function
10
11import os
12import time
13import isystem.connect as ic
14
15
16winidea_id = ''
17
18
19print('isystem.connect version: ' + ic.getModuleVersion())
20
21cmgr = ic.ConnectionMgr()
22cmgr.connect(ic.CConnectionConfig().instanceId(winidea_id))
23
24debugCtrl = ic.CDebugFacade(cmgr)
25ideCtrl = ic.CIDEController(cmgr)
26
27debugCtrl.download()
28debugCtrl.runUntilFunction("main")
29debugCtrl.waitUntilStopped()
30
31# create profiler document
32profiler = ic.CProfilerController2(cmgr, 'sample_profiler.trd', 'w')
33
34# Let's create a new trigger. First we have to make sure, that
35# the trigger does not already exist.
36profiler.removeTrigger('testTrigger')
37triggerIdx = profiler.createTrigger('testTrigger')
38
39# make the created trigger the active one
40profiler.select(triggerIdx)
41
42# profile code and data
43profiler.setProfilingSections(triggerIdx, True, True, False, False);
44
45# decrease the default buffer size. 32 Mb is enough for demo.
46profiler.setTriggerOption(triggerIdx, 'HW.Recorder.BufferSize', '32 MB')
47
48# start profiling when execution of the function "target_init" starts
49profiler.setFunctionTrigger(triggerIdx, "target_init")
50
51
52profiler.addFunction(triggerIdx, "get_random")
53profiler.addFunction(triggerIdx, "fibonacci")
54
55profiler.addVariable(triggerIdx, "main_loop_counter", ic.CProfilerController2.EDATRegular)
56profiler.addStateVariable(triggerIdx,
57 "g_enumA",
58 ic.CProfilerController2.EStateDefEnum,
59 "enumA")
60
61print('Target is running, profiler is recording data...')
62profiler.waitUntilLoaded() # make sure that winIDEA has already loaded the document if
63 # already existed
64profiler.start()
65debugCtrl.run()
66time.sleep(3)
67debugCtrl.stop()
68
69print('Target stopped, loading profiler data...')
70profiler.waitUntilLoaded()
71
72exportCfg = ic.CProfilerExportConfig()
73exportCfg.setFileName('profilerSample-1.xml') \
74 .setAreaScope(ic.CProfilerExportConfig.EAreaAll) \
75 .setAreaExportSections(True, True, True) \
76 .setSaveTimeline(True)
77
78print('-------------------------\nWriting export file with settings:\n')
79print(exportCfg.toString())
80print('-------------------------\n\n')
81profiler.exportData(exportCfg)
82
83exportCfg.setFileName('profilerSample-bin.xml')
84formatter = ic.CProfilerXMLExportFormat()
85formatter.setTimelineBinary(True)
86formatter.setUseIndent(False)
87exportCfg.setFormatter(formatter)
88print('Writing XML export file with binary timeline ...')
89profiler.exportData(exportCfg)
90
91debugCtrl.reset()
92debugCtrl.runUntilFunction("main")
93debugCtrl.waitUntilStopped()
94# we can also remove functions and variables from trigger configuration
95print('One function and variable will be removed from trigger configuration.')
96profiler.removeFunction(triggerIdx, "get_random")
97profiler.removeVariable(triggerIdx, "fibonacci")
98
99
100print('New recording started: Target is running, profiler is recording data ...')
101profiler.start()
102debugCtrl.run()
103time.sleep(3)
104debugCtrl.stop()
105
106print('Target stopped, loading profiler data...')
107profiler.waitUntilLoaded()
108
109exportCfg = ic.CProfilerExportConfig()
110exportFile = 'profilerSample-2.csv'
111exportCfg.setFileName(exportFile) \
112 .setSaveTimeline(True) \
113 .setAreaScope(ic.CProfilerExportConfig.EAreaFilter) \
114 .setFunctionsFilter('*') \
115 .setVariablesFilter('*') # use wildcard to export all data items
116
117
118exportCfg.setFileName('profilerSample.btf')
119formatter = ic.CProfilerBTFExportFormat()
120exportCfg.setFormatter(formatter)
121
122print('Writing BTF export file with binary timeline ...')
123profiler.exportData(exportCfg)
124
125# Let's try also some other profiler methods.
126print('Demonstration of some other profiler methods:')
127print(' Number of triggers: ', profiler.getNumberOfTriggers())
128
129# Trigger options have their dedicated methods getTriggerOption()
130# and setTriggerOption()
131print(" Profiler recording start: ", profiler.getTriggerOption(triggerIdx, 'HW.Recorder.Start'))
132
133# Print profiler results
134print('\n\n\nProfiler measurements')
135
136profilerExportFile = 'profilerSample-3.xml'
137profilerData = ic.CProfilerData2.createInstance(profiler,
138 profilerExportFile,
139 True, # export also timeline
140 '*', '*')
141
142# always check for parser warnings
143warnings = profilerData.getParserWarnings()
144if warnings:
145 print('WARNING(S): ', warnings)
146
147
148def printAreas(profilerData, areaType):
149
150 areaIterator = profilerData.getAreaIterator(areaType)
151
152 while areaIterator.hasNext():
153 area = areaIterator.next()
154 print('Area:')
155 print(' Id: ', hex(area.getAreaId()))
156 print(' Handle: ', area.getHandle())
157 print(' Path: ', area.getPath())
158 print(' Name: ', area.getAreaName())
159 print(' Value: ', area.getValue())
160 print(' Value Unit:', area.getValueUnit())
161 print(' Value Type:', area.getValueType())
162 print(' Parent h.: ', area.getParentHandle())
163 print(' Parent a.: ', area.getParentAreaName())
164
165
166print('\nFunction areas: ')
167printAreas(profilerData, ic.CProfilerArea2.EFunctions)
168
169print('\nVariable areas: ')
170printAreas(profilerData, ic.CProfilerArea2.EVariables)
171
172print('\nTimeline: ')
173timeIter = profilerData.getTimelineIterator()
174counter = 0
175while timeIter.hasNext():
176 timeEvent = timeIter.next()
177 print(' time: ', timeEvent.getTime())
178 if counter > 100:
179 break # limit the output
180 counter += 1
181
182
183profilerData.closeParser() # releases memory and closes XML file
184
185print("\n\n\nRun script 'profilerData.py' to print ALL the recorded results.")