Etienne Hamelin

Mihail Asavoae

Selma Azaiez

Alexandre Berne

Cyril Faure

Kods Trabelsi

Multilayer Monitoring for Real-Time Applications

Validation of timing requirements of multicore, heterogenous and distributed systems is difficult problem because of a large number of situations that introduce temporal variability and/or interference. A possible solution is to augment the system with monitors and to rely on runtime monitoring techniques. In this paper we propose such a runtime monitoring which spans all the semantics layers of a model-based design, from highlevel specification to executable code. We showcase our runtime monitoring on a safety-critical application for driving assistance.

I. INTRODUCTION

Runtime monitoring is a lightweight verification technique for detecting property violations in embedded safety-critical systems. A typical runtime verification workflow consists of the definition, the synthesis and the execution of a collection of monitors which observe concrete executions of the system and check their conformance with respect to a set of stipulated properties. The observation aspect requires either a form of instrumentation (e.g. the code is made available) or external annotations (e.g. only black-box / COTS components are provided). The conformance checking aspect usually refers to property violations, or stated differently, to deviations from expected correct runtime behaviors. The design and implementation of a runtime monitoring environment needs to address these aspects as well as the characteristics of the embedded safety-critical system under consideration. In the following we propose a versatile runtime monitoring, which we denote as multilayer runtime monitoring and which combines high-level design details with low-level implementation particularities (of both application and execution platform).

We consider a model-based design (MBD) methodology for embedded software, adapted to address complex designs and to respond to complex and precise requirements. A prime example of such a methodology is based on the synchronous dataflow principle, with well-established workflows from Lustre/SCADE [START_REF] Colac ¸o | SCADE6: A Formal Language for Embedded Critical Software Development[END_REF] or Simulink [START_REF] Dabney | Mastering Simulink[END_REF]. A MBD exposes several programming languages: the (just enumerated) highlevel languages, intermediate languages like C and finally, lowlevel languages (e.g. assembly or binary code). In this case a multilayer runtime monitoring mimics the MBD languages, with monitors being placed at each level and an existing simulation/execution environment, likewise available. We also consider a distributed execution platform, which is suitable to map mixed-critical applications.

This research was partially supported by the ECSEL-JU under the program ECSEL-Innovation Actions-2018 (ECSEL-IA) for research project CPS4EU (ID-826276) in the area Cyber-Physical Systems.

In this paper we exemplify our multilayer runtime monitoring, driven by the non-functional requirements of a safetycritical application from the automotive domain. More specifically, in this paper we address timing properties. The MBD workflow starts with a high-level Polygraph design [START_REF] Dubrulle | A Data Flow Model with Frequency Arithmetic[END_REF], a specialized dataflow-like language, which is further compiled and deployed on a distributed architecture. In this setting, the design of a multilayer runtime monitoring needs to address a certain number of challenges, presented in Section II. Moreover, details of the underlying MBD are in Section III, a high-level presentation of the multilayer runtime monitoring, in Section IV and the proposed case study, in Section V.

II. CHALLENGES

One of the main challenges in designing and analyzing safety-critical applications running on complex computational systems (e.g. heterogeneous, distributed or even virtualized [START_REF] Hamelin | Selection and evaluation of an embedded hypervisor: Application to an automotive platform[END_REF]) lies in the computation and communication timing variability of the application's components. This variability is due to various factors, among which we enumerate:

• task-specific behavior:

data-dependent (e.g. a task may chose a different behavior mode)

• inter-task interference due to shared software resources:

operating system-managed resources (e.g. scheduling, peripherals etc.), exclusive services (e.g. drivers, communication protocols stacks, synchronization primitives, etc.)

• inter-task interference due to shared hardware resources:

shared CPU cores, shared caches etc., shared communication buses, shared peripherals, etc. Static timing analyzers like aiT [1], or Otawa [START_REF] Ballabriga | OTAWA: An Open Toolbox for Adaptive WCET Analysis[END_REF] compute safe bounds on the worst-case execution time of an application (i.e. behaviour-related timing variability). Another source of timing variability is due to interference between tasks; different techniques (e.g. static, statistical etc.) are developed to compute the necessary bounds on the timing behavior. To address interferences, static timing analyzers are extended with specialized shared cache analyses or cache-related preemption delay analyses.

Static and dynamic analyses are used to accurately capture the timing variability, whereas online monitoring is how the system identifies and addresses the deviations from specified/validated timing values.

