6This script demonstrates recording of watch expressions and variables
7using slower but more flexible evaluator and fast batch access.
8The recorded data is then written to CSV file. If the 'openpyxl'
9module is installed, the data is also written to XLSX file.
11All the above functionality is grouped into functions, so you can
12easily take out only part of the script. This script can also be
13imported as a module to user's scripts, so it is easy to reuse
16See also dataRecorderWithDAQ.py.
21import isystem.connect
as ic
28 isPyLabInstalled =
True
29except ImportError
as ex:
30 isPyLabInstalled =
False
35 This function initializes the target. Customize it according to
39 debugCtrl = ic.CDebugFacade(cmgr)
42 debugCtrl.runUntilFunction("main")
43 debugCtrl.waitUntilStopped()
50def recordWatchExpressions(debugCtrl,
52 recordingTimeInSeconds,
58 This function evaluates watch expressions and returns list of results. The
59 amount of data that can be recorded
is limited by the amount of system
64 debugCtrl - iSYSTEM
's debugCtrl controller, which provides access to target
66 watches - list of strings with watch expressions,
for example
67 [
'main_loop_counter,h',
'g_arrayInt[0]']
69 recordingTime - how long to record the expressions,
in
70 seconds. Recording can also be terminated by
73 samplingInterval - defines how much time should
pass between samples
75 isPrintToStdOut -
if True, each row
is printed to stdout during recording
78 List of rows, where each row
is a list containing time stamp
and recorded
79 values
in the same order
as watch expressions were specified. Example
for
86 startTime = time.time()
87 endTime = startTime + recordingTimeInSeconds
90 print([
'Time'] + watches)
95 while (time.time() < endTime):
97 currentTime = time.time() - startTime
100 for expression
in watches:
102 value = debugCtrl.evaluate(ic.IConnectDebug.fRealTime, expression)
106 row.append(value.getResult())
112 recordedData.append(row)
115 nextSamplingTime = startTime + samplingInterval * sampleCounter
116 sleepTime = nextSamplingTime - time.time()
118 time.sleep(sleepTime)
123def recordWatchExpressionsToCSV(debugCtrl,
125 recordingTimeInSeconds,
131 This function evaluates watch expressions and writes them to CSV file.
132 If isRecordToMemory ==
False, the amount of data that can be recorded
is
133 limited by the free disk size.
137 debugCtrl - iSYSTEM
's debugCtrl controller, which provides access to target
139 watches - list of strings with watch expressions,
for example
140 [
'main_loop_counter,h',
'g_arrayInt[0]']
142 recordingTime - how long to record the expressions,
in
143 seconds. Recording can also be terminated by
146 samplingInterval - defines how much time should
pass between samples
148 fileName - name of the output CSV file.
150 isRecordToMemory -
if True, then data
is also stored into memory
151 array
and returned
as function
return value. Be
152 aware of memory usage
in this case. If false,
153 an empty list
is returned.
155 isPrintToStdOut -
if True, each row
is printed to stdout during recording
158 List of rows, where each row
is a list containing time stamp
and recorded
159 values
in the same order
as watch expressions were specified. Example
for
162 [0.1, 24, -525, 1.78]
165 If isRecordToMemory ==
False, an empty list
is returned.
168 startTime = time.time()
169 endTime = startTime + recordingTimeInSeconds
173 with open(fileName,
'w')
as csvFile:
178 csvWriter = csv.writer(csvFile)
180 header = [
'Time'] + watches
182 csvWriter.writerow(header)
185 while (time.time() < endTime):
187 currentTime = time.time() - startTime
190 for expression
in watches:
192 print(
'expression: ', expression)
193 value = debugCtrl.evaluate(ic.IConnectDebug.fRealTime, expression)
197 row.append(value.getResult())
199 csvWriter.writerow(row)
205 recordedData.append(row)
208 nextSamplingTime = startTime + samplingInterval * sampleCounter
209 sleepTime = nextSamplingTime - time.time()
211 time.sleep(sleepTime)
219 recordingTimeInSeconds,
220 samplingIntervalInSeconds):
222 This function runs batch access and returns recorded data
as a list of
223 SBatchAccessItemResult structures.
224 The amount of data that can be recorded
is limited by the amount of system
229 cmgr - iSYSTEM
's connection manager, which provides connection to target
230 debugCtrl - iSYSTEM's debugCtrl controller, which provides access to target
232 variables - list of strings with variables,
for example
233 [
'main_loop_counter',
'g_baseStruct.i_base']
235 recordingTime - how long to record the expressions,
in
238 samplingInterval - defines how much time should
pass between samples
241 A list of SBatchAccessItemResult structures, one structure per variable
245 numItems = len(variables)
246 numRuns = int(recordingTimeInSeconds / samplingIntervalInSeconds)
251 header = ic.SBatchAccessHeader()
252 header.m_dwFlags = (ic.SBatchAccessHeader.flRealTime |
253 ic.SBatchAccessHeader.flWantTimeStamp)
254 header.m_dwNumItems = numItems
255 header.m_dwNumRuns = numRuns
256 header.m_qwStartAtTime = 0
257 header.m_qwRunInterval = int(samplingIntervalInSeconds * 1000000)
259 ba_items = ic.VectorBatchAccessItem()
262 for var
in variables:
263 item = ic.SBatchAccessItem()
265 varInfo = dbgCtrl.getSymbolInfo(ic.IConnectDebug.fRealTime, var)
268 item.m_byFlags = ic.SBatchAccessItem.flRead
269 item.m_bySize = varInfo.getSizeMAUs()
270 item.m_byMemArea = varInfo.getMemArea()
271 item.m_aAddress = varInfo.getAddress()
272 ba_items.push_back(item)
273 itemSizes.append(varInfo.getSizeMAUs())
276 ba_results = ic.VectorBatchAccessResult(numItems * numRuns)
277 dataCtrl = ic.CDataController(cmgr)
280 dataCtrl.batchAccess(0, header, ba_items, ba_results)
282 return ba_results, itemSizes
285def bigEndian2Int(numBytes, cArray):
286 """ Converts big-endian seq. of bytes to integer. """
289 for i
in range(numBytes):
291 value |= ic.CDataController.getByte(cArray, i)
296def batchAccessResultToCSV(fileName, ba_results, itemSizes, variables):
298 Writes results of batchAccess() to CSV file. Uses big endian conversion.
301 fileName - then name of the output file
302 ba_results - results returned by function recordBatch()
303 itemSizes - results returned by function recordBatch()
306 numItems = len(itemSizes)
307 numRuns = int(ba_results.size() / numItems)
309 firstAccess = ba_results[0].m_qwTimeStamp
311 with open(fileName,
'w')
as csvFile:
313 csvWriter = csv.writer(csvFile)
316 csvWriter.writerow([
'Time'] + variables)
318 for runIdx
in range(numRuns):
320 row = [(ba_results[runIdx * numItems].m_qwTimeStamp - firstAccess)/1000000.]
322 for varIdx
in range(numItems):
323 result = ba_results[runIdx * numItems + varIdx]
325 if (result.m_byResult == ic.SBatchAccessItemResult.resOK):
326 value = bigEndian2Int(itemSizes[varIdx], result.m_abyData)
329 elif (result.m_byResult == ic.SBatchAccessItemResult.resAccess):
330 row.append(
'Can not access. Check access flags in header!')
331 elif (result.m_byResult == ic.SBatchAccessItemResult.resTimeout):
332 row.append(
'Timeout! Probably the sampling rate is invalid!')
334 row.append(
'Invalid error code: ' + str(result.m_byResult))
336 csvWriter.writerow(row)
339def batchAccessResultToList(ba_results, itemSizes):
341 Converts results of batchAccess() to Python list. Uses big endian conversion.
344 fileName - then name of the output file
345 ba_results - results returned by function recordBatch()
346 itemSizes - results returned by function recordBatch()
349 numItems = len(itemSizes)
350 numRuns = int(ba_results.size() / numItems)
352 firstAccess = ba_results[0].m_qwTimeStamp
355 for runIdx
in range(numRuns):
357 row = [(ba_results[runIdx * numItems].m_qwTimeStamp - firstAccess)/1000000.]
359 for varIdx
in range(numItems):
360 result = ba_results[runIdx * numItems + varIdx]
362 if (result.m_byResult == ic.SBatchAccessItemResult.resOK):
363 value = bigEndian2Int(itemSizes[varIdx], result.m_abyData)
366 elif (result.m_byResult == ic.SBatchAccessItemResult.resAccess):
367 row.append(
'Can not access. Check access flags in header!')
368 elif (result.m_byResult == ic.SBatchAccessItemResult.resTimeout):
369 row.append(
'Timeout! Probably the sampling rate is invalid!')
371 row.append(
'Invalid error code: ' + str(result.m_byResult))
373 recordedData.append(row)
378def writeDatatoCSV(fileName, data, expressions):
379 with open(fileName,
'w', neline=
'')
as csvFile:
380 csvWriter = csv.writer(csvFile)
382 csvWriter.writerow([
'Time'] + expressions)
385 csvWriter.writerow(row)
389 cmgr = ic.ConnectionMgr()
390 cmgr.connect(ic.CConnectionConfig().instanceId(winidea_id))
392 debugCtrl = initTarget(cmgr)
393 ideCtrl = ic.CIDEController(cmgr)
396 ideCtrl.setOption(
'/IDE/Debug.Symbols.Format.ANSI',
True)
402 watches = [
'main_loop_counter,h',
'g_intArray1[0],d',
'g_complexStruct.m_struct.i_base,d']
403 recordingTimeInSeconds = 5
404 samplingIntervalInSeconds = 0.2
405 filePrefix =
'watches'
406 isRecordToMemory =
True
407 isPrintToStdOut =
True
408 print(
'Recording watch expressions:')
409 watchResults = recordWatchExpressionsToCSV(debugCtrl,
411 recordingTimeInSeconds,
412 samplingIntervalInSeconds,
419 variables = [
'main_loop_counter',
'g_intArray1[0]',
'g_complexStruct.m_struct.i_base']
421 debugCtrl.modify(ic.IConnectDebug.fRealTime,
'main_loop_counter',
'0')
422 samplingIntervalInSeconds = 0.5
424 print(
'Recording with batch access...')
425 batchResults, itemSizes = recordBatch(cmgr,
428 recordingTimeInSeconds,
429 samplingIntervalInSeconds)
431 batchAccessResultToCSV(filePrefix +
'.csv', batchResults,
432 itemSizes, variables)
434 batchData = batchAccessResultToList(batchResults, itemSizes)
437 data = pl.array(batchData)
440 pl.plot(times, data[:, 1])
441 pl.ylabel(
'main_loop_counter')
444 pl.plot(times, data[:, 2],
'g')
445 pl.ylabel(
'g_intArray1[0]')
448 pl.plot(times, data[:, 3],
'r')
449 pl.ylabel(
'g_complexStruct.m_struct.i_base')
457if __name__ ==
'__main__':