sysview.py 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355
  1. import re
  2. import struct
  3. import copy
  4. import json
  5. import espytrace.apptrace as apptrace
  6. SYSVIEW_EVTID_NOP = 0 # Dummy packet.
  7. SYSVIEW_EVTID_OVERFLOW = 1
  8. SYSVIEW_EVTID_ISR_ENTER = 2
  9. SYSVIEW_EVTID_ISR_EXIT = 3
  10. SYSVIEW_EVTID_TASK_START_EXEC = 4
  11. SYSVIEW_EVTID_TASK_STOP_EXEC = 5
  12. SYSVIEW_EVTID_TASK_START_READY = 6
  13. SYSVIEW_EVTID_TASK_STOP_READY = 7
  14. SYSVIEW_EVTID_TASK_CREATE = 8
  15. SYSVIEW_EVTID_TASK_INFO = 9
  16. SYSVIEW_EVTID_TRACE_START = 10
  17. SYSVIEW_EVTID_TRACE_STOP = 11
  18. SYSVIEW_EVTID_SYSTIME_CYCLES = 12
  19. SYSVIEW_EVTID_SYSTIME_US = 13
  20. SYSVIEW_EVTID_SYSDESC = 14
  21. SYSVIEW_EVTID_USER_START = 15
  22. SYSVIEW_EVTID_USER_STOP = 16
  23. SYSVIEW_EVTID_IDLE = 17
  24. SYSVIEW_EVTID_ISR_TO_SCHEDULER = 18
  25. SYSVIEW_EVTID_TIMER_ENTER = 19
  26. SYSVIEW_EVTID_TIMER_EXIT = 20
  27. SYSVIEW_EVTID_STACK_INFO = 21
  28. SYSVIEW_EVTID_MODULEDESC = 22
  29. SYSVIEW_EVTID_INIT = 24
  30. SYSVIEW_EVENT_ID_PREDEF_LEN_MAX = SYSVIEW_EVTID_INIT
  31. SYSVIEW_EVTID_NAME_RESOURCE = 25
  32. SYSVIEW_EVTID_PRINT_FORMATTED = 26
  33. SYSVIEW_EVTID_NUMMODULES = 27
  34. SYSVIEW_EVENT_ID_PREDEF_MAX = SYSVIEW_EVTID_NUMMODULES
  35. SYSVIEW_EVENT_ID_MAX = 200
  36. SYSVIEW_MODULE_EVENT_OFFSET = 512
  37. SYSVIEW_SYNC_LEN = 10
  38. _sysview_events_map = {
  39. "SYS_NOP": SYSVIEW_EVTID_NOP,
  40. "SYS_OVERFLOW": SYSVIEW_EVTID_OVERFLOW,
  41. "SYS_ISR_ENTER": SYSVIEW_EVTID_ISR_ENTER,
  42. "SYS_ISR_EXIT": SYSVIEW_EVTID_ISR_EXIT,
  43. "SYS_TASK_START_EXEC": SYSVIEW_EVTID_TASK_START_EXEC,
  44. "SYS_TASK_STOP_EXEC": SYSVIEW_EVTID_TASK_STOP_EXEC,
  45. "SYS_TASK_START_READY": SYSVIEW_EVTID_TASK_START_READY,
  46. "SYS_TASK_STOP_READY": SYSVIEW_EVTID_TASK_STOP_READY,
  47. "SYS_TASK_CREATE": SYSVIEW_EVTID_TASK_CREATE,
  48. "SYS_TASK_INFO": SYSVIEW_EVTID_TASK_INFO,
  49. "SYS_TRACE_START": SYSVIEW_EVTID_TRACE_START,
  50. "SYS_TRACE_STOP": SYSVIEW_EVTID_TRACE_STOP,
  51. "SYS_SYSTIME_CYCLES": SYSVIEW_EVTID_SYSTIME_CYCLES,
  52. "SYS_SYSTIME_US": SYSVIEW_EVTID_SYSTIME_US,
  53. "SYS_SYSDESC": SYSVIEW_EVTID_SYSDESC,
  54. "SYS_USER_START": SYSVIEW_EVTID_USER_START,
  55. "SYS_USER_STOP": SYSVIEW_EVTID_USER_STOP,
  56. "SYS_IDLE": SYSVIEW_EVTID_IDLE,
  57. "SYS_ISR_TO_SCHEDULER": SYSVIEW_EVTID_ISR_TO_SCHEDULER,
  58. "SYS_TIMER_ENTER": SYSVIEW_EVTID_TIMER_ENTER,
  59. "SYS_TIMER_EXIT": SYSVIEW_EVTID_TIMER_EXIT,
  60. "SYS_STACK_INFO": SYSVIEW_EVTID_STACK_INFO,
  61. "SYS_MODULEDESC": SYSVIEW_EVTID_INIT,
  62. "SYS_INIT": SYSVIEW_EVTID_INIT,
  63. "SYS_NAME_RESOURCE": SYSVIEW_EVTID_NAME_RESOURCE,
  64. "SYS_PRINT_FORMATTED": SYSVIEW_EVTID_PRINT_FORMATTED,
  65. "SYS_NUMMODULES": SYSVIEW_EVTID_NUMMODULES
  66. }
  67. _os_events_map = {}
  68. def parse_trace(reader, parser, os_evt_map_file=''):
  69. """
  70. Parses trace.
  71. Parameters
  72. ----------
  73. reader : apptrace.Reader
  74. Trace reader object.
  75. parser : SysViewTraceDataParser
  76. Top level parser object.
  77. os_evt_map_file : string
  78. Path to file containg events format description.
  79. """
  80. global _os_events_map
  81. # parse OS events formats file
  82. _os_events_map = _read_events_map(os_evt_map_file)
  83. _read_file_header(reader)
  84. _read_init_seq(reader)
  85. while True:
  86. event = parser.read_event(reader, _os_events_map)
  87. parser.on_new_event(event)
  88. def _read_events_map(os_evt_map_file):
  89. """
  90. Reads SystemView events format description from file.
  91. Parameters
  92. ----------
  93. os_evt_map_file : string
  94. Path to file containg events format description.
  95. Returns
  96. -------
  97. dict
  98. a dict with event IDs as keys and values as tuples containg event name and a list of parameters.
  99. """
  100. os_evt_map = {}
  101. with open(os_evt_map_file) as f:
  102. for line in f:
  103. comps = line.split()
  104. if len(comps) < 2:
  105. continue
  106. params = []
  107. if len(comps) > 2:
  108. for p in comps[2:]:
  109. sp = p.split('=')
  110. if sp[1].startswith('%'):
  111. sp[1] = sp[1][1:]
  112. if sp[1] == 'u':
  113. params.append(SysViewEventParamSimple(sp[0], _decode_u32))
  114. elif sp[1] == 's':
  115. params.append(SysViewEventParamSimple(sp[0], _decode_str))
  116. elif sp[1] == 't' or sp[1] == 'T' or sp[1] == 'I' or sp[1] == 'p':
  117. # TODO: handle shrinked task/queue ID and addresses
  118. params.append(SysViewEventParamSimple(sp[0], _decode_u32))
  119. os_evt_map[int(comps[0])] = (comps[1], params)
  120. return os_evt_map
  121. def _read_file_header(reader):
  122. """
  123. Reads SystemView trace file header.
  124. Parameters
  125. ----------
  126. reader : apptrace.Reader
  127. Trace reader object.
  128. Returns
  129. -------
  130. list
  131. a list of header lines.
  132. """
  133. empty_count = 0
  134. lines = []
  135. while empty_count < 2:
  136. lines.append(reader.readline(linesep='\n'))
  137. if lines[-1] == ';\n':
  138. empty_count += 1
  139. return lines
  140. def _read_init_seq(reader):
  141. """
  142. Reads SystemView trace initial synchronisation sequence of bytes.
  143. Parameters
  144. ----------
  145. reader : apptrace.Reader
  146. Trace reader object.
  147. Raises
  148. -------
  149. SysViewTraceParseError
  150. If sync sequence is broken.
  151. """
  152. SYNC_SEQ_FMT = '<%dB' % SYSVIEW_SYNC_LEN
  153. sync_bytes = struct.unpack(SYNC_SEQ_FMT, reader.read(struct.calcsize(SYNC_SEQ_FMT)))
  154. for b in sync_bytes:
  155. if b != 0:
  156. raise SysViewTraceParseError("Invalid sync sequense!")
  157. def _decode_u32(reader):
  158. """
  159. Reads and decodes unsigned 32-bit integer.
  160. Parameters
  161. ----------
  162. reader : apptrace.Reader
  163. Trace reader object.
  164. Returns
  165. -------
  166. tuple
  167. a tuple containg number of read bytes and decoded value.
  168. """
  169. sz = 0
  170. val = 0
  171. while True:
  172. b, = struct.unpack('<B', reader.read(1))
  173. if b & 0x80:
  174. val |= (b & 0x7F) << (7 * sz)
  175. else:
  176. val |= b << (7 * sz)
  177. break
  178. sz += 1
  179. return (sz + 1,val)
  180. def _decode_id(reader):
  181. """
  182. Reads and decodes ID (task ID, queue handle, semaphore handle etc.).
  183. Parameters
  184. ----------
  185. reader : apptrace.Reader
  186. Trace reader object.
  187. Returns
  188. -------
  189. tuple
  190. a tuple containg number of read bytes and decoded value.
  191. """
  192. return _decode_u32(reader)
  193. def _decode_u64(reader):
  194. """
  195. Reads and decodes unsigned 64-bit integer.
  196. Parameters
  197. ----------
  198. reader : apptrace.Reader
  199. Trace reader object.
  200. Returns
  201. -------
  202. tuple
  203. a tuple containg number of read bytes and decoded value.
  204. """
  205. sz,val = _decode_u32(reader)
  206. sz2,high = _decode_u32(reader)
  207. sz += sz2
  208. return sz,(val | (high << 32))
  209. def _decode_str(reader):
  210. """
  211. Reads and decodes string.
  212. Parameters
  213. ----------
  214. reader : apptrace.Reader
  215. Trace reader object.
  216. Returns
  217. -------
  218. tuple
  219. a tuple containg number of read bytes and decoded value.
  220. """
  221. sz = 0
  222. val = ''
  223. sz, = struct.unpack('<B', reader.read(1))
  224. if sz == 0xFF:
  225. buf = struct.unpack('<2B', reader.read(2))
  226. sz = (buf[1] << 8) | buf[0]
  227. val, = struct.unpack('<%ds' % sz, reader.read(sz))
  228. val = val.decode("utf-8")
  229. if sz < 0xFF:
  230. return (sz + 1,val) # one extra byte for length
  231. return (sz + 3,val) # 3 extra bytes for length
  232. def _decode_plen(reader):
  233. """
  234. Reads and decodes event's payload length.
  235. Parameters
  236. ----------
  237. reader : apptrace.Reader
  238. Trace reader object.
  239. Returns
  240. -------
  241. int
  242. decoded value.
  243. """
  244. plen = 0
  245. b0, = struct.unpack('<B', reader.read(1))
  246. if b0 & 0x80:
  247. b1, = struct.unpack('<B', reader.read(1))
  248. plen = b1 # higher part
  249. plen = (plen << 7) | (b0 & ~0x80) # lower 7 bits
  250. else:
  251. plen = b0
  252. return plen
  253. class SysViewTraceParseError(apptrace.ParseError):
  254. """
  255. SystemView parse error exception.
  256. """
  257. pass
  258. class SysViewEvent(apptrace.TraceEvent):
  259. """
  260. Generic SystemView event class. This is a base class for all events.
  261. """
  262. def __init__(self, evt_id, reader, core_id, events_fmt_map=None):
  263. """
  264. Constructor. Reads and optionally decodes event.
  265. Parameters
  266. ----------
  267. evt_id : int
  268. Event ID.
  269. reader : apptrace.Reader
  270. Trace reader object.
  271. core_id : int
  272. Core ID event has been generated on.
  273. events_fmt_map : dict
  274. see return value of _read_events_map()
  275. """
  276. apptrace.TraceEvent.__init__(self, 'SysViewEvent', core_id, evt_id)
  277. self.plen = 0
  278. if self.id >= SYSVIEW_EVENT_ID_PREDEF_LEN_MAX:
  279. self.plen = _decode_plen(reader)
  280. if events_fmt_map:
  281. self._read_payload(reader, events_fmt_map)
  282. else:
  283. reader.forward(self.plen)
  284. _,self.ts = _decode_u32(reader)
  285. def _read_payload(self, reader, events_fmt_map):
  286. """
  287. Reads event's payload and populates its parameters dictionary.
  288. Parameters
  289. ----------
  290. reader : apptrace.Reader
  291. Trace reader object.
  292. events_fmt_map : dict
  293. see return value of _read_events_map()
  294. Raises
  295. -------
  296. SysViewTraceParseError
  297. if event has unknown or invalid format.
  298. """
  299. if self.id not in events_fmt_map:
  300. raise SysViewTraceParseError("Unknown event ID %d!" % self.id)
  301. self.name = events_fmt_map[self.id][0]
  302. evt_params_templates = events_fmt_map[self.id][1]
  303. params_len = 0
  304. for i in range(len(evt_params_templates)):
  305. event_param = copy.deepcopy(evt_params_templates[i])
  306. try:
  307. cur_pos = reader.get_pos()
  308. sz,param_val = event_param.decode(reader, self.plen - params_len)
  309. except Exception as e:
  310. raise SysViewTraceParseError("Failed to decode event {}({:d}) {:d} param @ 0x{:x}! {}".format(self.name, self.id, self.plen, cur_pos, e))
  311. event_param.idx = i
  312. event_param.value = param_val
  313. self.params[event_param.name] = event_param
  314. params_len += sz
  315. if self.id >= SYSVIEW_EVENT_ID_PREDEF_LEN_MAX and self.plen != params_len:
  316. raise SysViewTraceParseError("Invalid event {}({:d}) payload len {:d}! Must be {:d}.".format(self.name, self.id, self.plen, params_len))
  317. def __str__(self):
  318. params = ''
  319. for param in sorted(self.params.values(), key=lambda x: x.idx):
  320. params += '{}, '.format(param)
  321. if len(params):
  322. params = params[:-2] # remove trailing ', '
  323. return '{:.9f} - core[{:d}].{}({:d}), plen {:d}: [{}]'.format(self.ts, self.core_id, self.name, self.id, self.plen, params)
  324. class SysViewEventParam:
  325. """
  326. Abstract base SystemView event's parameter class. This is a base class for all event's parameters.
  327. """
  328. def __init__(self, name, decode_func):
  329. """
  330. Constructor.
  331. Parameters
  332. ----------
  333. name : string
  334. Event parameter name.
  335. decode_func : callable object
  336. Parameter decoding function.
  337. """
  338. self.name = name
  339. self.decode_func = decode_func
  340. self.value = None
  341. # positional index, used for sorting parameters before printing to make them looking as they appear in the event
  342. self.idx = 0
  343. def decode(self, reader, max_sz):
  344. """
  345. Reads and decodes events parameter.
  346. Parameters
  347. ----------
  348. reader : apptrace.Reader
  349. Trace reader object.
  350. max_sz : int
  351. Maximum number of bytes to read.
  352. Returns
  353. -------
  354. tuple
  355. a tuple containg number of read bytes and decoded value.
  356. """
  357. pass
  358. def __str__(self):
  359. return '{}: {}'.format(self.name, self.value)
  360. def to_jsonable(self):
  361. return {self.name: self.value}
  362. class SysViewEventParamSimple(SysViewEventParam):
  363. """
  364. Simple SystemView event's parameter class.
  365. """
  366. def decode(self, reader, max_sz):
  367. """
  368. see SysViewEventParam.decode()
  369. """
  370. return self.decode_func(reader)
  371. class SysViewEventParamArray(SysViewEventParamSimple):
  372. """
  373. Array SystemView event's parameter class.
  374. """
  375. def __init__(self, name, decode_func, size=-1):
  376. """
  377. Constructor.
  378. Parameters
  379. ----------
  380. name : string
  381. see SysViewEventParam.__init__()
  382. decode_func : callable object
  383. see SysViewEventParam.__init__()
  384. size : int
  385. Array's size. If -1 decode() will try to read all bytes from reader.
  386. """
  387. SysViewEventParamSimple.__init__(self, name, decode_func)
  388. self.arr_size = size
  389. def decode(self, reader, max_sz):
  390. """
  391. see SysViewEventParam.decode()
  392. """
  393. tottal_sz = 0
  394. vals = []
  395. i = 0
  396. while tottal_sz < max_sz:
  397. sz,val = self.decode_func(reader)
  398. vals.append(val)
  399. tottal_sz += sz
  400. i += 1
  401. if self.arr_size != -1 and i == self.arr_size:
  402. break
  403. return tottal_sz,vals
  404. class SysViewPredefinedEvent(SysViewEvent):
  405. """
  406. Pre-defined SystemView events class.
  407. """
  408. _predef_events_fmt = {
  409. SYSVIEW_EVTID_NOP: ('svNop', []),
  410. SYSVIEW_EVTID_OVERFLOW: ('svOverflow', [SysViewEventParamSimple('drop_cnt', _decode_u32)]),
  411. SYSVIEW_EVTID_ISR_ENTER: ('svIsrEnter', [SysViewEventParamSimple('irq_num', _decode_u32)]),
  412. SYSVIEW_EVTID_ISR_EXIT: ('svIsrExit', []),
  413. SYSVIEW_EVTID_TASK_START_EXEC: ('svTaskStartExec', [SysViewEventParamSimple('tid', _decode_id)]),
  414. SYSVIEW_EVTID_TASK_STOP_EXEC: ('svTaskStopExec', []),
  415. SYSVIEW_EVTID_TASK_START_READY: ('svTaskStartReady', [SysViewEventParamSimple('tid', _decode_id)]),
  416. SYSVIEW_EVTID_TASK_STOP_READY: ('svTaskStopReady', [SysViewEventParamSimple('tid', _decode_id),
  417. SysViewEventParamSimple('cause', _decode_u32)]),
  418. SYSVIEW_EVTID_TASK_CREATE: ('svTaskCreate', [SysViewEventParamSimple('tid', _decode_id)]),
  419. SYSVIEW_EVTID_TASK_INFO: ('svTaskInfo', [SysViewEventParamSimple('tid', _decode_id),
  420. SysViewEventParamSimple('prio', _decode_u32),
  421. SysViewEventParamSimple('name', _decode_str)]),
  422. SYSVIEW_EVTID_TRACE_START: ('svTraceStart', []),
  423. SYSVIEW_EVTID_TRACE_STOP: ('svTraceStop', []),
  424. SYSVIEW_EVTID_SYSTIME_CYCLES: ('svSysTimeCycles', [SysViewEventParamSimple('cycles', _decode_u32)]),
  425. SYSVIEW_EVTID_SYSTIME_US: ('svSysTimeUs', [SysViewEventParamSimple('time', _decode_u64)]),
  426. SYSVIEW_EVTID_SYSDESC: ('svSysDesc', [SysViewEventParamSimple('desc', _decode_str)]),
  427. SYSVIEW_EVTID_USER_START: ('svUserStart', [SysViewEventParamSimple('user_id', _decode_u32)]),
  428. SYSVIEW_EVTID_USER_STOP: ('svUserStart', [SysViewEventParamSimple('user_id', _decode_u32)]),
  429. SYSVIEW_EVTID_IDLE: ('svIdle', []),
  430. SYSVIEW_EVTID_ISR_TO_SCHEDULER: ('svExitIsrToScheduler', []),
  431. SYSVIEW_EVTID_TIMER_ENTER: ('svTimerEnter', [SysViewEventParamSimple('tim_id', _decode_u32)]),
  432. SYSVIEW_EVTID_TIMER_EXIT: ('svTimerExit', []),
  433. SYSVIEW_EVTID_STACK_INFO: ('svStackInfo', [SysViewEventParamSimple('tid', _decode_id),
  434. SysViewEventParamSimple('base', _decode_u32),
  435. SysViewEventParamSimple('sz', _decode_u32),
  436. SysViewEventParamSimple('unused', _decode_u32)]),
  437. SYSVIEW_EVTID_MODULEDESC: ('svModuleDesc', [SysViewEventParamSimple('mod_id', _decode_u32),
  438. SysViewEventParamSimple('evt_off', _decode_u32),
  439. SysViewEventParamSimple('desc', _decode_str)]),
  440. SYSVIEW_EVTID_INIT: ('svInit', [SysViewEventParamSimple('sys_freq', _decode_u32),
  441. SysViewEventParamSimple('cpu_freq', _decode_u32),
  442. SysViewEventParamSimple('ram_base', _decode_u32),
  443. SysViewEventParamSimple('id_shift', _decode_u32)]),
  444. SYSVIEW_EVTID_NAME_RESOURCE: ('svNameResource', [SysViewEventParamSimple('res_id', _decode_u32),
  445. SysViewEventParamSimple('name', _decode_str)]),
  446. SYSVIEW_EVTID_PRINT_FORMATTED: ('svPrint', [SysViewEventParamSimple('msg', _decode_str),
  447. SysViewEventParamSimple('lvl', _decode_u32),
  448. SysViewEventParamSimple('unused', _decode_u32)]),
  449. SYSVIEW_EVTID_NUMMODULES: ('svNumModules', [SysViewEventParamSimple('mod_cnt', _decode_u32)]),
  450. }
  451. def __init__(self, evt_id, reader, core_id):
  452. """
  453. see SysViewEvent.__init__()
  454. """
  455. SysViewEvent.__init__(self, evt_id, reader, core_id, self._predef_events_fmt)
  456. # self.name = 'SysViewPredefinedEvent'
  457. class SysViewOSEvent(SysViewEvent):
  458. """
  459. OS related SystemView events class.
  460. """
  461. def __init__(self, evt_id, reader, core_id, events_fmt_map):
  462. """
  463. see SysViewEvent.__init__()
  464. """
  465. SysViewEvent.__init__(self, evt_id, reader, core_id, events_fmt_map)
  466. # self.name = 'SysViewOSEvent'
  467. class SysViewHeapEvent(SysViewEvent):
  468. """
  469. Heap related SystemView events class.
  470. Attributes
  471. ----------
  472. events_fmt : dict
  473. see return value of _read_events_map()
  474. """
  475. events_fmt = {
  476. 0: ('esp_sysview_heap_trace_alloc', [SysViewEventParamSimple('addr', _decode_u32),
  477. SysViewEventParamSimple('size', _decode_u32),
  478. SysViewEventParamArray('callers', _decode_u32)]),
  479. 1: ('esp_sysview_heap_trace_free', [SysViewEventParamSimple('addr', _decode_u32),
  480. SysViewEventParamArray('callers', _decode_u32)]),
  481. }
  482. def __init__(self, evt_id, events_off, reader, core_id):
  483. """
  484. Constructor. Reads and optionally decodes event.
  485. Parameters
  486. ----------
  487. evt_id : int
  488. see SysViewEvent.__init__()
  489. events_off : int
  490. Offset for heap events IDs. Greater or equal to SYSVIEW_MODULE_EVENT_OFFSET.
  491. reader : apptrace.Reader
  492. see SysViewEvent.__init__()
  493. core_id : int
  494. see SysViewEvent.__init__()
  495. """
  496. cur_events_map = {}
  497. for id in self.events_fmt:
  498. cur_events_map[events_off + id] = self.events_fmt[id]
  499. SysViewEvent.__init__(self, evt_id, reader, core_id, cur_events_map)
  500. # self.name = 'SysViewHeapEvent'
  501. class SysViewTraceDataParser(apptrace.TraceDataProcessor):
  502. """
  503. Base SystemView trace data parser class.
  504. Attributes
  505. ----------
  506. STREAMID_SYS : int
  507. system events stream ID. Reserved for internal uses.
  508. STREAMID_LOG : int
  509. log events stream ID.
  510. STREAMID_HEAP : int
  511. heap events stream ID.
  512. """
  513. STREAMID_SYS = -1
  514. STREAMID_LOG = 0
  515. STREAMID_HEAP = 1
  516. def __init__(self, print_events=False, core_id=0):
  517. """
  518. Constructor.
  519. Parameters
  520. ----------
  521. print_events : bool
  522. see apptrace.TraceDataProcessor.__init__()
  523. core_id : int
  524. id of the core this parser object relates to.
  525. """
  526. apptrace.TraceDataProcessor.__init__(self, print_events=print_events, keep_all_events=True)
  527. self.sys_info = None
  528. self._last_ts = 0
  529. self.irqs_info = {}
  530. self.tasks_info = {}
  531. self.core_id = core_id
  532. def _parse_irq_desc(self, desc):
  533. """
  534. Parses IRQ description.
  535. Parameters
  536. ----------
  537. desc : string
  538. IRQ description string.
  539. Returns
  540. -------
  541. tuple
  542. a tuple with IRQ number and name or None on error.
  543. """
  544. m = re.match('I#([0-9]+)=(.+)', desc)
  545. if m:
  546. return m.group(2),m.group(1)
  547. return None
  548. def _update_ts(self, ts):
  549. """
  550. Calculates real event timestamp.
  551. Parameters
  552. ----------
  553. ts : int
  554. Event timestamp offset.
  555. Returns
  556. -------
  557. float
  558. real event timestamp.
  559. """
  560. self._last_ts += ts
  561. return float(self._last_ts) / self.sys_info.params['sys_freq'].value
  562. def read_extension_event(self, evt_id, reader):
  563. """
  564. Reads extension event.
  565. Default implementation which just reads out event.
  566. Parameters
  567. ----------
  568. evt_id : int
  569. Event ID.
  570. reader : apptrace.Reader
  571. Trace reader object.
  572. Returns
  573. -------
  574. SysViewEvent
  575. if this is top level parser returns object for generic event,
  576. otherwise returns None indicating to the calling top level parser
  577. that extension event are not supported.
  578. """
  579. if self.root_proc == self:
  580. # by default just read out and skip unknown event
  581. return SysViewEvent(evt_id, reader, self.core_id)
  582. return None # let decide to root parser
  583. def read_event(self, reader, os_evt_map):
  584. """
  585. Reads pre-defined or OS-related event.
  586. Parameters
  587. ----------
  588. reader : apptrace.Reader
  589. Trace reader object.
  590. os_evt_map : dict
  591. see return value of _read_events_map()
  592. Returns
  593. -------
  594. SysViewEvent
  595. pre-defined, OS-related or extension event object.
  596. """
  597. evt_hdr, = struct.unpack('<B', reader.read(1))
  598. # read ID and core num
  599. evt_id = 0
  600. if evt_hdr & 0x80:
  601. # evt_id (2 bytes)
  602. b, = struct.unpack('<B', reader.read(1))
  603. evt_id = b # higher part
  604. evt_id = (evt_id << 7) | (evt_hdr & ~0x80) # lower 7 bits
  605. else:
  606. # evt_id (1 byte)
  607. evt_id = evt_hdr
  608. if evt_id <= SYSVIEW_EVENT_ID_PREDEF_MAX:
  609. return SysViewPredefinedEvent(evt_id, reader, self.core_id)
  610. elif evt_id < SYSVIEW_MODULE_EVENT_OFFSET:
  611. return SysViewOSEvent(evt_id, reader, self.core_id, os_evt_map)
  612. else:
  613. return self.read_extension_event(evt_id, reader)
  614. def event_supported(self, event):
  615. return False
  616. def on_new_event(self, event):
  617. """
  618. Does essential processing of event. Must be called for every read event.
  619. Assigns real timestamp to event. Updates global system info: system description,
  620. mapping of tasks IDs to names and IRQ names to numbers.
  621. Parameters
  622. ----------
  623. event : SysViewEvent
  624. Event object.
  625. """
  626. if event.id == SYSVIEW_EVTID_TRACE_START:
  627. event.ts = 0
  628. self._last_ts = 0
  629. elif self.sys_info:
  630. event.ts = self._update_ts(event.ts)
  631. if event.id == SYSVIEW_EVTID_INIT:
  632. self.sys_info = event
  633. event.ts = self._update_ts(event.ts)
  634. elif event.id == SYSVIEW_EVTID_TASK_INFO:
  635. self.tasks_info[event.params['tid'].value] = event.params['name'].value
  636. elif event.id == SYSVIEW_EVTID_SYSDESC:
  637. irq = self._parse_irq_desc(event.params['desc'].value)
  638. if irq:
  639. irq_num = int(irq[1])
  640. self.irqs_info[irq_num] = irq[0]
  641. # count event and save it to the list
  642. apptrace.TraceDataProcessor.on_new_event(self, event)
  643. class SysViewTraceDataExtEventParser(SysViewTraceDataParser):
  644. def __init__(self, events_num, print_events=False, core_id=0):
  645. """
  646. Constructor.
  647. Parameters
  648. ----------
  649. print_events : bool
  650. see apptrace.TraceDataProcessor.__init__()
  651. core_id : int
  652. id of the core this parser object relates to.
  653. """
  654. SysViewTraceDataParser.__init__(self, core_id=core_id, print_events=print_events)
  655. self.events_off = 0
  656. self.events_num = events_num
  657. def event_supported(self, event):
  658. return False if (self.events_off < SYSVIEW_MODULE_EVENT_OFFSET or event.id < self.events_off or
  659. event.id >= (self.events_off + self.events_num)) else True
  660. class SysViewMultiTraceDataParser(SysViewTraceDataParser):
  661. """
  662. SystemView trace data parser supporting multiple event streams.
  663. """
  664. def __init__(self, print_events=False, core_id=0):
  665. """
  666. see SysViewTraceDataParser.__init__()
  667. """
  668. SysViewTraceDataParser.__init__(self, print_events, core_id)
  669. self.stream_parsers = {}
  670. def add_stream_parser(self, stream_id, parser):
  671. """
  672. Assigns parser for events stream.
  673. Parameters
  674. ----------
  675. stream_id : int
  676. stream ID. See SysViewTraceDataParser.STREAMID_xxx.
  677. Parsers for SysViewTraceDataParser.STREAMID_SYS are ignored.
  678. Top level parser is the default for SysViewTraceDataParser.STREAMID_SYS.
  679. parser : SysViewTraceDataParser
  680. parser object.
  681. """
  682. if stream_id == SysViewTraceDataParser.STREAMID_SYS:
  683. return
  684. parser.root_proc = self
  685. self.stream_parsers[stream_id] = parser
  686. def read_extension_event(self, evt_id, reader):
  687. """
  688. Reads extension event.
  689. Iterates over registered stream parsers trying to find one which supports that type of event.
  690. Parameters
  691. ----------
  692. evt_id : int
  693. see SysViewTraceDataParser.read_extension_event()
  694. reader : apptrace.Reader
  695. see SysViewTraceDataParser.read_extension_event()
  696. Returns
  697. -------
  698. SysViewEvent
  699. object for extension event, if extension event is not supported return SysViewEvent instance.
  700. """
  701. for stream_id in self.stream_parsers:
  702. evt = self.stream_parsers[stream_id].read_extension_event(evt_id, reader)
  703. if evt:
  704. return evt
  705. return SysViewTraceDataParser.read_extension_event(self, evt_id, reader)
  706. def on_new_event(self, event):
  707. """
  708. Iterates over registered stream parsers allowing them to do
  709. essential processing of event. Must be called for every read event.
  710. Parameters
  711. ----------
  712. event : SysViewEvent
  713. Event object.
  714. """
  715. SysViewTraceDataParser.on_new_event(self, event)
  716. for stream_id in self.stream_parsers:
  717. self.stream_parsers[stream_id].on_new_event(event)
  718. class SysViewEventContext():
  719. """
  720. SystemView event context.
  721. """
  722. def __init__(self, handle, irq, name=''):
  723. """
  724. Constructor.
  725. Parameters
  726. ----------
  727. handle : int
  728. handle of the context: task ID or IRQ number.
  729. irq : bool
  730. flag indicating whether this is IRQ or task context.
  731. name : string
  732. name of the context: task or IRQ name. Empty if context is unknown.
  733. """
  734. self.handle = handle
  735. self.irq = irq
  736. self.name = name
  737. class SysViewTraceDataProcessor(apptrace.TraceDataProcessor):
  738. """
  739. Base SystemView trace data processor class.
  740. """
  741. def __init__(self, traces, root_proc=None, print_events=False, keep_all_events=False):
  742. """
  743. Constructor.
  744. Parameters
  745. ----------
  746. traces : list
  747. list of parsers to process data from.
  748. print_events : bool
  749. see apptrace.TraceDataProcessor.__init__()
  750. keep_all_events : bool
  751. see apptrace.TraceDataProcessor.__init__()
  752. """
  753. apptrace.TraceDataProcessor.__init__(self, print_events, keep_all_events)
  754. self.event_ids = {}
  755. self.name = ""
  756. self.root_proc = root_proc if root_proc else self
  757. self.traces = {}
  758. self.ctx_stack = {}
  759. self.prev_ctx = {}
  760. self.no_ctx_events = []
  761. for t in traces:
  762. self.traces[t.core_id] = t
  763. # current context item is a tuple of task ID or IRQ num and 'in_irq' flag
  764. # empty list means IDLE context or self.start_ctx
  765. self.ctx_stack[t.core_id] = []
  766. # context is undefined, we do not know have we started the tracing in task/IDLE or IRQ context
  767. # in general there are three scenarious when we can start tracing: when core is in task, IDLE task or IRQ context
  768. self.prev_ctx[t.core_id] = None
  769. def _get_curr_context(self, core_id):
  770. """
  771. Returns current context.
  772. Parameters
  773. ----------
  774. core_id : int
  775. core ID for requested context.
  776. Returns
  777. -------
  778. SysViewEventContext
  779. context object
  780. None
  781. if there current is undefined
  782. """
  783. if len(self.root_proc.ctx_stack[core_id]):
  784. return self.root_proc.ctx_stack[core_id][-1]
  785. if self._get_prev_context(core_id):
  786. return SysViewEventContext(None, False, 'IDLE%d' % core_id)
  787. return None
  788. def _get_prev_context(self, core_id):
  789. """
  790. Returns current context.
  791. Parameters
  792. ----------
  793. core_id : int
  794. core ID for requested context.
  795. Returns
  796. -------
  797. SysViewEventContext
  798. context object
  799. """
  800. return self.root_proc.prev_ctx[core_id]
  801. def get_trace_stream(self, core_id, stream_id):
  802. """
  803. Retrieves parser for specified stream and core.
  804. Parameters
  805. ----------
  806. core_id : int
  807. Parser's core ID.
  808. stream_id : int
  809. Parser's stream ID.
  810. Returns
  811. -------
  812. SysViewTraceDataParser
  813. parser object for specified stream and core
  814. """
  815. if self.root_proc == self:
  816. return self.traces[core_id]
  817. return self.root_proc.get_trace_stream(core_id, stream_id)
  818. def event_supported(self, e):
  819. """
  820. Should be overriden in child class.
  821. """
  822. return False
  823. def handle_event(self, e):
  824. """
  825. Should be overriden in child class.
  826. """
  827. pass
  828. def print_report(self):
  829. """
  830. see apptrace.TraceDataProcessor.print_report()
  831. """
  832. apptrace.TraceDataProcessor.print_report(self)
  833. def _process_event(self, event):
  834. """
  835. Processes event.
  836. Keeps track of execution context on every core.
  837. Parameters
  838. ----------
  839. event : SysViewEvent
  840. Event object.
  841. Raises
  842. ----------
  843. SysViewTraceParseError
  844. if there is no parser for event's core or
  845. if SYSVIEW_EVTID_ISR_ENTER is received for unknown IRQ or
  846. if SYSVIEW_EVTID_TASK_START_EXEC or SYSVIEW_EVTID_TASK_STOP_READY is received for unknown task.
  847. """
  848. if event.core_id not in self.traces:
  849. raise SysViewTraceParseError("Event for unknown core %d" % event.core_id)
  850. trace = self.traces[event.core_id]
  851. if event.id == SYSVIEW_EVTID_ISR_ENTER:
  852. if event.params['irq_num'].value not in trace.irqs_info:
  853. raise SysViewTraceParseError("Enter unknown ISR %d" % event.params['irq_num'].value)
  854. if len(self.ctx_stack[event.core_id]):
  855. self.prev_ctx[event.core_id] = self.ctx_stack[event.core_id][-1]
  856. else:
  857. # the 1st context switching event after trace start is SYSVIEW_EVTID_ISR_ENTER, so we have been in IDLE context
  858. self.prev_ctx[event.core_id] = SysViewEventContext(None, False, 'IDLE%d' % event.core_id)
  859. # put new ISR context on top of the stack (the last in the list)
  860. self.ctx_stack[event.core_id].append(SysViewEventContext(event.params['irq_num'].value, True, trace.irqs_info[event.params['irq_num'].value]))
  861. elif event.id == SYSVIEW_EVTID_ISR_EXIT or event.id == SYSVIEW_EVTID_ISR_TO_SCHEDULER:
  862. if len(self.ctx_stack[event.core_id]):
  863. # return to the previous context (the last in the list)
  864. self.prev_ctx[event.core_id] = self.ctx_stack[event.core_id].pop()
  865. else:
  866. # the 1st context switching event after trace start is SYSVIEW_EVTID_ISR_EXIT, so we have been in ISR context,
  867. # but we do not know which one because SYSVIEW_EVTID_ISR_EXIT do not include the IRQ number
  868. self.prev_ctx[event.core_id] = SysViewEventContext(None, True, 'IRQ_oncore%d' % event.core_id)
  869. elif event.id == SYSVIEW_EVTID_TASK_START_EXEC:
  870. if event.params['tid'].value not in trace.tasks_info:
  871. raise SysViewTraceParseError("Start exec unknown task 0x%x" % event.params['tid'].value)
  872. if len(self.ctx_stack[event.core_id]):
  873. # return to the previous context (the last in the list)
  874. self.prev_ctx[event.core_id] = self.ctx_stack[event.core_id][-1]
  875. else:
  876. # the 1st context switching event after trace start is SYSVIEW_EVTID_TASK_START_EXEC, so we have been in IDLE context
  877. self.prev_ctx[event.core_id] = SysViewEventContext(None, False, 'IDLE%d' % event.core_id)
  878. # only one task at a time in context stack (can be interrupted by a bunch of ISRs)
  879. self.ctx_stack[event.core_id] = [SysViewEventContext(event.params['tid'].value, False, trace.tasks_info[event.params['tid'].value])]
  880. elif event.id == SYSVIEW_EVTID_TASK_STOP_EXEC:
  881. # delete task from context stack
  882. for ctx in self.ctx_stack[event.core_id]:
  883. if not ctx.irq:
  884. if len(self.ctx_stack[event.core_id]) == 1:
  885. # if this is the only ctx in context stack
  886. self.prev_ctx[event.core_id] = ctx
  887. del ctx
  888. break
  889. elif event.id == SYSVIEW_EVTID_TASK_STOP_READY:
  890. if event.params['tid'].value not in trace.tasks_info:
  891. raise SysViewTraceParseError("Stop ready unknown task 0x%x" % event.params['tid'].value)
  892. if len(self.ctx_stack[event.core_id]):
  893. if (not self.ctx_stack[event.core_id][-1].irq and event.params['tid'].value == self.ctx_stack[event.core_id][-1].handle):
  894. # return to the previous context (the last in the list)
  895. self.prev_ctx[event.core_id] = self.ctx_stack[event.core_id].pop()
  896. else:
  897. # the 1st context switching event after trace start is SYSVIEW_EVTID_TASK_STOP_READY, so we have been in task context
  898. self.prev_ctx[event.core_id] = SysViewEventContext(event.params['tid'].value, False, trace.tasks_info[event.params['tid'].value])
  899. def on_new_event(self, event):
  900. """
  901. Processes heap events.
  902. """
  903. if self.root_proc == self:
  904. SysViewTraceDataProcessor._process_event(self, event)
  905. curr_ctx = self._get_curr_context(event.core_id)
  906. if not curr_ctx:
  907. # postpone events handling till their context is known
  908. self.no_ctx_events.append(event)
  909. return
  910. event.in_irq = curr_ctx.irq
  911. event.ctx_name = curr_ctx.name
  912. # here we know the previous context: we switched from it or implied upon the 1st context switching event
  913. prev_ctx = self._get_prev_context(event.core_id)
  914. if len(self.no_ctx_events):
  915. for cached_evt in self.no_ctx_events:
  916. cached_evt.ctx_name = prev_ctx.name
  917. cached_evt.in_irq = prev_ctx.irq
  918. # count and save the event
  919. apptrace.TraceDataProcessor.on_new_event(self, cached_evt)
  920. if self.event_supported(event):
  921. self.handle_event(event)
  922. del self.no_ctx_events[:]
  923. # count and save the event
  924. apptrace.TraceDataProcessor.on_new_event(self, event)
  925. if self.event_supported(event):
  926. self.handle_event(event)
  927. def merge_and_process(self):
  928. """
  929. Merges events from all registered parsers, sorts them by timestamp and processes them.
  930. """
  931. all_events = []
  932. for t in self.traces.values():
  933. all_events.extend(t.events)
  934. all_events.sort(key=lambda x: x.ts)
  935. for event in all_events:
  936. self.on_new_event(event)
  937. class SysViewMultiStreamTraceDataProcessor(SysViewTraceDataProcessor):
  938. """
  939. SystemView trace data processor supporting multiple event streams.
  940. """
  941. def __init__(self, traces, print_events=False, keep_all_events=False):
  942. """
  943. see SysViewTraceDataProcessor.__init__()
  944. """
  945. SysViewTraceDataProcessor.__init__(self, traces, print_events=print_events, keep_all_events=keep_all_events)
  946. self.stream_procs = {}
  947. def add_stream_processor(self, stream_id, proc):
  948. """
  949. Assigns processor for events stream.
  950. Parameters
  951. ----------
  952. stream_id : int
  953. stream ID. See SysViewTraceDataParser.STREAMID_xxx.
  954. Parsers for SysViewTraceDataParser.STREAMID_SYS are ignored.
  955. Top level parser is the default for SysViewTraceDataParser.STREAMID_SYS.
  956. proc : SysViewTraceDataProcessor
  957. processor object.
  958. """
  959. if stream_id == SysViewTraceDataParser.STREAMID_SYS:
  960. return
  961. proc.root_proc = self # common processing data is kept by this processor
  962. self.stream_procs[stream_id] = proc
  963. def get_trace_stream(self, core_id, stream_id):
  964. """
  965. Retrieves parser for specified stream and core.
  966. Parameters
  967. ----------
  968. core_id : int
  969. Parser's core ID.
  970. stream_id : int
  971. Parser's stream ID.
  972. Returns
  973. -------
  974. SysViewTraceDataParser
  975. parser object for specified stream and core
  976. """
  977. trace = self.traces[core_id]
  978. if stream_id == SysViewTraceDataParser.STREAMID_SYS:
  979. return trace
  980. if isinstance(trace, SysViewMultiTraceDataParser):
  981. return trace.stream_parsers[stream_id]
  982. return trace
  983. def print_report(self):
  984. """
  985. Iterates over registered stream processors and prints their reports.
  986. """
  987. SysViewTraceDataProcessor.print_report(self)
  988. # need to sort stream procs by keys to print reports in the same order regardless of Python version
  989. stream_ids = list(self.stream_procs.keys())
  990. stream_ids.sort()
  991. for stream_id in stream_ids:
  992. self.stream_procs[stream_id].print_report()
  993. def cleanup(self):
  994. """
  995. Iterates over registered stream processors and cleans them up.
  996. """
  997. for stream_id in self.stream_procs:
  998. self.stream_procs[stream_id].cleanup()
  999. SysViewTraceDataProcessor.cleanup(self)
  1000. def on_new_event(self, event):
  1001. """
  1002. Iterates over registered stream processors allowing them to do
  1003. the processing of event.
  1004. Parameters
  1005. ----------
  1006. event : SysViewEvent
  1007. Event object.
  1008. """
  1009. SysViewTraceDataProcessor.on_new_event(self, event)
  1010. for stream_id in self.stream_procs:
  1011. self.stream_procs[stream_id].on_new_event(event)
  1012. class SysViewTraceDataJsonEncoder(json.JSONEncoder):
  1013. JSON_TRACE_VER = "1.0"
  1014. def default(self, obj):
  1015. global _sysview_events_map
  1016. global _os_events_map
  1017. if isinstance(obj, SysViewMultiStreamTraceDataProcessor):
  1018. json_event_ids = {"system": _sysview_events_map, "os": {}}
  1019. for eid in _os_events_map:
  1020. ename = _os_events_map[eid][0]
  1021. json_event_ids['os'][ename] = eid
  1022. for stream in obj.stream_procs.values():
  1023. json_event_ids[stream.name] = stream.event_ids
  1024. json_events = []
  1025. for e in obj.events:
  1026. for stream in obj.stream_procs.values():
  1027. if stream.event_supported(e):
  1028. json_events.append(e)
  1029. break
  1030. # include also OS and pre-defined events
  1031. if isinstance(e, SysViewPredefinedEvent) or isinstance(e, SysViewOSEvent):
  1032. json_events.append(e)
  1033. return {"version": self.JSON_TRACE_VER, "streams": json_event_ids, "events": json_events}
  1034. if isinstance(obj, SysViewHeapEvent):
  1035. blk_size = 0
  1036. if "size" in obj.params:
  1037. blk_size = obj.params["size"].value
  1038. blk_addr = "0x{:x}".format(obj.params["addr"].value)
  1039. callers = []
  1040. for addr in obj.params['callers'].value:
  1041. callers.append('0x{:x}'.format(addr))
  1042. return {"ctx_name": obj.ctx_name, "in_irq": obj.in_irq, "id": obj.id, "core_id": obj.core_id,
  1043. "ts": obj.ts, "addr": blk_addr, "size": blk_size, "callers": callers}
  1044. if isinstance(obj, SysViewPredefinedEvent) and obj.id == SYSVIEW_EVTID_PRINT_FORMATTED:
  1045. return {"ctx_name": obj.ctx_name, "in_irq": obj.in_irq, "id": obj.id, "core_id": obj.core_id,
  1046. "ts": obj.ts, "msg": obj.params["msg"].value, "lvl": obj.params["lvl"].value}
  1047. if isinstance(obj, SysViewEvent):
  1048. jobj = obj.to_jsonable()
  1049. # remove unused fields
  1050. if 'name' in jobj:
  1051. del jobj['name']
  1052. if 'plen' in jobj:
  1053. del jobj['plen']
  1054. return jobj
  1055. # Let the base class default method raise the TypeError
  1056. return json.JSONEncoder.default(self, obj)
  1057. class SysViewHeapTraceDataParser(SysViewTraceDataExtEventParser):
  1058. """
  1059. SystemView trace data parser supporting heap events.
  1060. """
  1061. def __init__(self, print_events=False, core_id=0):
  1062. """
  1063. SystemView trace data parser supporting multiple event streams.
  1064. see SysViewTraceDataExtEventParser.__init__()
  1065. """
  1066. SysViewTraceDataExtEventParser.__init__(self, events_num=len(SysViewHeapEvent.events_fmt.keys()), core_id=core_id, print_events=print_events)
  1067. def read_extension_event(self, evt_id, reader):
  1068. """
  1069. Reads heap event.
  1070. see SysViewTraceDataParser.read_extension_event()
  1071. """
  1072. if (self.events_off >= SYSVIEW_MODULE_EVENT_OFFSET and evt_id >= self.events_off and
  1073. evt_id < self.events_off + self.events_num):
  1074. return SysViewHeapEvent(evt_id, self.events_off, reader, self.core_id)
  1075. return SysViewTraceDataParser.read_extension_event(self, evt_id, reader)
  1076. def on_new_event(self, event):
  1077. """
  1078. Keeps track of heap module descriptions.
  1079. """
  1080. if self.root_proc == self:
  1081. SysViewTraceDataParser.on_new_event(self, event)
  1082. if event.id == SYSVIEW_EVTID_MODULEDESC and event.params['desc'].value == 'ESP32 SystemView Heap Tracing Module':
  1083. self.events_off = event.params['evt_off'].value
  1084. class SysViewHeapTraceDataProcessor(SysViewTraceDataProcessor, apptrace.BaseHeapTraceDataProcessorImpl):
  1085. """
  1086. SystemView trace data processor supporting heap events.
  1087. """
  1088. def __init__(self, toolchain_pref, elf_path, root_proc=None, traces=[], print_events=False, print_heap_events=False):
  1089. """
  1090. Constructor.
  1091. see SysViewTraceDataProcessor.__init__()
  1092. see apptrace.BaseHeapTraceDataProcessorImpl.__init__()
  1093. """
  1094. SysViewTraceDataProcessor.__init__(self, traces, root_proc=root_proc, print_events=print_events)
  1095. apptrace.BaseHeapTraceDataProcessorImpl.__init__(self, print_heap_events)
  1096. self.toolchain = toolchain_pref
  1097. self.elf_path = elf_path
  1098. # self.no_ctx_events = []
  1099. self.name = "heap"
  1100. stream = self.root_proc.get_trace_stream(0, SysViewTraceDataParser.STREAMID_HEAP)
  1101. self.event_ids = {"alloc": stream.events_off, "free": stream.events_off + 1}
  1102. def event_supported(self, event):
  1103. heap_stream = self.root_proc.get_trace_stream(event.core_id, SysViewTraceDataParser.STREAMID_HEAP)
  1104. return heap_stream.event_supported(event)
  1105. def handle_event(self, event):
  1106. heap_stream = self.root_proc.get_trace_stream(event.core_id, SysViewTraceDataParser.STREAMID_HEAP)
  1107. if (event.id - heap_stream.events_off) == 0:
  1108. heap_event = apptrace.HeapTraceEvent(event, True, toolchain=self.toolchain,
  1109. elf_path=self.elf_path)
  1110. else:
  1111. heap_event = apptrace.HeapTraceEvent(event, False, toolchain=self.toolchain,
  1112. elf_path=self.elf_path)
  1113. apptrace.BaseHeapTraceDataProcessorImpl.on_new_event(self, heap_event)
  1114. def print_report(self):
  1115. """
  1116. see apptrace.TraceDataProcessor.print_report()
  1117. """
  1118. if self.root_proc == self:
  1119. SysViewTraceDataProcessor.print_report(self)
  1120. apptrace.BaseHeapTraceDataProcessorImpl.print_report(self)
  1121. class SysViewLogTraceEvent(apptrace.LogTraceEvent):
  1122. """
  1123. SystemView log event.
  1124. """
  1125. def __init__(self, ts, msg):
  1126. """
  1127. Constructor.
  1128. Parameters
  1129. ----------
  1130. msg : string
  1131. Log message string.
  1132. """
  1133. self.msg = msg
  1134. self.ts = ts
  1135. def get_message(self, unused):
  1136. """
  1137. Retrieves log message.
  1138. Returns
  1139. -------
  1140. string
  1141. formatted log message
  1142. """
  1143. return '[{:.9f}] LOG: {}'.format(self.ts, self.msg)
  1144. class SysViewLogTraceDataParser(SysViewTraceDataParser):
  1145. """
  1146. SystemView trace data parser supporting log events.
  1147. """
  1148. def event_supported(self, event):
  1149. return event.id == SYSVIEW_EVTID_PRINT_FORMATTED
  1150. def on_new_event(self, event):
  1151. """
  1152. see SysViewTraceDataParser.on_new_event()
  1153. """
  1154. if self.root_proc == self:
  1155. SysViewTraceDataParser.on_new_event(self, event)
  1156. class SysViewLogTraceDataProcessor(SysViewTraceDataProcessor, apptrace.BaseLogTraceDataProcessorImpl):
  1157. """
  1158. SystemView trace data processor supporting heap events.
  1159. """
  1160. def __init__(self, traces=[], root_proc=None, print_events=False, print_log_events=False):
  1161. """
  1162. Constructor.
  1163. see SysViewTraceDataProcessor.__init__()
  1164. see apptrace.BaseLogTraceDataProcessorImpl.__init__()
  1165. """
  1166. SysViewTraceDataProcessor.__init__(self, traces, root_proc=root_proc, print_events=print_events)
  1167. apptrace.BaseLogTraceDataProcessorImpl.__init__(self, print_log_events)
  1168. self.name = "log"
  1169. self.event_ids = {"print": SYSVIEW_EVTID_PRINT_FORMATTED}
  1170. def event_supported(self, event):
  1171. return event.id == SYSVIEW_EVTID_PRINT_FORMATTED
  1172. def on_new_event(self, event):
  1173. """
  1174. Processes log events.
  1175. """
  1176. if self.root_proc == self:
  1177. SysViewTraceDataProcessor.on_new_event(self, event)
  1178. if event.id == SYSVIEW_EVTID_PRINT_FORMATTED:
  1179. log_evt = SysViewLogTraceEvent(event.ts, event.params['msg'].value)
  1180. apptrace.BaseLogTraceDataProcessorImpl.on_new_event(self, log_evt)
  1181. def print_report(self):
  1182. """
  1183. see apptrace.TraceDataProcessor.print_report()
  1184. """
  1185. if self.root_proc == self:
  1186. SysViewTraceDataProcessor.print_report(self)
  1187. apptrace.BaseLogTraceDataProcessorImpl.print_report(self)