• static analysis is performed on the control-flow graph of the source or binary code,

• dynamic analysis is performed on traces extracted from concrete executions on the actual architecture, on an emulated target etc., • online monitoring is performed, at runtime, on the embedded target

The list of challenges, while non-exhaustive, is sufficient to expose the potential complexity arising when the timing variability is analyzed. One of the objectives of our multilayer runtime monitoring is to provide the necessary support, in the form of monitors, at various levels in this system representation (e.g. from high-level design to hardware).

III. DESCRIPTION OF THE APPROACH

An overview of our approach is presented in Figure 1, adhering to a MBD workflow for dataflow designs. A use case defines the application and a dataflow model, in Polygraph, defines the correct behavior of the system. From the Polygraph model, through a dataflow compilation, we generate elements of the source code, in C (i.e. a scheduler) which are then integrated with other elements of the source code (e.g. userwritten code, libraries, RTOS APIs etc.), and finally compiled into a binary. When deploying and running such binaries on target boards, we obtain the execution traces which are then analysed by a processing engine. The goal is to check their conformance with respect to the correct timing, as defined in the high-level specification [START_REF] Kirner | Fully Automatic Worst-Case Execution Time Analysis for Matlab/Simulink Models[END_REF]. The first required step for analyzing the timing behaviour of our distributed application is to define accurately what is a "correct" behaviour for this application. To this end, we use the Polygraph model of computation and communication, presented in [START_REF] Dubrulle | A Data Flow Model with Frequency Arithmetic[END_REF]. Polygraph is a real-time dataflow paradigm that extends the multi-rate synchronous dataflow approach.

The Polygraph model defines a complex set of causal relationships between actor/task firings, message tokens, and time instants. From a Polygraph model verified as both consistent and live, we generate elements of source code, which are linked with other user-provided code files and the instrumentation, and finally compiled into a set of binary firmware. When running these firmware programs on a heterogeneous platform made of single-or multicore targets, we monitor and analyze the execution traces generated from the instrumented programs.

In a MBD workflow, as in Figure 1, the semantics of the initial use case is successively transformed. First, the use case is formalized in the dataflow design (i.e. a highlevel application semantics), then the C code is generated (i.e. an intermediate-level application semantics) and finally, it is compiled into the binary (i.e. a low-level application semantics). In order to preserve accurate traceability between the C code and the generated binary, the compilation is usually performed without optimizations. However, a coarser traceability could be preserved in the presence of compilation optimizations, so as to relate the high-level events to lowlevel functionalities (e.g. at function-level). In this work we consider compiler optimizations, however, regardless of the optimized/un-optimized compilation, it remains the fact that the use case semantics is obfuscated by this chain of transformations and, at the binary level, the use case characteristics (structural and functional) are difficult to identify and reason about. This motivates a runtime monitoring which should preserve some traceability features of the MBD compilation chain. Obviously, such a multilayered runtime monitoring implies the existence of execution environments at each level in the MBD workflow.

IV. MONITORING SYSTEM

In the following, we briefly present some design decisions behind our multilayer runtime monitoring. We distinguish three levels of interest, starting with a dataflow Polygraph design and ending at the hardware hardware level and we organize this section as such.

A. Application level monitoring

The timing properties derived from the Polygraph design are used by the code generator to instantiate a set of software monitors. Here, we rely on the traceability of dataflow compilation chains. These monitors are inserted into the generated C code; each monitor is dedicated to observe a specific set of events, and related causal or temporal properties (as specified in the dataflow design). Then, these monitors output a trace of timestamped events for further conformance checking with respect to an expected behavior. As previously mentioned, the conformance checking could be of static or statistical nature.

B. Binary level monitoring

In case of safety-critical applications (i.e. requiring safe and tight timing bounds), timing analysis should be addressed in worst-case scenarios. There are two types of worst-case timing analysis: based on static analysis and on measurements. In the measurement-based approach, the binary is actually executed on the architecture or in a simulation environment and the results are interpreted with respect to a set of requirements. The instrumentation is necessary in this case to ensure that the collected executions are representative for the input application. In the context of runtime execution, and thus, in the presence of a monitoring system, the measurement-based timing analysis seems to be the obvious choice. The code is instrumented at meaningful program points (actor job start, job end, message send/receive) so that runtime observations are possible whenever the code execution passes these points.

The binary instrumentation could and should be coupled with the non-intrusive hardware performance monitoring, which is detailed next.

