change(sysview): drop ESP mcore extension

This commit is contained in:
Erhan Kurubas
2025-06-18 23:29:05 +02:00
committed by BOT
parent 3c29b8feec
commit d4a3d3e760
2 changed files with 557 additions and 473 deletions

View File

@@ -72,7 +72,7 @@ _sysview_events_map = {
'SYS_INIT': SYSVIEW_EVTID_INIT, 'SYS_INIT': SYSVIEW_EVTID_INIT,
'SYS_NAME_RESOURCE': SYSVIEW_EVTID_NAME_RESOURCE, 'SYS_NAME_RESOURCE': SYSVIEW_EVTID_NAME_RESOURCE,
'SYS_PRINT_FORMATTED': SYSVIEW_EVTID_PRINT_FORMATTED, 'SYS_PRINT_FORMATTED': SYSVIEW_EVTID_PRINT_FORMATTED,
'SYS_NUMMODULES': SYSVIEW_EVTID_NUMMODULES 'SYS_NUMMODULES': SYSVIEW_EVTID_NUMMODULES,
} }
_os_events_map = {} _os_events_map = {}
@@ -94,7 +94,7 @@ def parse_trace(reader, parser, os_evt_map_file=''):
global _os_events_map global _os_events_map
# parse OS events formats file # parse OS events formats file
_os_events_map = _read_events_map(os_evt_map_file) _os_events_map = _read_events_map(os_evt_map_file)
parser.esp_ext = ('; ESP_Extension\n' in _read_file_header(reader)) _read_file_header(reader)
_read_init_seq(reader) _read_init_seq(reader)
while True: while True:
event = parser.read_event(reader, _os_events_map) event = parser.read_event(reader, _os_events_map)
@@ -199,7 +199,7 @@ def _decode_u32(reader):
sz = 0 sz = 0
val = 0 val = 0
while True: while True:
b, = struct.unpack('<B', reader.read(1)) (b,) = struct.unpack('<B', reader.read(1))
if b & 0x80: if b & 0x80:
val |= (b & 0x7F) << (7 * sz) val |= (b & 0x7F) << (7 * sz)
else: else:
@@ -262,11 +262,11 @@ def _decode_str(reader):
""" """
sz = 0 sz = 0
val = '' val = ''
sz, = struct.unpack('<B', reader.read(1)) (sz,) = struct.unpack('<B', reader.read(1))
if sz == 0xFF: if sz == 0xFF:
buf = struct.unpack('<2B', reader.read(2)) buf = struct.unpack('<2B', reader.read(2))
sz = (buf[0] << 8) | buf[1] sz = (buf[0] << 8) | buf[1]
val, = struct.unpack('<%ds' % sz, reader.read(sz)) (val,) = struct.unpack('<%ds' % sz, reader.read(sz))
val = val.decode('utf-8') val = val.decode('utf-8')
if sz < 0xFF: if sz < 0xFF:
return (sz + 1, val) # one extra byte for length return (sz + 1, val) # one extra byte for length
@@ -288,9 +288,9 @@ def _decode_plen(reader):
decoded value. decoded value.
""" """
plen = 0 plen = 0
b0, = struct.unpack('<B', reader.read(1)) (b0,) = struct.unpack('<B', reader.read(1))
if b0 & 0x80: if b0 & 0x80:
b1, = struct.unpack('<B', reader.read(1)) (b1,) = struct.unpack('<B', reader.read(1))
plen = b1 # higher part plen = b1 # higher part
plen = (plen << 7) | (b0 & ~0x80) # lower 7 bits plen = (plen << 7) | (b0 & ~0x80) # lower 7 bits
else: else:
@@ -302,6 +302,7 @@ class SysViewTraceParseError(apptrace.ParseError):
""" """
SystemView parse error exception. SystemView parse error exception.
""" """
pass pass
@@ -309,6 +310,7 @@ class SysViewEvent(apptrace.TraceEvent):
""" """
Generic SystemView event class. This is a base class for all events. Generic SystemView event class. This is a base class for all events.
""" """
def __init__(self, evt_id, core_id, reader, events_fmt_map=None): def __init__(self, evt_id, core_id, reader, events_fmt_map=None):
""" """
Constructor. Reads and optionally decodes event. Constructor. Reads and optionally decodes event.
@@ -361,13 +363,21 @@ class SysViewEvent(apptrace.TraceEvent):
cur_pos = reader.get_pos() cur_pos = reader.get_pos()
sz, param_val = event_param.decode(reader, self.plen - params_len) sz, param_val = event_param.decode(reader, self.plen - params_len)
except Exception as e: except Exception as e:
raise SysViewTraceParseError('Failed to decode event {}({:d}) {:d} param @ 0x{:x}! {}'.format(self.name, self.id, self.plen, cur_pos, e)) raise SysViewTraceParseError(
'Failed to decode event {}({:d}) {:d} param @ 0x{:x}! {}'.format(
self.name, self.id, self.plen, cur_pos, e
)
)
event_param.idx = i event_param.idx = i
event_param.value = param_val event_param.value = param_val
self.params[event_param.name] = event_param self.params[event_param.name] = event_param
params_len += sz params_len += sz
if self.id >= SYSVIEW_EVENT_ID_PREDEF_LEN_MAX and self.plen != params_len: if self.id >= SYSVIEW_EVENT_ID_PREDEF_LEN_MAX and self.plen != params_len:
raise SysViewTraceParseError('Invalid event {}({:d}) payload len {:d}! Must be {:d}.'.format(self.name, self.id, self.plen, params_len)) raise SysViewTraceParseError(
'Invalid event {}({:d}) payload len {:d}! Must be {:d}.'.format(
self.name, self.id, self.plen, params_len
)
)
def __str__(self): def __str__(self):
params = '' params = ''
@@ -375,13 +385,16 @@ class SysViewEvent(apptrace.TraceEvent):
params += '{}, '.format(param) params += '{}, '.format(param)
if len(params): if len(params):
params = params[:-2] # remove trailing ', ' params = params[:-2] # remove trailing ', '
return '{:.9f} - core[{:d}].{}({:d}), plen {:d}: [{}]'.format(self.ts, self.core_id, self.name, self.id, self.plen, params) return '{:.9f} - core[{:d}].{}({:d}), plen {:d}: [{}]'.format(
self.ts, self.core_id, self.name, self.id, self.plen, params
)
class SysViewEventParam: class SysViewEventParam:
""" """
Abstract base SystemView event's parameter class. This is a base class for all event's parameters. Abstract base SystemView event's parameter class. This is a base class for all event's parameters.
""" """
def __init__(self, name, decode_func): def __init__(self, name, decode_func):
""" """
Constructor. Constructor.
@@ -413,7 +426,7 @@ class SysViewEventParam:
Returns Returns
------- -------
tuple tuple
a tuple containg number of read bytes and decoded value. a tuple containing number of read bytes and decoded value.
""" """
pass pass
@@ -428,6 +441,7 @@ class SysViewEventParamSimple(SysViewEventParam):
""" """
Simple SystemView event's parameter class. Simple SystemView event's parameter class.
""" """
def decode(self, reader, max_sz): def decode(self, reader, max_sz):
""" """
see SysViewEventParam.decode() see SysViewEventParam.decode()
@@ -439,6 +453,7 @@ class SysViewEventParamArray(SysViewEventParamSimple):
""" """
Array SystemView event's parameter class. Array SystemView event's parameter class.
""" """
def __init__(self, name, decode_func, size=-1): def __init__(self, name, decode_func, size=-1):
""" """
Constructor. Constructor.
@@ -476,6 +491,7 @@ class SysViewPredefinedEvent(SysViewEvent):
""" """
Pre-defined SystemView events class. Pre-defined SystemView events class.
""" """
_predef_events_fmt = { _predef_events_fmt = {
SYSVIEW_EVTID_NOP: ('svNop', []), SYSVIEW_EVTID_NOP: ('svNop', []),
SYSVIEW_EVTID_OVERFLOW: ('svOverflow', [SysViewEventParamSimple('drop_cnt', _decode_u32)]), SYSVIEW_EVTID_OVERFLOW: ('svOverflow', [SysViewEventParamSimple('drop_cnt', _decode_u32)]),
@@ -484,12 +500,19 @@ class SysViewPredefinedEvent(SysViewEvent):
SYSVIEW_EVTID_TASK_START_EXEC: ('svTaskStartExec', [SysViewEventParamSimple('tid', _decode_id)]), SYSVIEW_EVTID_TASK_START_EXEC: ('svTaskStartExec', [SysViewEventParamSimple('tid', _decode_id)]),
SYSVIEW_EVTID_TASK_STOP_EXEC: ('svTaskStopExec', []), SYSVIEW_EVTID_TASK_STOP_EXEC: ('svTaskStopExec', []),
SYSVIEW_EVTID_TASK_START_READY: ('svTaskStartReady', [SysViewEventParamSimple('tid', _decode_id)]), SYSVIEW_EVTID_TASK_START_READY: ('svTaskStartReady', [SysViewEventParamSimple('tid', _decode_id)]),
SYSVIEW_EVTID_TASK_STOP_READY: ('svTaskStopReady', [SysViewEventParamSimple('tid', _decode_id), SYSVIEW_EVTID_TASK_STOP_READY: (
SysViewEventParamSimple('cause', _decode_u32)]), 'svTaskStopReady',
[SysViewEventParamSimple('tid', _decode_id), SysViewEventParamSimple('cause', _decode_u32)],
),
SYSVIEW_EVTID_TASK_CREATE: ('svTaskCreate', [SysViewEventParamSimple('tid', _decode_id)]), SYSVIEW_EVTID_TASK_CREATE: ('svTaskCreate', [SysViewEventParamSimple('tid', _decode_id)]),
SYSVIEW_EVTID_TASK_INFO: ('svTaskInfo', [SysViewEventParamSimple('tid', _decode_id), SYSVIEW_EVTID_TASK_INFO: (
'svTaskInfo',
[
SysViewEventParamSimple('tid', _decode_id),
SysViewEventParamSimple('prio', _decode_u32), SysViewEventParamSimple('prio', _decode_u32),
SysViewEventParamSimple('name', _decode_str)]), SysViewEventParamSimple('name', _decode_str),
],
),
SYSVIEW_EVTID_TRACE_START: ('svTraceStart', []), SYSVIEW_EVTID_TRACE_START: ('svTraceStart', []),
SYSVIEW_EVTID_TRACE_STOP: ('svTraceStop', []), SYSVIEW_EVTID_TRACE_STOP: ('svTraceStop', []),
SYSVIEW_EVTID_SYSTIME_CYCLES: ('svSysTimeCycles', [SysViewEventParamSimple('cycles', _decode_u32)]), SYSVIEW_EVTID_SYSTIME_CYCLES: ('svSysTimeCycles', [SysViewEventParamSimple('cycles', _decode_u32)]),
@@ -501,23 +524,45 @@ class SysViewPredefinedEvent(SysViewEvent):
SYSVIEW_EVTID_ISR_TO_SCHEDULER: ('svExitIsrToScheduler', []), SYSVIEW_EVTID_ISR_TO_SCHEDULER: ('svExitIsrToScheduler', []),
SYSVIEW_EVTID_TIMER_ENTER: ('svTimerEnter', [SysViewEventParamSimple('tim_id', _decode_u32)]), SYSVIEW_EVTID_TIMER_ENTER: ('svTimerEnter', [SysViewEventParamSimple('tim_id', _decode_u32)]),
SYSVIEW_EVTID_TIMER_EXIT: ('svTimerExit', []), SYSVIEW_EVTID_TIMER_EXIT: ('svTimerExit', []),
SYSVIEW_EVTID_STACK_INFO: ('svStackInfo', [SysViewEventParamSimple('tid', _decode_id), SYSVIEW_EVTID_STACK_INFO: (
'svStackInfo',
[
SysViewEventParamSimple('tid', _decode_id),
SysViewEventParamSimple('base', _decode_u32), SysViewEventParamSimple('base', _decode_u32),
SysViewEventParamSimple('sz', _decode_u32), SysViewEventParamSimple('sz', _decode_u32),
SysViewEventParamSimple('unused', _decode_u32)]), SysViewEventParamSimple('unused', _decode_u32),
SYSVIEW_EVTID_MODULEDESC: ('svModuleDesc', [SysViewEventParamSimple('mod_id', _decode_u32), ],
),
SYSVIEW_EVTID_MODULEDESC: (
'svModuleDesc',
[
SysViewEventParamSimple('mod_id', _decode_u32),
SysViewEventParamSimple('evt_off', _decode_u32), SysViewEventParamSimple('evt_off', _decode_u32),
SysViewEventParamSimple('desc', _decode_str)]), SysViewEventParamSimple('desc', _decode_str),
SYSVIEW_EVTID_INIT: ('svInit', [SysViewEventParamSimple('sys_freq', _decode_u32), ],
),
SYSVIEW_EVTID_INIT: (
'svInit',
[
SysViewEventParamSimple('sys_freq', _decode_u32),
SysViewEventParamSimple('cpu_freq', _decode_u32), SysViewEventParamSimple('cpu_freq', _decode_u32),
SysViewEventParamSimple('ram_base', _decode_u32), SysViewEventParamSimple('ram_base', _decode_u32),
SysViewEventParamSimple('id_shift', _decode_u32)]), SysViewEventParamSimple('id_shift', _decode_u32),
],
),
SYSVIEW_EVTID_DATA_SAMPLE: ('svDataSample', []), SYSVIEW_EVTID_DATA_SAMPLE: ('svDataSample', []),
SYSVIEW_EVTID_NAME_RESOURCE: ('svNameResource', [SysViewEventParamSimple('res_id', _decode_u32), SYSVIEW_EVTID_NAME_RESOURCE: (
SysViewEventParamSimple('name', _decode_str)]), 'svNameResource',
SYSVIEW_EVTID_PRINT_FORMATTED: ('svPrint', [SysViewEventParamSimple('msg', _decode_str), [SysViewEventParamSimple('res_id', _decode_u32), SysViewEventParamSimple('name', _decode_str)],
),
SYSVIEW_EVTID_PRINT_FORMATTED: (
'svPrint',
[
SysViewEventParamSimple('msg', _decode_str),
SysViewEventParamSimple('lvl', _decode_u32), SysViewEventParamSimple('lvl', _decode_u32),
SysViewEventParamSimple('unused', _decode_u32)]), SysViewEventParamSimple('unused', _decode_u32),
],
),
SYSVIEW_EVTID_NUMMODULES: ('svNumModules', [SysViewEventParamSimple('mod_cnt', _decode_u32)]), SYSVIEW_EVTID_NUMMODULES: ('svNumModules', [SysViewEventParamSimple('mod_cnt', _decode_u32)]),
} }
@@ -533,6 +578,7 @@ class SysViewOSEvent(SysViewEvent):
""" """
OS related SystemView events class. OS related SystemView events class.
""" """
def __init__(self, evt_id, core_id, reader, events_fmt_map): def __init__(self, evt_id, core_id, reader, events_fmt_map):
""" """
see SysViewEvent.__init__() see SysViewEvent.__init__()
@@ -550,12 +596,20 @@ class SysViewHeapEvent(SysViewEvent):
events_fmt : dict events_fmt : dict
see return value of _read_events_map() see return value of _read_events_map()
""" """
events_fmt = { events_fmt = {
0: ('esp_sysview_heap_trace_alloc', [SysViewEventParamSimple('addr', _decode_u32), 0: (
'esp_sysview_heap_trace_alloc',
[
SysViewEventParamSimple('addr', _decode_u32),
SysViewEventParamSimple('size', _decode_u32), SysViewEventParamSimple('size', _decode_u32),
SysViewEventParamArray('callers', _decode_u32)]), SysViewEventParamArray('callers', _decode_u32),
1: ('esp_sysview_heap_trace_free', [SysViewEventParamSimple('addr', _decode_u32), ],
SysViewEventParamArray('callers', _decode_u32)]), ),
1: (
'esp_sysview_heap_trace_free',
[SysViewEventParamSimple('addr', _decode_u32), SysViewEventParamArray('callers', _decode_u32)],
),
} }
def __init__(self, evt_id, core_id, events_off, reader): def __init__(self, evt_id, core_id, events_off, reader):
@@ -574,8 +628,8 @@ class SysViewHeapEvent(SysViewEvent):
see SysViewEvent.__init__() see SysViewEvent.__init__()
""" """
cur_events_map = {} cur_events_map = {}
for id in self.events_fmt: for _id in self.events_fmt:
cur_events_map[events_off + id] = self.events_fmt[id] cur_events_map[events_off + _id] = self.events_fmt[_id]
SysViewEvent.__init__(self, evt_id, core_id, reader, cur_events_map) SysViewEvent.__init__(self, evt_id, core_id, reader, cur_events_map)
# self.name = 'SysViewHeapEvent' # self.name = 'SysViewHeapEvent'
@@ -593,6 +647,7 @@ class SysViewTraceDataParser(apptrace.TraceDataProcessor):
STREAMID_HEAP : int STREAMID_HEAP : int
heap events stream ID. heap events stream ID.
""" """
STREAMID_SYS = -1 STREAMID_SYS = -1
STREAMID_LOG = 0 STREAMID_LOG = 0
STREAMID_HEAP = 1 STREAMID_HEAP = 1
@@ -614,7 +669,6 @@ class SysViewTraceDataParser(apptrace.TraceDataProcessor):
self.irqs_info = {} self.irqs_info = {}
self.tasks_info = {} self.tasks_info = {}
self.core_id = core_id self.core_id = core_id
self.esp_ext = False
def _parse_irq_desc(self, desc): def _parse_irq_desc(self, desc):
""" """
@@ -701,24 +755,18 @@ class SysViewTraceDataParser(apptrace.TraceDataProcessor):
SysViewEvent SysViewEvent
pre-defined, OS-related or extension event object. pre-defined, OS-related or extension event object.
""" """
evt_hdr, = struct.unpack('<B', reader.read(1)) (evt_hdr,) = struct.unpack('<B', reader.read(1))
# read ID and core num # read ID and core num
evt_id = 0 evt_id = 0
if evt_hdr & 0x80: if evt_hdr & 0x80:
# evt_id (2 bytes) # evt_id (2 bytes)
b, = struct.unpack('<B', reader.read(1)) (b,) = struct.unpack('<B', reader.read(1))
# higher part # higher part
if self.esp_ext:
evt_id,core_id = self._decode_core_id(b)
else:
evt_id = b evt_id = b
core_id = self.core_id core_id = self.core_id
evt_id = (evt_id << 7) | (evt_hdr & ~0x80) # lower 7 bits evt_id = (evt_id << 7) | (evt_hdr & ~0x80) # lower 7 bits
else: else:
# evt_id (1 byte) # evt_id (1 byte)
if self.esp_ext:
evt_id,core_id = self._decode_core_id(evt_hdr)
else:
evt_id = evt_hdr evt_id = evt_hdr
core_id = self.core_id core_id = self.core_id
if evt_id <= SYSVIEW_EVENT_ID_PREDEF_MAX: if evt_id <= SYSVIEW_EVENT_ID_PREDEF_MAX:
@@ -779,14 +827,22 @@ class SysViewTraceDataExtEventParser(SysViewTraceDataParser):
self.events_num = events_num self.events_num = events_num
def event_supported(self, event): def event_supported(self, event):
return False if (self.events_off < SYSVIEW_MODULE_EVENT_OFFSET or event.id < self.events_off or return (
event.id >= (self.events_off + self.events_num)) else True False
if (
self.events_off < SYSVIEW_MODULE_EVENT_OFFSET
or event.id < self.events_off
or event.id >= (self.events_off + self.events_num)
)
else True
)
class SysViewMultiTraceDataParser(SysViewTraceDataParser): class SysViewMultiTraceDataParser(SysViewTraceDataParser):
""" """
SystemView trace data parser supporting multiple event streams. SystemView trace data parser supporting multiple event streams.
""" """
def __init__(self, print_events=False, core_id=0): def __init__(self, print_events=False, core_id=0):
""" """
see SysViewTraceDataParser.__init__() see SysViewTraceDataParser.__init__()
@@ -850,10 +906,11 @@ class SysViewMultiTraceDataParser(SysViewTraceDataParser):
self.stream_parsers[stream_id].on_new_event(event) self.stream_parsers[stream_id].on_new_event(event)
class SysViewEventContext(): class SysViewEventContext:
""" """
SystemView event context. SystemView event context.
""" """
def __init__(self, handle, irq, name=''): def __init__(self, handle, irq, name=''):
""" """
Constructor. Constructor.
@@ -876,6 +933,7 @@ class SysViewTraceDataProcessor(apptrace.TraceDataProcessor):
""" """
Base SystemView trace data processor class. Base SystemView trace data processor class.
""" """
def __init__(self, traces, root_proc=None, print_events=False, keep_all_events=False): def __init__(self, traces, root_proc=None, print_events=False, keep_all_events=False):
""" """
Constructor. Constructor.
@@ -903,7 +961,8 @@ class SysViewTraceDataProcessor(apptrace.TraceDataProcessor):
# empty list means IDLE context or self.start_ctx # empty list means IDLE context or self.start_ctx
self.ctx_stack[t.core_id] = [] self.ctx_stack[t.core_id] = []
# context is undefined, we do not know have we started the tracing in task/IDLE or IRQ context # context is undefined, we do not know have we started the tracing in task/IDLE or IRQ context
# in general there are three scenarios when we can start tracing: when core is in task, IDLE task or IRQ context # in general there are three scenarios when we can start tracing:
# when core is in task, IDLE task or IRQ context
self.prev_ctx[t.core_id] = None self.prev_ctx[t.core_id] = None
def _get_curr_context(self, core_id): def _get_curr_context(self, core_id):
@@ -966,13 +1025,13 @@ class SysViewTraceDataProcessor(apptrace.TraceDataProcessor):
def event_supported(self, e): def event_supported(self, e):
""" """
Should be overriden in child class. Should be overridden in child class.
""" """
return False return False
def handle_event(self, e): def handle_event(self, e):
""" """
Should be overriden in child class. Should be overridden in child class.
""" """
pass pass
@@ -1000,14 +1059,6 @@ class SysViewTraceDataProcessor(apptrace.TraceDataProcessor):
if SYSVIEW_EVTID_TASK_START_EXEC or SYSVIEW_EVTID_TASK_STOP_READY is received for unknown task. if SYSVIEW_EVTID_TASK_START_EXEC or SYSVIEW_EVTID_TASK_STOP_READY is received for unknown task.
""" """
if event.core_id not in self.traces: if event.core_id not in self.traces:
if 0 in self.traces and self.traces[0].esp_ext:
# for Espressif extension there is one trace for all cores
trace = self.traces[0]
if event.core_id not in self.ctx_stack:
self.ctx_stack[event.core_id] = []
if event.core_id not in self.prev_ctx:
self.prev_ctx[event.core_id] = None
else:
raise SysViewTraceParseError('Event for unknown core %d' % event.core_id) raise SysViewTraceParseError('Event for unknown core %d' % event.core_id)
else: else:
trace = self.traces[event.core_id] trace = self.traces[event.core_id]
@@ -1017,16 +1068,20 @@ class SysViewTraceDataProcessor(apptrace.TraceDataProcessor):
if len(self.ctx_stack[event.core_id]): if len(self.ctx_stack[event.core_id]):
self.prev_ctx[event.core_id] = self.ctx_stack[event.core_id][-1] self.prev_ctx[event.core_id] = self.ctx_stack[event.core_id][-1]
else: else:
# the 1st context switching event after trace start is SYSVIEW_EVTID_ISR_ENTER, so we have been in IDLE context # the 1st context switching event after trace start is SYSVIEW_EVTID_ISR_ENTER,
# so we have been in IDLE context
self.prev_ctx[event.core_id] = SysViewEventContext(None, False, 'IDLE%d' % event.core_id) self.prev_ctx[event.core_id] = SysViewEventContext(None, False, 'IDLE%d' % event.core_id)
# put new ISR context on top of the stack (the last in the list) # put new ISR context on top of the stack (the last in the list)
self.ctx_stack[event.core_id].append(SysViewEventContext(event.params['irq_num'].value, True, trace.irqs_info[event.params['irq_num'].value])) self.ctx_stack[event.core_id].append(
SysViewEventContext(event.params['irq_num'].value, True, trace.irqs_info[event.params['irq_num'].value])
)
elif event.id == SYSVIEW_EVTID_ISR_EXIT or event.id == SYSVIEW_EVTID_ISR_TO_SCHEDULER: elif event.id == SYSVIEW_EVTID_ISR_EXIT or event.id == SYSVIEW_EVTID_ISR_TO_SCHEDULER:
if len(self.ctx_stack[event.core_id]): if len(self.ctx_stack[event.core_id]):
# return to the previous context (the last in the list) # return to the previous context (the last in the list)
self.prev_ctx[event.core_id] = self.ctx_stack[event.core_id].pop() self.prev_ctx[event.core_id] = self.ctx_stack[event.core_id].pop()
else: else:
# the 1st context switching event after trace start is SYSVIEW_EVTID_ISR_EXIT, so we have been in ISR context, # the 1st context switching event after trace start is SYSVIEW_EVTID_ISR_EXIT,
# so we have been in ISR context,
# but we do not know which one because SYSVIEW_EVTID_ISR_EXIT do not include the IRQ number # but we do not know which one because SYSVIEW_EVTID_ISR_EXIT do not include the IRQ number
self.prev_ctx[event.core_id] = SysViewEventContext(None, True, 'IRQ_oncore%d' % event.core_id) self.prev_ctx[event.core_id] = SysViewEventContext(None, True, 'IRQ_oncore%d' % event.core_id)
elif event.id == SYSVIEW_EVTID_TASK_START_EXEC: elif event.id == SYSVIEW_EVTID_TASK_START_EXEC:
@@ -1036,10 +1091,13 @@ class SysViewTraceDataProcessor(apptrace.TraceDataProcessor):
# return to the previous context (the last in the list) # return to the previous context (the last in the list)
self.prev_ctx[event.core_id] = self.ctx_stack[event.core_id][-1] self.prev_ctx[event.core_id] = self.ctx_stack[event.core_id][-1]
else: else:
# the 1st context switching event after trace start is SYSVIEW_EVTID_TASK_START_EXEC, so we have been in IDLE context # the 1st context switching event after trace start is SYSVIEW_EVTID_TASK_START_EXEC,
# so we have been in IDLE context
self.prev_ctx[event.core_id] = SysViewEventContext(None, False, 'IDLE%d' % event.core_id) self.prev_ctx[event.core_id] = SysViewEventContext(None, False, 'IDLE%d' % event.core_id)
# only one task at a time in context stack (can be interrupted by a bunch of ISRs) # only one task at a time in context stack (can be interrupted by a bunch of ISRs)
self.ctx_stack[event.core_id] = [SysViewEventContext(event.params['tid'].value, False, trace.tasks_info[event.params['tid'].value])] self.ctx_stack[event.core_id] = [
SysViewEventContext(event.params['tid'].value, False, trace.tasks_info[event.params['tid'].value])
]
elif event.id == SYSVIEW_EVTID_TASK_STOP_EXEC: elif event.id == SYSVIEW_EVTID_TASK_STOP_EXEC:
# delete task from context stack # delete task from context stack
for ctx in self.ctx_stack[event.core_id]: for ctx in self.ctx_stack[event.core_id]:
@@ -1053,12 +1111,18 @@ class SysViewTraceDataProcessor(apptrace.TraceDataProcessor):
if event.params['tid'].value not in trace.tasks_info: if event.params['tid'].value not in trace.tasks_info:
raise SysViewTraceParseError('Stop ready unknown task 0x%x' % event.params['tid'].value) raise SysViewTraceParseError('Stop ready unknown task 0x%x' % event.params['tid'].value)
if len(self.ctx_stack[event.core_id]): if len(self.ctx_stack[event.core_id]):
if (not self.ctx_stack[event.core_id][-1].irq and event.params['tid'].value == self.ctx_stack[event.core_id][-1].handle): if (
not self.ctx_stack[event.core_id][-1].irq
and event.params['tid'].value == self.ctx_stack[event.core_id][-1].handle
):
# return to the previous context (the last in the list) # return to the previous context (the last in the list)
self.prev_ctx[event.core_id] = self.ctx_stack[event.core_id].pop() self.prev_ctx[event.core_id] = self.ctx_stack[event.core_id].pop()
else: else:
# the 1st context switching event after trace start is SYSVIEW_EVTID_TASK_STOP_READY, so we have been in task context # the 1st context switching event after trace start is SYSVIEW_EVTID_TASK_STOP_READY,
self.prev_ctx[event.core_id] = SysViewEventContext(event.params['tid'].value, False, trace.tasks_info[event.params['tid'].value]) # so we have been in task context
self.prev_ctx[event.core_id] = SysViewEventContext(
event.params['tid'].value, False, trace.tasks_info[event.params['tid'].value]
)
def on_new_event(self, event): def on_new_event(self, event):
""" """
@@ -1105,6 +1169,7 @@ class SysViewMultiStreamTraceDataProcessor(SysViewTraceDataProcessor):
""" """
SystemView trace data processor supporting multiple event streams. SystemView trace data processor supporting multiple event streams.
""" """
def __init__(self, traces, print_events=False, keep_all_events=False): def __init__(self, traces, print_events=False, keep_all_events=False):
""" """
see SysViewTraceDataProcessor.__init__() see SysViewTraceDataProcessor.__init__()
@@ -1146,10 +1211,6 @@ class SysViewMultiStreamTraceDataProcessor(SysViewTraceDataProcessor):
SysViewTraceDataParser SysViewTraceDataParser
parser object for specified stream and core parser object for specified stream and core
""" """
if core_id not in self.traces and 0 in self.traces and self.traces[0].esp_ext:
# for Espressif extension there is one trace for all cores
trace = self.traces[0]
else:
trace = self.traces[core_id] trace = self.traces[core_id]
if stream_id == SysViewTraceDataParser.STREAMID_SYS: if stream_id == SysViewTraceDataParser.STREAMID_SYS:
return trace return trace
@@ -1222,11 +1283,26 @@ class SysViewTraceDataJsonEncoder(json.JSONEncoder):
callers = [] callers = []
for addr in obj.params['callers'].value: for addr in obj.params['callers'].value:
callers.append('0x{:x}'.format(addr)) callers.append('0x{:x}'.format(addr))
return {'ctx_name': obj.ctx_name, 'in_irq': obj.in_irq, 'id': obj.id, 'core_id': obj.core_id, return {
'ts': obj.ts, 'addr': blk_addr, 'size': blk_size, 'callers': callers} 'ctx_name': obj.ctx_name,
'in_irq': obj.in_irq,
'id': obj.id,
'core_id': obj.core_id,
'ts': obj.ts,
'addr': blk_addr,
'size': blk_size,
'callers': callers,
}
if isinstance(obj, SysViewPredefinedEvent) and obj.id == SYSVIEW_EVTID_PRINT_FORMATTED: if isinstance(obj, SysViewPredefinedEvent) and obj.id == SYSVIEW_EVTID_PRINT_FORMATTED:
return {'ctx_name': obj.ctx_name, 'in_irq': obj.in_irq, 'id': obj.id, 'core_id': obj.core_id, return {
'ts': obj.ts, 'msg': obj.params['msg'].value, 'lvl': obj.params['lvl'].value} 'ctx_name': obj.ctx_name,
'in_irq': obj.in_irq,
'id': obj.id,
'core_id': obj.core_id,
'ts': obj.ts,
'msg': obj.params['msg'].value,
'lvl': obj.params['lvl'].value,
}
if isinstance(obj, SysViewEvent): if isinstance(obj, SysViewEvent):
jobj = obj.to_jsonable() jobj = obj.to_jsonable()
# remove unused fields # remove unused fields
@@ -1243,20 +1319,26 @@ class SysViewHeapTraceDataParser(SysViewTraceDataExtEventParser):
""" """
SystemView trace data parser supporting heap events. SystemView trace data parser supporting heap events.
""" """
def __init__(self, print_events=False, core_id=0): def __init__(self, print_events=False, core_id=0):
""" """
SystemView trace data parser supporting multiple event streams. SystemView trace data parser supporting multiple event streams.
see SysViewTraceDataExtEventParser.__init__() see SysViewTraceDataExtEventParser.__init__()
""" """
SysViewTraceDataExtEventParser.__init__(self, events_num=len(SysViewHeapEvent.events_fmt.keys()), core_id=core_id, print_events=print_events) SysViewTraceDataExtEventParser.__init__(
self, events_num=len(SysViewHeapEvent.events_fmt.keys()), core_id=core_id, print_events=print_events
)
def read_extension_event(self, evt_id, core_id, reader): def read_extension_event(self, evt_id, core_id, reader):
""" """
Reads heap event. Reads heap event.
see SysViewTraceDataParser.read_extension_event() see SysViewTraceDataParser.read_extension_event()
""" """
if (self.events_off >= SYSVIEW_MODULE_EVENT_OFFSET and evt_id >= self.events_off and if (
evt_id < self.events_off + self.events_num): self.events_off >= SYSVIEW_MODULE_EVENT_OFFSET
and evt_id >= self.events_off
and evt_id < self.events_off + self.events_num
):
return SysViewHeapEvent(evt_id, core_id, self.events_off, reader) return SysViewHeapEvent(evt_id, core_id, self.events_off, reader)
return SysViewTraceDataParser.read_extension_event(self, evt_id, core_id, reader) return SysViewTraceDataParser.read_extension_event(self, evt_id, core_id, reader)
@@ -1266,7 +1348,10 @@ class SysViewHeapTraceDataParser(SysViewTraceDataExtEventParser):
""" """
if self.root_proc == self: if self.root_proc == self:
SysViewTraceDataParser.on_new_event(self, event) SysViewTraceDataParser.on_new_event(self, event)
if event.id == SYSVIEW_EVTID_MODULEDESC and event.params['desc'].value == 'M=ESP32 SystemView Heap Tracing Module': if (
event.id == SYSVIEW_EVTID_MODULEDESC
and event.params['desc'].value == 'M=ESP32 SystemView Heap Tracing Module'
):
self.events_off = event.params['evt_off'].value self.events_off = event.params['evt_off'].value
@@ -1274,7 +1359,10 @@ class SysViewHeapTraceDataProcessor(SysViewTraceDataProcessor, apptrace.BaseHeap
""" """
SystemView trace data processor supporting heap events. SystemView trace data processor supporting heap events.
""" """
def __init__(self, toolchain_pref, elf_path, root_proc=None, traces=[], print_events=False, print_heap_events=False):
def __init__(
self, toolchain_pref, elf_path, root_proc=None, traces=[], print_events=False, print_heap_events=False
):
""" """
Constructor. Constructor.
see SysViewTraceDataProcessor.__init__() see SysViewTraceDataProcessor.__init__()
@@ -1296,11 +1384,9 @@ class SysViewHeapTraceDataProcessor(SysViewTraceDataProcessor, apptrace.BaseHeap
def handle_event(self, event): def handle_event(self, event):
heap_stream = self.root_proc.get_trace_stream(event.core_id, SysViewTraceDataParser.STREAMID_HEAP) heap_stream = self.root_proc.get_trace_stream(event.core_id, SysViewTraceDataParser.STREAMID_HEAP)
if (event.id - heap_stream.events_off) == 0: if (event.id - heap_stream.events_off) == 0:
heap_event = apptrace.HeapTraceEvent(event, True, toolchain=self.toolchain, heap_event = apptrace.HeapTraceEvent(event, True, toolchain=self.toolchain, elf_path=self.elf_path)
elf_path=self.elf_path)
else: else:
heap_event = apptrace.HeapTraceEvent(event, False, toolchain=self.toolchain, heap_event = apptrace.HeapTraceEvent(event, False, toolchain=self.toolchain, elf_path=self.elf_path)
elf_path=self.elf_path)
apptrace.BaseHeapTraceDataProcessorImpl.on_new_event(self, heap_event) apptrace.BaseHeapTraceDataProcessorImpl.on_new_event(self, heap_event)
def print_report(self): def print_report(self):
@@ -1316,6 +1402,7 @@ class SysViewLogTraceEvent(apptrace.LogTraceEvent):
""" """
SystemView log event. SystemView log event.
""" """
def __init__(self, ts, msg): def __init__(self, ts, msg):
""" """
Constructor. Constructor.
@@ -1344,6 +1431,7 @@ class SysViewLogTraceDataParser(SysViewTraceDataParser):
""" """
SystemView trace data parser supporting log events. SystemView trace data parser supporting log events.
""" """
def event_supported(self, event): def event_supported(self, event):
return event.id == SYSVIEW_EVTID_PRINT_FORMATTED return event.id == SYSVIEW_EVTID_PRINT_FORMATTED
@@ -1359,6 +1447,7 @@ class SysViewLogTraceDataProcessor(SysViewTraceDataProcessor, apptrace.BaseLogTr
""" """
SystemView trace data processor supporting heap events. SystemView trace data processor supporting heap events.
""" """
def __init__(self, traces=[], root_proc=None, print_events=False, print_log_events=False): def __init__(self, traces=[], root_proc=None, print_events=False, print_log_events=False):
""" """
Constructor. Constructor.

View File

@@ -7,7 +7,6 @@
# Trace data can be provided in multiple trace files (one per CPU). After processing phase # Trace data can be provided in multiple trace files (one per CPU). After processing phase
# script prints report for every type of trace data stream which was found. # script prints report for every type of trace data stream which was found.
# #
import argparse import argparse
import json import json
import logging import logging
@@ -50,16 +49,13 @@ def split_segger_multicore_file(file_path):
header = f.read(200) header = f.read(200)
header_str = header.decode('utf-8', errors='ignore') header_str = header.decode('utf-8', errors='ignore')
core0_offset = None
core1_offset = None core1_offset = None
for line in header_str.split('\n'): for line in header_str.split('\n'):
if '; Offset Core0' in line: if '; Offset Core1' in line:
core0_offset = int(line.strip().split()[-1])
elif '; Offset Core1' in line:
core1_offset = int(line.strip().split()[-1]) core1_offset = int(line.strip().split()[-1])
if core0_offset is None or core1_offset is None: if core1_offset is None:
logging.error('Failed to parse core offsets') logging.error('Failed to parse core1 offset')
return None, None return None, None
# Read the entire file # Read the entire file
@@ -258,7 +254,6 @@ def main():
proc.print_report() proc.print_report()
proc.cleanup() proc.cleanup()
if len(temp_files) > 0:
for file in temp_files: for file in temp_files:
try: try:
os.remove(file) os.remove(file)