\section{System Trace} \label{chapter:btf} A trace is defined as a sequence of events. Events depict a change in the state of a system and can be represented on different levels of abstraction. These are discussed in more detail in \autoref{section:trace_measurement}. For the timing analysis of embedded multi-core real-time systems a trace on system level is required. Tools that analyze or visualize traces must be able to interpret the recorded events. For example, the software that interacts with hardware trace devices must be able to understand the hardware events that are generated on-chip. Otherwise it is not possible to transform the hardware events into higher level software events. For that reason a well-defined format for events is required for further processing of recorded traces. Depending on the goal pursued with a trace measurement, one level of abstraction can be more appropriate than another. On the one hand, a software engineer who implements a feedback control system is mainly interested in the functions and variables that correspond to that particular task. A system engineer on the other hand, who integrates a variety of different modules into a single application, is not interested in the details of each individual module. Instead the functionality of the system as a whole is of interest. \subsection{BTF Specification} A trace on system level can be used to analyze timing, performance, and reliability of an embedded system. \glsdesc{btf} (\gls{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 which system state changes but also the source of that change. For example, an observed event on system level could be the activation of a task with the corresponding timestamp. Then a \gls{btf} event additionally contains the information that the task activation was triggered by a certain alarm. Let $k$ be an index in $\mathbb{N}_{0}$ denoting an individual event occurrence then a \gls{btf} event can be 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) \end{equation} where each element maps to a \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 \emph{note}. A \gls{btf} trace can then be defined as a sequence of \gls{btf} events where $n \in \mathbb{N}_{0}$ is the number of events in the trace: \begin{equation} B = (b_1, b_2, \dots, b_n) \end{equation} \begin{table}[] \centering \begin{tabular}{r|l} Field & Meaning \\ \hline time $(t)$ & Timestamp relative to a certain point in time. \\ source $(\Psi)$ & Entity that caused an event. \\ source instance $(\psi)$ & Entity instance that caused an event. \\ target type $(\iota)$ & Type of the entity that is influenced by an event. \\ target $(T)$ & Entity that is influenced by an event. \\ target instance $(\tau)$ & Entity instance that is influenced by an event. \\ action $(\alpha)$ & The way in which target is influenced by source. \\ note $(\nu)$ & An optional field that is used for certain events. \\ \end{tabular} \caption[\gls{btf} event fields]{A \gls{btf} event consists 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} event can be represented textually as a comma-separated list where each field maps to an element as shown in the following listing. \vspace{1cm} \begin{lstlisting} 12891, TASK_200MS, 3, SIG, EngineSpeed, 0, write, 42 \end{lstlisting} \vspace{1cm} The first field (\lstinline{12891}) represents the timestamp of the event. A \gls{btf} trace contains the chronological order of events that occurred in a system. Therefore, for each timestamp $t_k \in \mathbb{N}_{0}$ in a trace it holds that $t_{k} \leq t_{k+1}$. All timestamps within the same trace must be specified relative to a certain point in time, that can be chosen arbitrarily. Hence, neither trace nor system start must occur at $t_0 = 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 unit for time is nanoseconds. A \gls{btf} event represents the notification of one entity by another. Each entity has an unique name. In the previous example, the source entity $\Psi$ has the name \lstinline{TASK_200MS} and the target entity $T$ is called \lstinline{EngineSpeed}. The fourth field \lstinline{SIG} is the short representation of the target entity type $\iota$. \autoref{tab:entity_overview} gives an overview of all entity types and their corresponding short \glspl{id}. Entity types are discussed in more detail in \autoref{subsection:btf_entity_types}. In this example, the target entity \lstinline{EngineSpeed} is a signal. The source entity type is not part of a \gls{btf} event. Some entities, tasks, \glspl{isr}, runnables, and stimuli have a lifecycle. This means at a certain point in time an entity becomes active in the system and eventually it leaves the system. For example, the lifecycle of a task starts with its activation and ends when it terminates. If \glspl{mta} are allowed for an application, it is possible that multiple \emph{instances} of a task are active at the same time. For those cases where multiple instances of an entity are currently active, it is consequently not clear to which instance of the entity the event refers. Instance counter fields $\psi$ and $\tau$ are used to distinguish between multiple instances of the same entity. The counters are integer values $\psi, \tau \in \mathbb{N}_{0}$ that are incremented for each new entity becoming active in the system. The first instance of an entity gets the counter value $0$. \lstinline{TASK_200MS} has an instance counter value of \lstinline{3} which means the event refers to the fourth instance of this entity. For entities that do not have a lifecycle like signals, the counter field is not relevant and $0$ can be used as a placeholder value. The seventh field $\alpha$ represents the way in which the target entity is influenced by the source entity. In this example \lstinline{TASK_200MS} writes a new value to the signal entity \lstinline{EngineSpeed}. Depending on source and target entity type, different actions are allowed by the specification as discussed in \autoref{subsection:btf_actions}. For signal write events the note field $\nu$ is used to denote the value that is written to the signal in this case \lstinline{42}. The note field is only required for certain events. \autoref{tab:btf_fields} summarizes the meaning of the different \gls{btf} fields. A \gls{btf} trace can be persisted in a \gls{btf} trace file. This file contains two parts: a meta and a data section. The meta section is written at the beginning of the file. It contains general information on the trace such as \gls{btf} version, creator of the trace file, creation date, and time unit used by the time field. Each meta attribute uses a separate line, starting with a \lstinline{#}, followed by the attribute name, a space, and the attribute definition. \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 \end{lstlisting} \end{code} In the data section one \gls{btf} event is written per line in chronological order. The first event of a trace is located directly after the meta section and the last event 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. \subsection{BTF Entity Types} \label{subsection:btf_entity_types} As shown in \autoref{tab:entity_overview} \gls{btf} specifies fourteen entity types that can be classified into five categories: environment, software, hardware, operating system, and information. Some entity types are not relevant for this thesis and therefore only discussed briefly. The actions or in other words the way in which one entity can be influenced by another are defined for each entity type as discussed in \autoref{subsection:btf_actions}. Actions for types that are classified as not relevant are not considered. \begin{table}[] \centering \begin{tabular}{c|c c c} Category & Entity Type & Type \gls{id} & Relevant \\ \hline Environment & Stimulus & STI & X \\ \hline & Task & T & X \\ Software & \gls{isr} & I & X \\ & Runnable & R & X \\ & Instruction Block & IB & \\ \hline & Electronic Control Unit & ECU & \\ Hardware & Processor & Processor & \\ & Core & C & X \\ & Memory Module & M & \\ \hline & Scheduler & SCHED & \\ Operating System & Signal & SIG & X \\ & Semaphore & SEM & X \\ & Event & EVENT & X \\ \hline Information & Simulation & SIM & X \\ \end{tabular} \caption[\gls{btf} entity types]{\gls{btf} entity types can be divided into five categories. Types that are relevant in the context of this thesis are marked by an X.} \label{tab:entity_overview} \end{table} \textbf{Environment} contains only the stimulus entity type. Stimuli are used to depict application behavior that cannot be represented by other entity types. A stimulus can be used to activate a task or \gls{isr} and to set a signal value. Multiple stimulus instances can exist in a system at a certain point in time. Thus, the instance counter field is required for stimulus entities. \textbf{Software} contains the task, \gls{isr}, runnable, and instruction block types. Tasks and \glspl{isr} summarized by the term process are containers for application software and discussed in \autoref{section:osekvdxos}. Runnable is a term established by \gls{autosar} and relates to the concept of C type functions. A runnable can be executed from the context of processes and contains application specific functionality. Multiple runnables can be active in a system at the same time for example, if the same runnable is executed by two different tasks allocated to distinct cores. Hence, an instance counter is required for runnable entities. Instruction blocks are used to represent execution time within the context of runnables. Since these execution times become available implicitly via the corresponding runnable events, the addition of instruction blocks to a \gls{btf} trace is optional and does not provide any immediate benefits. \textbf{Hardware} contains the electronic control unit (ECU), processor, core, and memory module types. An ECU consists of one or more processors. This allows it to represent a multi-processor system. Generally, tracing only supports the recording of a single processor. Multi-processor setups require a way to synchronize the measurement between multiple trace measurement tools. The design of such a setup is not in the scope of this thesis. A processor is composed of one or more cores and recording multiple cores on the same chip is feasible via tracing. Cores are necessary to map software and \gls{os} events to the corresponding hardware entities. Since this information is important for the analysis of embedded systems, cores are relevant for this thesis. Memory modules model different memory sections on a chip. They allow it to represent memory related processes on the CPU such as access times to variables or cache misses. According to Helm \cite{christianmaster}, direct measurement of memory access times is not possible. Instead, dedicated code must be added to the application in order to determine the execution times for different memory access operations. Due to the intrusiveness of this approach it is not feasible for real applications. Therefore, memory modules are not supported in this thesis. \textbf{Operating System} covers scheduler, signal, semaphore, and event entity types. The scheduler entity type is used to represent actions executed by the \gls{os} that relate to the scheduling of process instances. Scheduler events become available implicitly via the respective process actions and are thus not considered in this thesis. Signals represent access to variables that are relevant for the analysis of an application. Consequently, signal events must be added to a \gls{btf} trace that is recorded from hardware. Semaphores entities are used to control access to common resources in parallel systems. A process can request a semaphore before it enters a critical section, e.g.\ a section that contains an access to a memory region that is vulnerable to race conditions. If the semaphore is free the request is accepted, the semaphore is locked and all subsequent requests fail. Once the process has left the critical section it releases the semaphore. Events are objects 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. Event entities do not have a lifecycle therefore, no instance counter value is required. \textbf{Information} contains only the simulation entity type. This entity type has two purposes. Firstly, it can be used to provide information about errors that occurred during trace recording. Secondly, it is required to trigger stimulus events. Since stimulus events are mandatory to represent task activations by non process objects, the simulation entity must be considered in the context of this thesis. Because \emph{simulation} does not make sense in a trace recorded from hardware \emph{system} can be used as a more appropriate term. \subsection{BTF Actions} \label{subsection:btf_actions} \gls{btf} specifies different actions. The available actions are dependent on the source and target entity types of the respective event. \textbf{Stimuli} only support the \emph{trigger} action. A stimulus can be triggered by process and simulation entities. Once a stimulus is triggered it can be used for the actual event: the activation of a task or \gls{isr} or to set the value of a signal. \begin{figure}[] \centering \centerline{\includegraphics[width=\textwidth]{./media/btf/process_state_chart.png}} \caption[Process state figure]{\gls{btf} \cite{btf} specifies more process states than \gls{osek} (compare \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} entities support the actions shown in \autoref{fig:process_state_chart}. A process instance starts in the \emph{not initialized} state. From there it can be \emph{activated} in order to switch into the \emph{active} state by a stimulus entity. All state transitions except \emph{activate} are executed by core entities. An active process is changed into the \emph{running} state as soon as it is scheduled by the \gls{os}. 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 current process changes into the \emph{ready} state. A ready process \emph{resumes} running once the core becomes available again. If a process finishes execution it \emph{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}. If the resource becomes available, the process continues running which is indicated by the \emph{run} action. 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. A polling process that is removed from the core is \emph{parked} and switched into the \emph{parking} state. If the 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}. In addition to state transition actions, \gls{btf} specifies process notification actions. These 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 process instances than allowed are activated in parallel. If this happens, no new task instance is created. Therefore, a notification event is necessary to make the event visible 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 has a different source core than the preempt event. Consequently, the related migration event is known. \begin{figure}[] \centering \centerline{\includegraphics[width=0.8\textwidth]{./media/btf/runnable_state_chart.png}} \caption[Runnable state figure]{\gls{btf} runnable states and state transitions \cite{btf}.} \label{fig:runnable_state_chart} \end{figure} \textbf{Runnable} instances start in the \emph{not initialized} state as shown in \autoref{fig:runnable_state_chart}. Runnables can be \emph{started} by \glspl{isr} and tasks in order to switch into the \emph{running} state. A runnable instance that \emph{terminates} switches into the \emph{terminated} stated and therefore finishes its lifecycle. Because a runnable can only be executed from process context, it can not continue running if the respective process is preempted. In this case the runnable must be \emph{suspended}. Once the process resumes execution the runnable can also \emph{resume}. \textbf{Core} entities are used to provide an execution context for process entities and cannot be used as a target entity themselves. Consequently, no \gls{btf} core actions are specified. Only one process can be allocated to a core at the same time and core entities do not have a lifecycle. \textbf{Signal} entities can be influenced by two actions: \emph{read} and \emph{write}. A signal can be read within the context of 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. They indicate 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 note field must denote the value that was assigned to a variable. For read events the note field can optionally indicate the value of the variable that was accessed. \textbf{Semaphores} can be categorized into different types. Counting se\-ma\-phores can be requested multiple times. They have an initial counter value of zero. For every request, this counter is incremented and every time it is released the value is decremented. A counting semaphore is locked once the counter has reached a predefined value. 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}, resources are discussed in \autoref{subsection:osek_architecture}. \gls{btf} semaphore events can represent all mentioned semaphore types. 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 as shown in \autoref{fig:semaphore_state_chart}. \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 \emph{assigned} to the semaphore and the counter is \emph{incremented}, otherwise a \emph{waiting} event is triggered. Once a semaphore is \emph{released}, the assignment is removed and the counter is \emph{decremented}.} \label{tab:semaphore_process} \end{table} \begin{figure}[] \centering \centerline{\includegraphics[width=\textwidth]{./media/btf/semaphore_state_chart.png}} \caption[Semaphore states and actions]{\gls{btf} \cite{btf} semaphore entities do not have a lifecycle. Nevertheless, they must be \emph{initialized} before they are ready for the first time. A semaphore can be \emph{unlocked} or \emph{locked}. A counting semaphore can be requested multiple times in which case it changes into the \emph{used} state. If there are no requests the semaphore is \emph{free}. A semaphore that has at least as many requests as allowed is \emph{full} and changes into the \emph{locked} state. Further requests in the locked stated result in an \emph{overfull} action.} \label{fig:semaphore_state_chart} \end{figure} A process request to a semaphore is indicated by \emph{requestsemaphore}. If a request is successful 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, 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. 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. A free semaphore is not requested by any process. At the first request 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 or release 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 \emph{full} again. \textbf{Events} can be influenced by three different actions. If a process starts waiting for an event, this is indicated by the \emph{wait\_event} action. Another process can set an event via the \emph{set\_event} action. For this action it is necessary to provide the entity for which the event is set via the \gls{btf} note field. An event can be cleared by the process for which the event was set which is indicated by \emph{clear\_event}.