C. Architecture level monitoring

The software-level runtime monitoring is complemented by a dedicated hardware infrastructure in the form of a Performance Monitoring Unit (PMU), available in most hardware architectures. The PMU allows recording of architectural and micro-architecture events for profiling purposes. Most modern CPU architectures contain a PMU embedded in the silicon, which provides performance counters (PMCs), a set of performance events to be counted Events such as preemptions, cache hits/misses could be tracked via the PMU to analyze the execution time of the system under test [START_REF] Bircher | Complete System Power Estimation Using Processor Performance Events[END_REF], [START_REF] Rodrigues | A Study on the Use of Performance Counters to Estimate Power in Microprocessors[END_REF]. Several commercial tools like ARM Streamline gator kernel module and daemon [2] are available to leverage PMUs in order to provide real-time feedback to engineers and help them to diagnose bugs or identify bottlenecks in software.

V. CASE-STUDY AND EXPERIMENTATION

We showcase our approach by setting up a practical prototype platform, which embeds the monitoring layers described above into a use-case implemented as a Polygraph design.

In Figure 2, we present our use-case. This application is representative of the kind of real-time computing loads associated with advanced driver assistance systems (ADAS): the Camera actor generates image frames at a fixed rate e.g. 15 frames per second. These frames are analyzed by two mostly independent sub-chains. On one hand, lanes are detected on every frame using classic computer vision algorithms, and illustrates a time-critical chain. On the other hand Objects detection is performed using a deep neural network, and processes only a subsampled set of the input frames, in a soft real-time way. The Display sink actor serves as visual output, and additionally checks for deadline misses.

A. Case study implementation

The case study was implemented on a set of two Raspberry Pi multicore embedded computers, equipped with the Linux Operating system patched with PREEMPT RT to support realtime applications, connected over Ethernet.

The RPi model 3B+ has a Broadcom BCM2835, 4-core ARMv7 processor, with 16KiB private L1 instruction, 16KiB L1 data cache, a 512KiB shared L2 cache.

Actors communicate through ZeroMQ messages using the publish/subscribe communication pattern. ZeroMQ [START_REF] Hintjens | ZeroMQ: Messaging for Many Applications[END_REF], available as both C and Python-compatible, was chosen for its performance and versatility, supporting equally well interthread, inter-process process and Ethernet-based communications, independently from actual scheduling-related configuration. In comparison the popular ROS framework, available in C++ and Python, uses by default a single event queue for scheduling callbacks in a run-to-completion manner. This makes configuration and verification of real-time properties complex (see e.g. [START_REF] Casini | Response-Time Analysis of ROS 2 Processing Chains Under Reservation-Based Scheduling[END_REF]).

Below is a simplified view of the implementation for an actor thread, where the business logic is inserted into a task and communication structure generated from the Polygraph model with inline tracing statements. The actor detailed, Perspective Warp, has a simple Polygraph specification: one input port, one output port, and no clock constraint, i.e. firings are triggered by incoming messages. The Display actor, implemented in Python, subscribes to the outputs of both lane and object detection chains, and additionally monitors the end-to-end latency of each processing sub-chain.

2) Lane detection: The image processing pipeline is inspired from the many Python implementations of Advanced Lane Detection published by participants to the popular "Self Driving Car" NanoDegree from Udacity, e.g. [START_REF] Sharma | Advanced Lane Lines Detection[END_REF].

These actors represent a hard real-time processing subchain. They are implemented in bare C, as three separate The Perspective Warp actor transforms the front view image into a bird-eye-view image, following a manuallycalibrated perspective transform, as shown in Figure 4a.

The Lane Detection actor then uses a color filter to extract lane markings, then a boxed histogram search to identify the most plausible markings (local maxima) for each lane, shown in Figure 4b.

A 2nd degree polynomial is fitted through the local maxima. The polynomial is used to extrapolate and draw curved lane besides the detected markings, shown in Figure 4c.

Finally, the Inverse Perspective actor projects the lane-marked bird-eye-view into a front view, shown in Fig- ure 4d.

3) Object detection: The Object detection actor uses a deep neural network (DNN) to detect objects such as cars, trucks or motorcycles (see 5. The network used is the SSD Mobilenet v3, pre-trained on 300x300 color images using the COCO Small dataset [START_REF] Yu | TensorFlow Model Garden[END_REF]. This network is not trained specifically for ADAS applications, but is however representative of the type of computational load typical of computer vision DNNs.

This actor is implemented in Python, and uses the Tensorflow Lite runtime. Due to its intensive CPU and memory usage, this actor only processes 1 frame per second. This actor is mapped onto the non-isolated cores.

4) Variability sources: In II, we recalled the most prominent sources of temporal variability in real-time applications. The following measures are configured so as to reduce variability to a minimum:

