MT/content/result.tex

594 lines
30 KiB
TeX

\chapter{System Trace}
\label{chapter:btf}
In \autoref{section:trace_measurement} a trace has been defined as a
sequence of chronological ordered events. An event is a system state change an
evaluator is interested in. Various trace tools exist to record events. They
can be classified into hardware, hybrid and software tools.
The same event can be represented on different levels as shown in
\autoref{fig:trace_event_levels}. An event within the respective level
shall be called hardware, software or system event. An event can be moved
from one level into another via transformation. For example a voltage level
change in memory is a hardware event. The corresponding software event could
be a value change of a certain variable.
Different representation levels do not relate to measurement tools with the
same name. A hardware event can be measured directly via hardware tracing.
But it is also possible to detect the change of a variable via software
tracing. Based on the software event the occurrence of the respective hardware
event can be deduced. This means hardware event detection is not limited to
hardware tracing and the same is true for software events.
A well-defined format for events is required for further processing of recorded
traces. Tools that analyze or visualize a trace must be able to interpret the
recorded data. For example the hardware trace host software must be able to
understand the hardware events that are generated by the on-chip trace device.
Otherwise it is not possible to transform the hardware events into higher level
software events.
Depending on the measurement goal a different event level may be required: A
hardware designer is not interested in the timing behavior of an engine control
unit, rather the correct functionality of a certain hardware register is of
interest. On the other hand, an application architect relies on the correct
functionality of the hardware, but the timing behavior of an application on
architecture level must be analyzable.
\section{BTF}
A system level trace can be used to analyze timing, performance and reliability
of an embedded system. \gls{btf} (\glsdesc{btf}) \cite{btf} was specified to
support these use cases. It assumes a signal processing system, where one
entity influences another entity in the system. This means an event does not
only contain the information about which system state changed, but also the
source for the change. For example, a regular system event could be the
activation of a task with the corresponding timestamp. A \gls{btf} event
additionally contains the information that the task activation was triggered by
a certain alarm.
A \gls{btf} event is defined as an octuple
\begin{equation}
\label{eq:btf_trace}
b_{k} = (t_k,\, \Psi_k,\, \psi_k,\, \iota_k,\, T_k,\, \tau_k,\, \alpha_k,\,
\nu_k),\, k \in \mathbb{N},
\end{equation}
where each element represents a certain \gls{btf} field: $t_k$ is the
\emph{timestamp}, $\Psi_k$ is the \emph{source}, $\psi_k$ is the \emph{source
instance}, $\iota_k$ is the \emph{target type}, $T_k$ is the \emph{target},
$\tau_k$ is the \emph{target instance}, $\alpha$ is the event \emph{action} and
$\nu_k$ is an optional note. A \gls{btf} trace can now be defined as
\begin{equation}
B = \{b_k | t_{k} \leq t_{k+1} \wedge k \leq n\},\, n \in \mathbb{N},
\end{equation}
where $k$ is the index of a certain event and $n$ is the number of elements in
the trace.
The timestamp field is an integer value $t_k \in \mathbb{N}_{0}$. All
timestamps within the same trace must be specified relative to a certain point
in time, which is usually the start of trace measurement. System and trace
start can occur at different points in time. Consequently, neither trace nor
system start must occur at $t = 0$. The time period between two events $b_{k}$
and $b_{k+1}$ can be calculated as $\Delta t = t_{k+1} - t_{k}$. If not
specified otherwise, the time unit for $t_k$ is nanoseconds.
A \gls{btf} event represents the notification of one entity by another. There
exist different entity types corresponding to the software and hardware objects
of an application. Each entity of a certain type has an unique name that must
not be shared by entities of other types. Certain entity types have a life
cycle. This means multiple instances of the same entity can occur within the
same trace. Instance counters are required to distinguish between different
instances of the same entity. This is important for multicore systems where an
entity can run on two processor cores in parallel.
\autoref{fig:entity_inheritance} depicts the relationship between entity type,
entity and entity instance.
\begin{figure}[]
\centering
\includegraphics[width=0.7\textwidth]{./media/btf/entity_inheritance.pdf}
\caption[\gls{btf} entity inheritance]{A \gls{btf} event represents the
impact of one entity by another. Entities have different types and multiple
entities can exist for one type, identified by an unique name. Entities that
have a life cycle, such as runnables, can be instantiated multiple times. An
instance counter is required to distinguish multiple instantiations.}
\label{fig:entity_inheritance}
\end{figure}
A basic entity type is a runnable, which is essentially a simple function. A
system may contain of multiple runnable entities called \emph{Runnable\_1},
\emph{Runnable\_2} and \emph{Runnable\_3}. The life cycle of a runnable starts
with the execution of this runnable and ends when it terminates. A runnable
can execute different actions such as calling another runnable or writing a
variable. In a multicore system the same runnable entity \emph{Runnable\_2}
may be executed by two other runnables that are running in parallel on
different cores. If \emph{Runnable\_2} writes to a variable, it is not known
from which core that write occurred. With the information about which instance
executed the write this problem is solved.
The \emph{source} and \emph{target} fields are strings that represent entities
which are part of the system. The target entity is influenced by the source
entity. \emph{Source instance} and \emph{target instance} are positive integer
values that identify the instance of the respective entity. \emph{Target type}
is the type of the target entity. Types are represented by their corresponding
type \gls{id}. A source type field is not part of a \gls{btf} event even
though it would make sense in certain cases.
The \emph{action} field indicates the way in which way one entity is influenced
by another. Depending on the source and target entity types, different actions
are possible and allowed by the specification. The last field \emph{note} is
optional even though it can be used to carry additional information for certain
events. \autoref{tab:btf_fields} summarizes the meaning of the different
\gls{btf} fields.
\begin{table}[]
\centering
\begin{tabular}{r|l}
Field & Meaning \\
\hline
time & Timestamp relative to a certain point in time. \\
source & Name of the entity that caused an event. \\
source instance & Instance number of the entity that caused an event. \\
target type & Type of the entity that is influenced by an event. \\
target & Name of the entity that is influenced by an event. \\
target instance & Instance of the entity that is influenced by an event. \\
action & The way in which target is influenced by source. \\
note & An optional field that is used for certain events. \\
\end{tabular}
\caption[\gls{btf} event fields]{A \gls{btf} event contains of eight fields.
An event describes the way in which one system entity is influenced by
another one.}
\label{tab:btf_fields}
\end{table}
A \gls{btf} trace can be persisted in a \gls{btf} trace file. This file
contains of two sections: a meta and a data section. The meta section stands
at the beginning of the file. It contains information such as \gls{btf}
version, creator of the trace file, creation date and time unit used by the
time field. Each meta attribute stands in a separate line in the form
\lstinline{#<attribute name> <attribute definition>}. The data section
contains one \gls{btf} event per line in chronological order. The first event
comes at the beginning of the data section and the last event stands at the end
of the file. Comments are denoted by a \lstinline{#} followed by a space.
\autoref{listing:btf_example} shows an example trace file.
\begin{code}
\begin{lstlisting}[caption={[An example \gls{btf} trace file]A \gls{btf} trace
file contains of two sections. A meta section at the beginning of a file
includes information such as creator, creation date and time unit. It is
followed by a data section that contains one event per line. Comments are
denoted by a number sign followed by a space.},
label={listing:btf_example}]
#version 2.1.4
#creator BTF-Writer (15.01.0.537)
#creationDate 2015-02-18T14:18:20Z
#timeScale ns
0, Sim, 0, STI, S_1MS, 0, trigger
0, S_1MS, 0, T, T_1MS_0, 0, activate
100, Core_0, 0, T, T_1MS_0, 0, start
100, T_1MS_1, 0, R, Runnable_0, 0, start
25000, T_1MS_1, 0, R, Runnable_0, 0, terminate
25100, Core_1, 0, T, T_1MS_0, 0, terminate
# | | | | | | |
# time source | | target | action
# source instance | target instance
# target type
#
# Note that a number sign followed by a space denotes
# a comment. Whitespaces in the data section are ignored.
\end{lstlisting}
\end{code}
\section{BTF Entity Types}
\begin{table}[]
\centering
\begin{tabular}{c|c c }
Category & Entity Type & Type \gls{id} \\
\hline
& Task & T \\
Software & \gls{isr} & I \\
& Runnable & R \\
\hline
& Signal & SIG \\
\gls{os} & Semaphore & SEM \\
& Event & EVENT \\
\hline
& Simulation & SIM \\
Other & Core & Core \\
& Stimulus & STI \\
\hline
& Instruction Block & IB \\
& Electronic Control Unit & ECU \\
Not discussed & Processor & Processor \\
& Memory Module & M \\
& Scheduler & SCHED \\
\end{tabular}
\caption[\gls{btf} entity types]{\gls{btf} entity types can be divided into
three categories: software, \gls{os} and other types. Entity types are
represented by their type \gls{id}. Some types are not relevant for this
thesis and are therefore not discussed.}
\label{tab:entity_overview}
\end{table}
\gls{btf} specifies the entity types that can be used for \gls{btf} events.
Each entity type can be influenced by certain other types and vice versa. The
actions or in other words, the way in which one entity can be influenced by
another, are also defined. Different actions are possible for different entity
types. Entity types can be categorized into software, \gls{os} and other
entity types.
Not all entity types specified by \gls{btf} are discussed in detail as shown in
\autoref{tab:entity_overview}. The entity type instruction block (\emph{IB})
represents a sub fraction of a runnable. This concept is used by simulation
but does not translate to a concept used by a real application.
An electronic control unit (\emph{ECU}) consist of a at least one processor
(\emph{Processor}). This concept allows it to represent a system containing of
multiple processors that communicate with each other. The recording of a multi
system aware hardware trace would required a measurement configuration with
multiple trace tools that are synchronized to each other. The design of such a
setup was not in the scope of this thesis which is why ECU and processor
entities are not discussed.
Memory modules (\emph{M}) can be used to represent different memory sections of
a CPU\@. The \gls{btf} specification does not provide further information
about memory modules. Via hardware tracing the information about which memory
sections are accessed by certain data events becomes available. Since the
specification does not provide further details about how to use memory modules,
no further discussion is possible.
The scheduler (\emph{SCHED}) entity type is used to represent actions executed
by the \gls{os} that relate to the scheduling of task and process instances.
Scheduler events become available implicitly via the respective process
actions.
\subsection{Software Entity Types}
\gls{btf} distinguishes three kinds of software entity types: tasks,
\glspl{isr} and runnables, with the respective type \glspl{id} \emph{T},
\emph{I} and \emph{R}. Tasks and \glspl{isr} are collected under the umbrella
term process. Accordingly, they share the same state and transition model as
shown in \autoref{fig:process_state_chart}.
\begin{figure}[]
\centering
\centerline{\includegraphics[width=1.3\textwidth]{./media/btf/process_state_chart.png}}
\caption[Process state figure]{\gls{btf} specifies more process states than
\gls{osek} (see \autoref{fig:extended_task_state_model}). The additional
states polling and parking are required to represent active waiting. Not
initialized and terminated indicate the beginning and end of a process
lifecycle. The green boxes between the states show the name of the \gls{btf}
action for the respective transition.}
\label{fig:process_state_chart}
\end{figure}
\textbf{Process} instances start in the \emph{not initialized} state. From
there they can be \emph{activated} in order to switch into the \emph{active}
state by a stimulus (\emph{STI}) entity. All state transitions except
\emph{activate} are executed by core (\emph{C}) entities. An active process
can be changed into the \emph{running} state by the core on which the process
is scheduled.
A running process can \emph{preempt}, \emph{terminate}, \emph{poll} and
\emph{wait}. Preemption occurs if another process is scheduled to be executed
on the core. In this case, the process can no longer be executed and changes
into the \emph{ready} state. A ready process \emph{resumes} running once the
core becomes available again. If a process has finished execution it
terminates and switches into the \emph{terminated} state. This finishes the
lifecycle of a process instance.
A process that \emph{polls} a resource switches into the active waiting state
\emph{polling}. A process that \emph{waits} for an event switches into the
passive waiting state \emph{waiting}. A \emph{waiting} process is
\emph{released} into the ready state if one of the requested events becomes
available. If a polled resource becomes available, the task continues running
which is indicated by the \emph{run} action.
A polling process that is removed from the core is \emph{parked} and switched
into the \emph{parking} state. If the polled resource becomes available while
the process is parking it is switched into the ready state. This transition is
called \emph{release\_parking}. Otherwise the process continues polling, once
it is reallocated to the core, which is called \emph{poll\_parking}.
\autoref{tab:process_overview} summarizes process state transitions.
\begin{table}[]
\centering
\begin{tabular}{c c c c}
Current state & Next state & Action & Source Entity Types\\
\hline
not initialized & active & activate & STI \\
active & running & start & C \\
ready & running & resume & C \\
running & ready & preempt & C \\
running & terminated & terminate & C \\
running & polling & poll & C \\
running & waiting & wait & C \\
waiting & ready & release & C \\
polling & running & run & C \\
polling & parking & park & C \\
parking & ready & release\_parking & C \\
parking & polling & poll\_parking & C \\
\end{tabular}
\caption[Process state table]{Process entities can be in different states. A
process instance starts in the not initialized state and finishes in the
terminate state. Each state transition has an unique action name. The
activate action can only be triggered by a stimulus entity. All other
actions can only be triggered by a core entity.}
\label{tab:process_overview}
\end{table}
In addition to state transition actions, \gls{btf} specifies process
notification actions. This actions do not trigger a process state change, but
indicate other events related to a process entity. The \emph{mtalimitexceeded}
action is triggered if more task instances than the allowed maximal value are
activated. If this happens, no new task instance is created. Therefore, a
notification event is necessary to make the event available in the trace.
All other process notification actions are related to migration, the
reallocation of a process from one core to another. \gls{osekos} does not
support process migration since a separate kernel is executed on each core.
Thus migration notifications are not relevant for an \gls{osek} compliant
\gls{os}. Additionally migration actions become available implicitly via the
respective process transition actions. If a process instance is preempted on
one core and resumed on another, the resume event will have a different source
core than the preempt event. Consequently, the related migration event is
known.
\textbf{Runnable} instances start in the not initialized state.
Runnables can be \emph{started} by \glspl{isr} and tasks in order to switch
into the \emph{running} state. A runnable that \emph{terminates} switches into
the \emph{terminated} stated and therefore finishes its lifecycle according to
\autoref{tab:runnable_overview}.
Since a runnable can only be executed from a process context it can not
continue running if the respective process is preempted. For this case the
runnable must be \emph{suspended} and switches into \emph{suspended} state.
Once the process resumes execution the runnable can also \emph{resume}.
\begin{table}[]
\centering
\begin{tabular}{c c c c}
Current state & Next state & Action & Source Entity Types\\
\hline
not initialized & running & start & T, I \\
running & terminated & terminate & T, I \\
running & suspended & suspend & T, I \\
suspended & running & resume & T, I \\
\end{tabular}
\caption[Runnable state table]{All runnable actions can be triggered by task
and \gls{isr} entity types. A runnable lifecycle starts when the runnable
first starts execution and ends when the runnable is terminated. A runnable
is suspended and resumed depending on the process context in which it is
executed.}
\label{tab:runnable_overview}
\end{table}
\subsection{OS Entity Types}
\begin{table}[]
\centering
\begin{tabular}{c c c}
Action & Source Entity Types \\
\hline
read & P \\
write & P, STI \\
\end{tabular}
\caption[Signal actions]{Signals can be read or written. For a write event
the new value is provided via the note field.}
\label{tab:signal_overview}
\end{table}
\gls{os} event types are categorized into signal, semaphore and event types.
Signals are identified by \emph{SIG}, semaphores by \emph{SEM} and events by
\emph{EVENT}.
\textbf{Signal} entities represent variables that are relevant for the analysis
of an application. There are only two signal actions: \emph{read} and
\emph{write} as shown in \autoref{tab:signal_overview}. A signal can be read
by a process entity. This means that the value of a variable is retrieved from
memory. A signal entity does not have a lifecycle, thus the instance counter
value for signals can remain constant.
Write actions can be executed by process and stimulus entities. A write action
means that a new value is assigned to a variable. If this assignment is done
from process context, the respective process entity is the source for the write
event. Otherwise a stimulus entity can be used to represent the source, for
example if a signal is changed by the \gls{os} or a hardware module.
For signal writes, the \gls{btf} note field must be used to denote the value
that was assigned to a variable, usually represented by an integer value in
decimal representation. However, \gls{btf} does not specify in which form the
value must be provided. For read events the note field can optionally be used
to indicate the value of the variable that was accessed.
\textbf{Semaphores} can be used to control access to a common resource in
parallel systems. The basic idea is that a process can request a semaphore,
before it enters a critical section, for example a section that contains access
to shared variables. If the semaphore is free, the request is accepted and the
semaphore will be locked. All requests to a locked semaphore fail, thus no
other process can access the shared variables. When the process leaves the
critical section, it releases the semaphore, which then becomes free for other
resources.
There exist different types of semaphores. A counting semaphore may be
requested multiple times. Every time a counting semaphore is requested, a
counter is incremented and every time a counting semaphore is released, the
same counter is decremented. A counting semaphore is locked once the counter
has reached a predefined value and the initial counter value is zero.
\begin{table}[]
\centering
\begin{tabular}{r l}
Action & Meaning \\
\hline
requestsemaphore & Process requests a semaphore \\
exclusivesemaphore & Process requests a semaphore exclusively \\
assigned & Process is assigned as the owner of a semaphore \\
waiting & Process is assigned as waiting to a locked semaphore\\
released & Assignment from process to semaphore is removed \\
increment & Semaphore counter is incremented \\
decrement & Semaphore counter is decremented \\
\end{tabular}
\caption[Semaphore process actions]{Processes can interact with semaphores
in different ways. If a process requests a semaphore successfully, it is
assigned to the semaphore and the counter is incremented, otherwise a waiting
event is triggered. Once a semaphore is released, the assignment is removed
and the counter is decremented.}
\label{tab:semaphore_process}
\end{table}
A binary semaphore is a specialization of a counting semaphore for which the
maximum counter value is one. A mutex is a binary semaphore that supports an
ownership concept. This means a mutex knows all processes that may request it.
This information allows the implementation of priority ceiling protocols in
order to avoid deadlocks and priority inversion. The \gls{osek} term for mutex
is \emph{resource} as described in \autoref{subsection:osek_architecture}.
\gls{btf} semaphore events can be used to represent the different semaphore
types mentioned above. Semaphore actions can be divided into two categories:
Actions triggered by process instances as shown in
\autoref{tab:semaphore_process} and actions executed by a semaphore entity
itself.
A process request to a semaphore is indicated by \emph{requestsemaphore}. If a
request is successful (the semaphore is not locked), the semaphore counter is
\emph{incremented} and the process is \emph{assigned} to the semaphore. The
\emph{exclusivesemaphore} action represents a semaphore request that only
succeeds, if the semaphore is currently not requested by any other process,
i.e.\ the counter value is zero. If a process fails to request a semaphore and
switches into polling mode, in order to wait for this semaphore, this is
indicated by the \emph{waiting} action. A process that releases a semaphore
\emph{decrements} the semaphore counter and the respective semaphore is
\emph{released}, the process is no longer assigned to it.
\begin{figure}[]
\centering
\centerline{\includegraphics[width=1.2\textwidth]{./media/btf/semaphore_state_chart.png}}
\caption[Semaphore states and actions]{Semaphore entities do not have a
lifecycle. Nevertheless, they must be initialized before they are ready for
the first time. A semaphore can be unlocked or locked. A counting semaphore
can be requested multiple times in which cases it changes into the used state.
If there are no requests the semaphore is free. A semaphore that has at least
as many requests as allowed if full and changes into the locked state.
Further requests in the locked stated result in an overfull action.}
\label{fig:semaphore_state_chart}
\end{figure}
Semaphores do not have a lifecycle, which is why their instant counter remains
constant. Nevertheless, a semaphore must be moved from the \emph{not
initialized} to the \emph{free} state by the \emph{ready} action before it is
requested for the first time as shown in figure
\autoref{fig:semaphore_state_chart}.
A free semaphore is not requested by any processes. Once it is requested for
the first time, the behavior is dependent on the semaphore type. A mutex or
binary semaphore is \emph{locked} and moved into the \emph{full} state. A
counting semaphored is changed into the \emph{used} state which is indicated by
the \emph{used} action. The used action is repeated for a counting semaphore
for each further request and release of the semaphore, as long as the counter
value stays greater than zero and smaller than the maximum value. If the
counter value of a used semaphore becomes zero this semaphore is \emph{freed}.
If the maximum counter value is reached the semaphore state becomes \emph{full}
which is indicated by the \emph{lock\_used} action.
When a full binary semaphore or mutex is released, it is \emph{unlocked} and
becomes free again, while a counting semaphore is changed back to the used
state, indicated by the \emph{unlock\_full} action. A request to a full
semaphore entity results in an \emph{overfull} action and the state is changed
to \emph{overfull}. The overfull state indicates that there is at least one
process polling a semaphore. Each additional request also results in an
overfull action. Once there are no more processes waiting for a semaphore,
this semaphore becomes full again which is indicated by the \emph{full} action.
\autoref{tab:semaphore_semaphore} summarizes semaphore states and their
meaning.
\begin{table}[]
\centering
\begin{tabular}{r|l}
State & Meaning \\
\hline
not initialized & Semaphore is not ready \\
free & No process is assigned to the semaphore \\
used & At least one process is assigned \\
full & Maximum number of processes are assigned \\
overfull & Semaphore is full and there are further requests \\
\end{tabular}
\caption[Semaphore state overview]{Semaphores can be in five different
states. Before a semaphore entity can be used, it must be moved into the
free state. No process is assigned to a free semaphore. A counting
semaphore that has not yet reached its maximum request value, is in used
state. Once no further requests are accepted, a semaphore is full. A full
semaphore that is requested by another process is said to be overfull.}
\label{tab:semaphore_semaphore}
\end{table}
\textbf{Events} are objects used for inter process communication, provided by
the \gls{os}. One process can use an event to notify another one, for example
when a computation finishes or a resource becomes available. Consequently, the
source entity for an event action must be a task or \gls{isr}. Event entities
do not have a lifecycle, therefore, no instance counter value is required.
There exist three event actions: \emph{wait\_event}, \emph{clear\_event} and
\emph{set\_event}. A process, that waits for an event, changes into passive
waiting mode, until the respective event is set. An event can be set by
another process. For the \emph{set\_event} action it is necessary to specify
for which process entity the respective event is set. This information is
provided via the \gls{btf} note field. An event can be cleared by the process
for which the event was set.
\subsection{Other Entity Types}
There are three other entity types: simulation, core and stimulus entities.
The type \gls{id} for simulation is \emph{SIM}, for core \emph{C} and for
stimulus \emph{STI}.
\textbf{Stimul} are used to depict application behavior that cannot be
represented by other entity types. The only stimulus action is \emph{trigger}.
A stimulus can be triggered by process and simulation entities, Once a
stimulus is triggered, it can be used for the actual event, i.e.\ the
activation of a task instance. Multiple stimulus instances can exist in a
system at a certain point in time. Thus the instance counter field must be
used for stimulus events.
\begin{table}[]
\centering
\begin{tabular}{r|l}
Action & Meaning \\
\hline
finalize & Initialization of system environment completed \\
error & An error record during trace recording \\
tag & Transmit meta information about the source entity \\
description & Provide a description for the source entity \\
\end{tabular}
\caption[Simulation actions]{The simulation entity can be used to provide
meta information about the trace environment. Simulation is misleading since
it must also be used in a \gls{btf} trace recorded on hardware. That is why
the term \emph{system} is more appropriate. The system entity can be used to
trigger stimulus instances. For tag and description events the note field
is used to provide meta information.}
\label{tab:simulation_actions}
\end{table}
\textbf{Simulation} entities are used to provide meta information in a
simulated \gls{btf} trace as shown in \autoref{tab:simulation_actions}.
Nevertheless, it can, and must, also be used in a hardware trace. For example,
a stimulus entity that activates a task can be triggered by a process or
simulation entity. In the first case, the resulting \gls{btf} events represent
an inter-process activation. However, in the case that a process gets
activated by an alarm, process is not the correct source type and simulation
must be used instead. Since a simulation entity does not make too much sense
in a hardware trace, \emph{system} is a more appropriate term to denote the
concept represented by the simulation entity type.
\textbf{Core} entities are used to provide an execution context for process
entities. Only one process can be allocated to a core at the same time. Core
entities do not have a lifecycle.