• data-dependent behavior is reduced to a minimum: the memory allocation is authorized only during setup, and the execution flow depends on image size but not image content. Only the Gauss-Jordan matrix inversion used in the polynomial fit step has execution flow, however this represent a small fraction of the execution time (less than 100µs); • time-critical tasks are scheduled as high-priority real-time threads • time-critical tasks are run on isolated CPU cores: the isolcpu and taskset commands prevent the OS from scheduling background services on two CPU cores dedicated to real-time tasks, and consequently ensure interference-free access to private L1 caches; • inter-task synchronization is limited to blocking on message reception, thus enforcing a correct Polygraph dataflow semantics. The execution times of the non-critical Object detection subchain on the other hand show much more variability, due to e.g.:

• data-dependent behavior: due to its black box nature, we could not inspect to what extent the TFLite runtime behavior does depend on actual image content. To the least, we observe a variable execution time, and assume that some operations depend on e.g. the number of objects detected. This task configuration is expected to reduce the risk of interference between non-critical and critical tasks. However, the shared L2 cache remains a possible source of interference, since both critical and non-critical task chains process memory chunks larger than the last-level L2 cache.

5) Monitoring infrastructure:

The monitoring infrastructure is integrated within each Python and C-based actor thread, using the low-overhead LTTNG-UST infrastructure (Linux Tracing Toolkig -New Generation, User-Space Tracing). In our configuration, LTTNG-UST tracing was tested to cost approximately 5µs per trace point, well below the time granularity of the monitored events. We monitor all Polygraph dataflow relevant events, that is: actor job start, job end, message sent, message received. Using these events, we can compute the execution times of each actor job.

In addition, the Image Source actor generates a timestamp, which is transported together with the image payload during all processing steps. This enables other actors computing the input and output latency of each actor (time of arrival of input data, and time of departure of output data, relative to original input timestamp).

The real-time, NTP synchronized, clock CLOCK_REALTIME is used to compare timestamps from distributed platforms with millisecond-level precision, whereas the monotonic clock CLOCK_MONOTONIC is used to compare timestamps inside a given platform, up to microsecond precision for e.g. actor execution times.

The event trace generated by this monitoring infrastructure, showed in Figure 6 allows to analyze the evolution in time of execution times of critical actor jobs (in µs; top section). In particular, the execution time of critical actors is relatively stable (standard deviation is below 2% of the average). The input/output latency is computed at each actor job (in ms; middle section).

In the PMU trace (lower section), we see hardware-level metrics for the Perspective warp actor. In particular, from PMU monitored metrics we compute the instruction per cycle ratio (IPC), and miss rate at private (L1) as well as shared (last level) cache. In our application, a significant variability of the miss rate at shared cache LL (stddev ≈ 12% • avg) is probably caused by interference from the non-critical, memory-intensive, Object detection actor. This variable LL miss rate would cause a variable access time for data outside L1 cache, and variable instruction per cycle (IPC). However since most data reads only hit the L1 cache (miss rate < 1%), the effect of LL cache interference is not much visible on actor execution time or the IPC metric in this run.

B. Static WCET Analysis

In order to better establish correlations between the monitoring infrastructure and the architecture timing, we have considered a cycle-accurate, WCET analysis for the Perspective Warp actor. More precisely, we consider a reference implementation of this actor which is then evaluated with Otawa static timing analyzer [START_REF] Ballabriga | OTAWA: An Open Toolbox for Adaptive WCET Analysis[END_REF] for ARM processors. Whereas specialized analyses are necessary to address shared caches or the possibility to accommodate the preemption, Otawa proposes single-core, non-preemptive analysis, hence we only directly analyze L1 cache effects. Let us elaborate next on these two aspects of the experimentation. The reference implementation of the Perspective Warp actor is characterized by the following elements. First, the input image, as shown in Figure 3 is of fixed size (i.e. 300x200 pixels) and the output image, as shown in Figure 4a is also of fixed side (i.e. 200x133 pixels). We note that both image sizes are modifiable, but we fix them as a referenced input-output, as we have previously stated. Second, the code is organized in three stages: memory allocation of all the manipulated images, followed by a perspective transformation algorithm (through a resolution of a system of linear equations) and finally, the generation of the resulted imaged. We note that our contribution (wrt. the monitoring infrastructure) is to observe the timing contribution of the memory accesses. Third, the code is stripped of auxiliary functionalities, namely calls to the ZMQ library and other tracing operations. Finally, we also addressed a highly-optimized version (-O3) of this code (as used in all the other tests). From the architecture point of view, we analyze with Otawa single-core timing, using cache analyses for L1 caches (and without considering the L2 shared cache). As such, the resulting code presents its core functionality which is then evaluated with the static timing analyzer in order to obtain a timing bound in the absence of other interferences (i.e. from ObjectDetection and Linux background services).

The Otawa timing analyzer is also highly configurable, featuring, on the architecture side, an infrastructure for ARM, RISC-V or PPC architectures (to name a few) and on the anal-ysis side, a wide range of abstractions to compute flow-facts from both the input program and the underlying architecture (e.g. standard cache may-and must-analyses). Also, Otawa proposes an advanced scripting to facilitate the extraction of loop addresses, in order to introduce loop bounds. We note that Otawa is accompanied by oRange [START_REF] De | Static Loop Bound Analysis of C Programs Based on Flow Analysis and Abstract Interpretation[END_REF] tool to compute these loop bounds, however, due to the fact that our code contains only for-loops, it is not necessary to consider oRange for these bounds. In our experimentation with the Perspective Warp actor, we consider the ARM architecture of Otawa with a simple pipeline and instruction and data caches, for which the aforementioned analyses are selected. In this setting, Otawa returns slighly more than 12 million cycles for each image processed, for a code which is dominated by memory accesses (55% instructions). This estimate is roughly three times the cycle count measured by runtime monitoring.

The Otawa analyzer only considers a 1 level cache, whereas our target features 2 cache levels; for this reason we cannot expect Otawa to provide an accurate figure. However since the L1 miss rate is low (cf. Fig. 6, consistent with Otawa analysis), the effect of 2nd level cache cannot explain the large difference. This discrepancy needs to be further investigated.

While these results are used as a baseline WCET behavior for Perspective Warp, similar investigations could be performed for the other time-critical actors of our case study.

VI. RELATED WORK

Model-based design (MBD) approaches for real-time systems consider as, for the high-level application, a design developed using synchronous languages like Lustre [START_REF] Halbwachs | A synchronous language at work: the story of Lustre[END_REF]. For this particular language (as for others in the same family), a notion of observer could be defined [START_REF] Halbwachs | Synchronous Observers and the Verification of Reactive Systems[END_REF] to address design properties. More precisely, an observer, according to [START_REF] Halbwachs | Synchronous Observers and the Verification of Reactive Systems[END_REF] is another program which observers the behavior of the original application (in Lustre) and determines eventual deviations from stipulated correct behaviors. In other words, an observer is a monitor for the high-level application and a high-level Polygraph design, as in our work, could also support such an approach.

The Polygraph formal model is also used by Alkalee, a spin-off of CEA LIST, as the base of their modeling tool Euphilia [START_REF] Euphilia | the systems modeling tool[END_REF]. Alkalee moreover provides the Receef runtime environment [START_REF]Receef, the embedded features orchestration software[END_REF], which can supervise actors' communication events according to the input system model. The Receef monitors can additionally trigger various containment strategies for communication faults, e.g. when an expected data sample is not received on time. To the best of our knowledge, the Receef monitoring infrastructure does not cover, nor interface to, low-level architectural observation points such as hardware performance counters.

In the context of the low-level application and the underlying execution platform (wrt. the same MBD workflow), a typical monitoring systems relies on hardware performance counters (HPCs) to observe the behavior of the system under analysis. As such, HPCs are used to address security properties, e.g. in [START_REF] Bourdon | Anomaly detection using hardware performance counters on a large scale deployment[END_REF], safety properties, e.g. in [START_REF] Malone | Are hardware performance counters a cost effective way for integrity checking of programs[END_REF] and nonfunctional requirements, e.g. energy [START_REF] Landry | Exploiting performance counters to predict and improve energy performance of HPC systems[END_REF] and timing [START_REF] Nowotsch | Monitoring and WCET analysis in COTS multi-core-SoC-based mixed-criticality systems[END_REF]. The key aspects in using HPCs to cover a wide range of properties are that modern processors support them and also that their overhead wrt. the runtime analysis is minimal. We also consider HPCs in our current work for the same reasons, however, we also aim to correlate the results of their measurements with different observation methods (i.e. at different semantics levels in the system design). Such correlations define our framework of multilayer monitoring for mixed-criticality systems.

The worst-case timing analysis is necessary to ensure that critical tasks in mixed-criticality systems are able to meet their timing deadlines. There are two types of timing analysisusing static-based [START_REF] Wilhelm | Static Timing Analysis for Hard Real-Time Systems[END_REF] and measurement-based [START_REF] Wenzel | Measurement-Based Timing Analysis[END_REF] methods. Our multilayer monitoring framework draws inspiration from both, as follows. The static timing analysis, when applied to MBD workflows (i.e. a survey of methods and techniques is presented in [START_REF] Asavoae | Program Semantics in Model-Based WCET Analysis: A State of the Art Perspective[END_REF]) considers the application to be represented and analyzed at each level [START_REF] Maiza | The W-SEPT Project: Towards Semantic-Aware WCET Estimation[END_REF] and aims to establish traceability properties between these levels. In the same way, our approach aims to exploit the traceability towards increasing the confidence between the observed timing behavior at the various levels. The measurement-based timing analysis uses the HPCs to estimate timing bounds of critical tasks, having problems of compositionality [START_REF] Maxim | Reproducibility and representativity: mandatory properties for the compositionality of measurement-based WCET estimation approaches[END_REF]. Another way of performing measurement-based timing analysis is by code instrumentation followed by the application of statistical and/or probabilistic methods on the collected results [3]. In the same way, our approach considers the HPCs, but with a broader goal, that of establishing (composable) connections with different levels in a MBD workflow.

VII. CONCLUSION

We explained in this document how we used a MBD methodology to define a monitoring system for a distributed execution platform in order to validate their temporal behaviour during their execution. Using a high-level dataflow language, i.e. Polygraph, the correct temporal behavior is specified. From these specifications, source code is generated or written to embed software monitors. These monitors are compiled into the application, and inserted into the application execution flow, and track dataflow-relevant events. At the binary level, two types of worst-case timing analysis are considered. For the first one, static analyses are performed on the control flow graph as a high level abstraction of the binary code. The second one a measurement-based approach where the binary is actually executed on the architecture and the results are interpreted with respect to these measurements. Finally, at the architecture level, execution is profiled using tools such as Performance Monitoring Unit (PMU). We have shown that these various monitoring layers provide complementary data, especially useful to modelling the actual execution time in presence of inter-task interference.

Fig. 1 :

 1 Fig. 1: Overview of the design flow

Listing 1 :

 1 Example actor code // actor thread void * a c t o r p e r s p e c t i v e w a r p ( void * a r g ) { // Input channel: create subscriber socket void * z i n = z m q s o c k e t ( z c t x , ZMQ SUB ) ; // connect to TCP endpoint z m q c o n n e c t ( z i n , "tcp://..." ) ; // subscribe to topic z m q s e t s o c k o p t ( z i n , ZMQ SUBSCRIBE , "frame" ) ; // Output channel: Create publisher socket z o u t = z m q s o c k e t ( z c t x , ZMQ PUB ) ; // bind to inter-process com endpoint zmq bind ( z o u t , "inproc://persp_warp" ) ; // Allocate image memory space i m g t * i m i n = img new ( . . . ) ; i m g t * i m o u t = img new ( . . . ) ; // Main loop while ( 1 ) { t r a c e j o b s t a r t ( . . . ) ; // receive (blocking) input message z m q r e c v i m a g e ( z i n , im in , . . . ) ; t r a c e t o k e n r e c e i v e d ( . . . ) ; // transform front view to bird-eye view i m g p e r s p e c t i v e w a r p ( im in , im out , . . . ) ; // send output message t r a c e t o k e n s e n d ( . . . ) ; zmq send image ( z o u t , im out , . . . ) ; t r a c e j o b e n d ( . . . ) ; } } 1) Test stubs: The ADAS camera is simulated by a Image source actor, implemented with Python and OpenCV. It periodically sends images (300x200 pixels, RGB format) extracted from a video file, shown in Figure 3.

Fig. 2 :

 2 Fig. 2: Use-case dataflow

Fig. 4 :Fig. 5 :

 45 Fig. 4: Lane detection chain: intermediate stages

Fig. 6 :

 6 Fig. 6: Execution trace analysis