Yves Bernard

Cédric Gava

Cédrik Besseyre

Bertrand Crouzet

Laurent Marliere

Pierre Moreau

Samuel Rochet

Modeling of Hardware and Software for specifying Hardware Abstraction Layers

Keywords: MBSE, System Engineering, SysML, model, Interface, hardware/software co-design

In this paper we describe a practical approach for modeling low level interfaces between software and hardware parts based on SysML operations. This method is intended to be applied for the development of drivers involved on what is classically called the "hardware abstraction layer" or the "basic software" which provide high level services for resources management on the top of a bare hardware platform. It is also an enabler for co-design processes since the design of hardware and software can be decoupled. In addition this approach is compatible with virtual prototyping technologies such as SystemC/TLM. An application to a simple a study case is provided for illustration purpose.

INTRODUCTION

For many software developers, an application is based on the services provided by an operating system and/or a middleware that fully abstracts the actual implementation of the hardware platform on which this application runs. However there is always a point, where the most basic software, the one that directly access to the hardware resource, has to be developed. Usually, the design of the high level software applications uses distinct domains and different abstractions compared with the design of hardware platforms. This cannot be the case when designing this basic software. The lowest level interface between the hardware components and the software has to be built on common concepts. There is neither middleware, nor operating system in this context. Resources are provided by bare hardware components, only described in their datasheets. Among them, there are the processors with theirs sets of instructions used by software for specifying execution flows.

Often, the industrial context on which the development is taking place is time-constrained in such a way that the design of the basic software shall generally be carried out concurrently with the design of the hardware platform. It is the so-called: "hardware/software co-design" issue.

A common practice is to organize the various components of a product according to layers of responsibilities. It enables the separation of concerns and facilitates the re-use, the maintenance and the work assignment. Concepts like: Hardware Dependent Software (HDS) and Hardware Abstraction Layer (HAL) are widely used for the development of such systems [START_REF] Domer | Introduction to Hardware-dependent Software design[END_REF].

The idea of a unified representation for both the hardware and the software, allowing a seamless approach for their development was presented in [START_REF] Bouchhima | A unified HW/SW interface model to remove discontinuities between HW and SW design[END_REF]. In [START_REF] Lefftz | A design flow for critical embedded systems[END_REF], [START_REF] Gerin | Flexible and executable hardware/software interface modeling for multiprocessor SoC design using SystemC[END_REF], [START_REF] Jerraya | Programming models and HW-SW interfaces abstraction for multi-processor SoC[END_REF] or [START_REF] Baklouti | Extending transaction level modeling for embedded software design and validation[END_REF] such models are developed for the purpose of trade-offs analysis regarding the allocation of computing tasks in the context of Systems on Chip (SoC). The hardware(HW)/software(SW) interface is abstracted in SystemC in such a way that it is easy to change the allocation of a functional task between hardware and software resources, but the modeling of HDS is not actually broached.

In [START_REF] Lefftz | A design flow for critical embedded systems[END_REF], [START_REF] Gerin | Flexible and executable hardware/software interface modeling for multiprocessor SoC design using SystemC[END_REF] and [START_REF] Muller | The SATURN Approach to SysML-Based HW/SW Codesign[END_REF], SystemC models are used in some later steps of the design process to validate the HDS, but only the HW is modeled. Indeed in these models, an Instruction Set Simulator (ISS) can execute the software, directly in its binary compiled format, almost as a real platform does. In these approaches, nothing is said about the modeling of the HDS: the topic is to debug the software as a whole.

Finally, all the methods involving the UML [START_REF] Omg | OMG Unified Modeling Language (OMG UML)[END_REF] and MARTE [START_REF] Omg | UML Profile for MARTE: Modeling and Analysis of Real-Time Systems -Version 1.1[END_REF] standards, like [START_REF] Robert | A UML design flow aimed at embedded systems[END_REF], [START_REF] Quadri | MADES: a SysML/MARTE high level methodology for real-time and embedded systems[END_REF], [START_REF] Abdallah | Modelisation UML/MARTE de SoC et analyse temporelle basee sur l'approche synchrone[END_REF] or [START_REF] Koudri | Processus MOPCOM pour SoC/SoPC[END_REF], use allocation relations to link software tasks to resources of the hardware. From the point-of-view of software, these relations enable trade-off analysis, typically: tasks scheduling or competition for shared resources. These methods assume that applications will rely on an Operating System and HDS for simplifying the access to hardware resources by abstracting the actual hardware topology and protocols. However they do not deal with the design of those essential software components.

The kind of the hardware models involved in hardware/software co-design is focused on the digital functions of an electronic circuit related by interconnection components like buses or bridges. The modeling of such architectures, which we will call "digital architecture" in this paper, has been addressed by standards such as IP-XACT [START_REF]IEEE, IEEE Standard for IP-XACT, Standard Structure for Packaging, Integrating, and Reusing IP wiwith Tool Flows[END_REF] and SystemC [START_REF]IEEE Standard for Standard SystemC Language Reference Manual[END_REF]. The IP-XACT standard is firstly designed for assembling IPs. It provides a structural description of those architectures but it does not address the behavioral aspects. The SystemC standard provides facilities for describing both the structure and the behavior of hardware architectures. Derived from the C++ programming language, SystemC is executable and, associated with an Instruction Set Simulator (ISS), it makes it possible to runs co-simulations of software on virtual hardware platforms. However, since they are focused on execution, SystemC models are not convenient to support all the aspects of a design model. It represents a possible implementation of a specification that provides the expected execution traces as long as real-time aspects remains out-of scope.

In addition, the level of details required by SystemC model makes them inappropriate for the early stages of the HDS design phase. SysML [START_REF] Omg | OMG Systems Modeling Language (OMG SysML) V1.3[END_REF] is better adapted for this purpose; this is the reason why we chose it for implementing the modeling methodology presented in the following paragraphs.

VIEWPOINTS

The hardware concepts

Each function of a digital architecture is modeled as a reusable component that can owns ports which specify connection points between the component and its environment. There are two fundamental roles of ports in these architectures: "master" ports, which can initiate a communication, and "slave" ports, which can only react to communications requests. For each port an "interface definition" is provided. It usually refers to a communication standard like PCI, Ethernet or AFDX. If the communication conveys identification (i.e. address) information along with data, then the ports conforming to this interface definition are said to be "addressable".

For each addressable slave port, a memory map can be established. It specifies how any resource can be unambiguously identified and thus read or written at that port through an addressable master port.

Digital architectures assemble two kinds of components:

 Functional components like: data storages, processors or input/output devices which provide the resources used by the software applications  Interconnection components, like "bridges" and "buses" which provide the communication channel allowing all the functional components working together as a whole (i.e. the so-called "platform"). In general, the word "bus" is used for interconnection components which have ports of the same interface definition, whereas "bridges" is used for those having ports of different interface definitions 1 .

"Transparent" interconnections can map storage elements in slave's memory maps into masters address spaces whereas "opaque" do not .When more than one resource is published at a slave port, their precise locations are characterized by offset values which are used in address resolution. We call "address resolution" of an element E S owned by the memory map MM S of a slave port S, the computation of an address integer value A ES-M in a master's address space AS M of a master port M. This computation mainly depends on the offset O ES-S of E S in the memory map MM S and on the offsets O Mi1 of the traversed master port between M and S.

Figure 1: Master and slaves ports organization of a data bus

A processor has at least a master port for connecting it to the rest of the platform. The software executed by the processor typically uses read or write instructions (e.g. the "MOV" data movement instructions in assembly language) for accessing a particular storage resource. The address used to specify the location of this resource refers to the processor's master port address space, and is defined according to the address resolution mechanism.

The software concepts

By "software" people usually refers to a sequence of instructions allowing a processor to perform the functions of an application. By extension it may refer to a binary file, which will be effectively fetched by the processor for these instructions or to the source code as well. Nevertheless it is only through interactions with hardware resources that the software will be able to realize the expected functions.

In the commonly used programming languages, the description of software resources is based on the concepts of "variable" and "function" (or "subprogram"). The former specifies a storage resource (e.g. for data) while the latter defines a reusable piece of code intended to provide a specific service. The result generated by the execution of this service may depend on the values of one or more parameters, which are a special kind of variables.

Software modules are consistent sets of functions and variables. Interactions between software modules are based on the services they are able to provide, i.e. on the functions they make available to other software modules. An operation characterizes a service that can be requested. This is the main concept used for specifying software interfaces. The concept of "call" is used to designate an instruction that is a request for executing of a service. A call can be "synchronous" or "asynchronous" depending on its effect on the instruction sequence. The call is said "synchronous" when, upon this call, the current instruction sequence stops, waiting for the execution of the requested service and then restart at the next instruction once this execution ends. With an "asynchronous" call, the request is still sent, but the calling sequence of instructions does not wait and continues with the next instructions, in order. By the way, only synchronous calls can provide return values.

Common concepts

To improve productivity and clarity, both high level programming and modeling languages replace the basic concepts of bare hardware components and assembly languages by more or less advanced constructs. Raising the level of abstraction is desirable in order to decouple the functional aspect, related to the need which is usually stable, from the implementation that is linked to an evolving technology. For a developer dealing with the low level interface between hardware and software, the issue is to find among these advanced constructs those that can provide a straightforward and semantically consistent description of the technology actually available at this level.

Even if the formalisms and the vocabulary used to describe hardware and high level software may seems quite different, conceptually they are not. Indeed, and despite they map to different abstractions, both domains are built on the concepts of storage and service. This convergence is imperative because, as pointed out in §2.1.2, any software code, whatever the programming language used, will be finally executed by the interactions of hardware components.

However, due to their nature, hardware and software interfaces do not have the same flexibility. While the interfaces of software components can easily be explicit and usually follow the "one service one operation" rule, the mapping between the interface of the hardware components and the services they provide can hardly be that straightforward.

For any hardware component, invocating a service is realized by writing one or more values at a specific storage location and, depending on the kind of service, sometimes reading one or more values to get a result. Read and write instructions, such as those based on the well know "MOV" assembly code, are the basic services for interacting with hardware components. These instructions can be modeled by SysML operations which will be invocated using synchronous calls. Indeed, even if the services provided by the hardware component are usually executed asynchronously, the invocations of each basic read or write instruction is actually a synchronous call. By the way, any processor instruction can be mapped to a SysML::Operation. Since the software is executed by the processor, the interface between the software and the hardware is definitively the instructions set of the processor.

Interruptions are another interaction mechanism used by hardware components. They can be efficiently modeled by Signal events which correspond to asynchronous calls. If a software component intends to react to a specific hardware interruption, it has to provide a piece of code specified as the handler for this interruption. In SysML this handler maps to a Reception.

Both grounded on SysML::Operation and SysML::Reception concepts, software and hardware interfaces becomes seamless and easy to integrate in the same model. Of course, interacting with hardware component remains more crude and complex but it is precisely the role of the hardware abstraction layer to deal with this.

INTERFACE PRINCIPLES

GENERAL PRINCIPLES

In this paragraph we list the possible interactions with a hardware component, through its hardware interface, using SysML::Operations and SysML::Reception. In addition some practical constraints that characterize industrial projects are considered:

 The common practice is to use symbolic names for identifying the storage spaces  The number of addressable storage spaces per component may be huge


No assumption can be made on the mapping between the symbolic name and the actual storage location which may change along the development phase but which shall be resolved as a specific value (i.e. an address in the memory map) at the end.

Relying on an abstraction layer, the proposed approach provides: on one side a flatten view of the services offered by addressable hardware components and on the other side the low level interface to the bare hardware platform.

INTERFACE FEATURES

Operation-based hardware interface

The service-based hardware interface provided upon the abstraction appears as a list of services published (i.e. offered) by the hardware platform. These services are modeled by SysML::Operations. They may be organized on a per component basis.

The names of these operations describe the services they are related to, hiding the registers actually involved. For example, operations like: start(), stop(), getSpeed(), setSpeed() or doSoftReset() will be provided rather than: writeStartBit() or readStatusRegister(). In the same way, the types of the operation parameters come from the functional domain of the corresponding hardware component, abstracting the conventions used by the implementation regarding the values stored and the precise location. Then, if a setSpeed() service works with a restricted set of available baud rates, an enumeration will be used (e.g. with the literals '56600' and'115200') and not the corresponding values of the bit-fields (e.g. '011' and '100') that will be written in the control register at the end.

Figure 2: Examples of Hardware Abstraction Level APIs

These services, together with the protocol descriptions and the timing constraints, are sufficient to specify how the hardware platform can be used by a software component, assuming the HAL is provided. They can be specified at an early stage of the development process. The details of the implementation, which includes the coding conventions used, the hardware platform topology and any change thereof will be managed within the HAL and will not be propagated to the software components.

Hardware low-level interface

The interface between the HAL and the bare hardware platform is abstracted according to the approach described in §2.1.3. Three kinds of services are required:

 "write" services are modeled as SysML::Operations provided by the hardware. They change a value stored at a specific location within the memory map. A "write" service has two input parameters: one for the location and one for the value to store in it. It has neither output nor return parameter.

 "read" services are modeled as SysML::Operations provided by the hardware. They retrieve a value stored at a specific location within the memory map. A "read" service has one input parameter for specifying the location. It has one return parameter, which will be assigned the requested value, and no output parameter.

 "exception" services are modeled as SysML::Receptions provided by the HAL. They specify handler for the exceptions mapped to the corresponding signals. Just like processors exceptions, they have no parameter.

Since hardware platforms usually support more than one data type (e.g.: bit, byte, word, word32…), specific "write" and "read" services will have to be defined.

Abstracting memory maps and address spaces

The specification of the services can use symbolic values instead of real addresses to refer to locations of specific hardware storage resources (registers or bit-fields) in the memory map. This is a way to decouple the development of the HAL from some changes of the hardware design. Since the memory map highly depends on the hardware topology, it increases the codesign capabilities. The symbolic values will be replaced by the actual addresses on the final platform once fully specified. This implies that any element the memory map refers to can be uniquely identified.

PROTOCOLS

For a resource offering a set of services, it may be some constraints in the way these services have to be used for working as expected. For instance, some components need to be initialized or parameterized before providing any other services. In addition there are resources that cannot be reached directly. Accessing resources may become tricky when the topology of the hardware platform is complex because of the interleaving of protocols.

When a hardware resource is directly accessible from the processor executing the software (i.e. no interconnect is used), the developer has to deal with the protocol of that resource only. Unfortunately, in most cases, those resources are reachable only through one (or more) interconnects, among which some may be opaque. In such a topology, accessing the resource implies interweaving the protocol of that resource with the one of the opaque interconnect that relates it to the processor. For transparent interconnects, there is no need for taking care of the protocol since resources behind them are directly mapped into masters address spaces. The stacking of protocols significantly increases the complexity and may turn to a real nightmare when several interconnects are cascaded.

The discussion on the way SysML can be used to model protocols would be worth investigating. The main problem is that the SysML::InterfaceBlock provided in place of the UML::Interface metaclass has no feature for this. Could the pre and postconditions together with invariants sufficient for describing the protocols of hardware resources? This is an interesting open point but it is out of the scope of this paper. In our context, we will assume that the protocols are specified, whatever the way.

THE HAL MODELING PATTERN

The goal is to encapsulate protocols for offering a set of abstract but straightforward services, i.e. an Application Programmable Interface (API) for the development of applications that will execute on the platform, whatever its topology.

To deals with this, we adopted a progressive approach. The first step is carried out independently for each addressable hardware resource on the platform, modeled as a part of the SysML::Block representing the overall HAL. Each of those parts is typed by the SysML::Block responsible for dealing with their own protocols, as specified by their datasheets. A given resource (i.e. part type) may have more than one API and, even for a given API, more than one connection point. For instance, a data bus usually provides number of connection points for both "master" and "slave" APIs. Connection points are modeled using SysML::Ports typed by the SysML::InterfaceBlock which specifies the corresponding API. In the second step, the parts of the HAL are interconnected to mirror the topology of the hardware platform, according to the following rules. For each HAL part representing an addressable hardware device:

 If it is located on the processor's address space, it is directly connected to the HAL "cpu" port standing for the hardware platform  Otherwise, follow the connection path from the device up to the processor:

o For each intermediate connection, make sure the end closer to the processor is connected to the right port. In some cases, when a connection uses more than one APIs, several ports and then several connectors may be involved.

The third step consists in specifying, for each part type involved in the HAL, how the services provided by its API are realized based on services provided to it by:  Either the API of the HAL's part it is connected to  Or based on the CPU instruction set, if it is directly on the processor address space.

This design pattern is scalable since it actually breaks down the stack of protocols so that they are addressed one at a time, which allows dealing with topologies of any level of complexity.

APPLICATION TO THE STUDY CASE

Assume the hardware platform shown Figure 4. This is a very simple architecture sufficient for illustrating our modeling approach. One single central processing unit core (CPU), with its associated memory chip (Mem), drives two discrete signals (DSO) through two identical controllers. The first one, controlling DSO_1, is directly connected to the processor's bus. The second one, controlling DSO_2, is located behind a bridge (Z-Bridge).

Components using the services provided by other components

Low level hardware interface (i.e. the instructions set)

Components using low level hardware interface

Interconnect component (in yellow)

Functional component (in green)

Figure 4: Study case description

As a study case, we will describe how to specify an API allowing an application to set the value of any of the DSO using a simple set() operation, independently of the topology and on the local protocol of the DSO controller.

INTERFACES MODELING

Regarding the processor unit, according to the proposed approach and considering that we focus on using the platform resources, we only need a limited number of behavioral features: operations for read and write and signals for exceptions. In practice, read and write operations should be overloaded to deal with all the data formats supported by the processor. In the context of this study case, we assume that there is only one format (32 bits data words), and that no burst is available. Similarly, we limit to three the number of exceptions managed: one for starting the normal execution ("main" signal), one for the "divide by zero" exception ("div0" signal) and the last one for the hardware exceptions ("irq" signal). The modeled interface is depicted Figure 5. Note that, assuming this InterfaceBlock is used to type the port on the platform side and according to the SysML convention, the read and write operation are declared "provided" while the signal handlers for the three exceptions are declared "required" (i.e. it is up to the software application to provide these handlers). On the HAL side, the port will have the same type but it will be conjugated (i.e. isConjugated=true).

The DSO controller used is imaginary but it has a representative interface. Its datasheet is presented Figure 6.

Memory Map

Register Size Offset Access

RegCMD 8bits 00 R/W RegV 8bits 01 R/W Bitfield Register Size Access Start/Stop RegCMD[0] 1 R/W DSOVal RegV[2] 1 R/W Programming interface

Start/Stop

If this bit is set to 1 then the controller drives the output with the value set in RegV. If this bit is set to 0, then the output is in high impedance state.

DSOVal

If the controller is started, this bit controls the output state: a 1 in this bit drives the output at high state; a 0 drives the output at low state.  An isStarted() service returns the Boolean value "true" whether the controller is started and "false" otherwise.

 The setValue(in val : DSOState) service sets the value of the controlled DSO according to the value of its input parameter which is of a discrete typed specify by the DSOState enumeration.

 The getValue():DSOState service returns the value actually reflected by the DSO at the time it is called The Z bus has a 20 bits address bus only. Only the 20 lowest significant bits are taken into account to locate an access on the Z bus.



For any access to a component register through RegData register of the Z bus, its address must be set in the Z bus RegAddr register first.  The setData(in addr : MMapLocation, in val : Data32) service allows setting the value of a register of a component connected to the bus. The register is identified by its location in the memory map, as provided by the "addr" parameter, and the value to assign is provided by the "val" parameter.

 The getData(in addr : MMapLocation) : Data32 service returns the value of a 32 bits register at the memory map location provided by its "addr" parameter.

ABSTRACTION IMPLEMENTATION

Once the digital architecture is available, the internal specification of the abstraction layer can be completed, according to the approach presented in §4. Figure 11 shows the resulting model. In the hardware digital architecture, the dso1 controller and the z bridge component, which are connected to the processor's bus, are directly mapped in the address space of the processor's master port. By the way, in the HAL, their corresponding abstractions use the processor instruction set directly, as modeled by their "cpu" ports.

The gap between the services offered at the API level and those actually provided by the processor instructions has to be filled by the behavior (i.e. the algorithm) specified for each of the operations provided by the HAL to the software application. Theoretically, any kind of behavior description may be used but, in practice, SysML::Activity graphs and SysML::OpaqueBehavior encapsulating pseudo-code or executable language are the best solutions. Alternatively, the description of the expected behavior can be limited to the specification of pre and post conditions together with a list of invariants, if any.

For the purpose of our case we chose an imperative pseudo-code. The API services provided by the HAL for the DSO1 controller are specified as follow:

start() {//set hw::dso1::regCMD bit 0 to 1 write(hw::dso1::regCMD,read(hw::dso1::regCMD) or 0x01);} stop() {//set hw::dso1::regCMD bit 0 to 0 write(hw::dso1::regCMD,read(hw::dso1::regCMD) and 0xFE Comparing the implementation of the API for DSO1 and DSO2, we notice that the level of complexity is exactly the same, despite the additional protocol we have to deal with.

CONCLUSION

Using abstractions coming from the software domain, we described how we can build a low level model for the specification of interfaces to bare hardware platforms. Thanks to its level of abstraction together with the concepts on which it is founded, this approach provides a seamless transition between the hardware and the software domain. This makes it convenient for supporting model-based development of the Hardware Abstraction Layer (HAL) which hides the actual topology of a hardware platform and presents it as a flat list of services.

The approach described in this paper is also compatible and consistent with the technologies of virtual prototyping like SystemC/TLM, which enable early verification and validation. Indeed, the seamless specification model provided might be used to generate the executable model of the virtual prototype, assuming the hardware behavior is modeled as well.

Both HAL and virtual prototyping are key features for providing real co-design facilities for hardware and software components of a product Our next step will be to investigate how SysML can be used for specifying protocols. This may require some enhancement of the current standard. Then we will study in more details how the model of the hardware/software interface can be properly related to the modeling of hardware behavior. The multiprocessors/multi-cores aspects will be another axe of our future works as well.

Figure 3 :

 3 Figure 3: modeling principle to the Hardware Abstraction Layer

Figure 5 :

 5 Figure 5: CPU Interface modeled using a SysML::InterfaceBlock, as exposed by the HW platform

Figure 6 :

 6 Figure 6: DSO controller datasheet, as used for the study case The API we want to provide for the DSO controller is shown Figure 7. It offers the following services:  Start/Stop services are provided through the corresponding start() and stop() operations. They have no parameter.

Figure 7 :

 7 Figure 7: API provided for the DSO controller on the application side of the HALIn the same spirit, we assume the datasheet described Figure8for our "Z-Bridge" controller.

Figure 8 :

 8 Figure 8: Z-Bus controller datasheet, as used for the study case The API we want to provide for the Z-Bridge is shown Figure 9. It offers the following services:

Figure 9 :

 9 Figure 9: API provided for the Z-Bridge on the application side of the HAL On the hardware interface side of the HAL, there is only one connection point to the CPU which will execute the software the HAL is made of. At this point, interactions are restricted by the processor instruction set. This is reflected by the IB_Instr InterfaceBlock typing the hardware platform port used by the HAL. The DSOs provided by the hardware platform are represented by two distinct ports type by the IB_DSO_Digital InterfaceBlock. The description of this last port type is out of the scope of this paper.The model of the resulting architecture is shown in Figure10. Assuming the protocols related to the HAL API are provided, it suitable for the development of the software application.

Figure 10 :

 10 Figure 10: Resulting architecture for the study case, as used for the development of a software application

Figure 11 :

 11 Figure 11: Digital architecture of the hardware platform and its corresponding HAL

  Driving the DSO2 output from the software application requires interleaving both the DSO controller protocol and the Z-Bridge protocol. However, this work can be simplified since we can rely on the bridge's service API developed at the previous step, as described below.

	else
	cpu.write(hw::dso1::regCMD,cpu.read(hw::dso1::regCMD) and 0xFB);}
	getValue() : DSOState {//test hw::dso1::regV bit 2
	if((cpu.read(hw::dso1::regV) and 0xFB)!=0)
	return DSOState::High;
	else
	return DSOState::Low;}
	While the API services for the Z-Bridge are specified as follow:
	setData(in addr : MMapLocation, in val : Data32) {
	cpu.write(hw::bridge::RegAddr, addr.toData32());
	cpu.write(hw::bridge::RegData, val);}
	getData(in addr : MMapLocation) : Data32 {
	cpu.write(hw::bridge::RegAddr, addr.toData32());
	returncpu.read(hw::bridge::RegData);}

);} isStarted() : Boolean {//test hw::dso1::regCMD bit 0 value if(cpu.read(hw::dso1::regCMD) and 0x01) return True; else return False;} setValue(in val : DSOState) {//set hw::dso1::regV bit 2 if(val==DSOState::High) cpu.write(hw::dso1::regCMD,cpu.read(hw::dso1::regCMD) or 0x04); start() {//set hw::dso2::regCMD bit 0 to 1 z.setData(hw::dso2::regCMD, z.getData(hw::dso2::regCMD) or 0x01);} stop() {//set hw::dso2::regCMD bit 0 to 0 z.setData(hw::dso2::regCMD, z.getData(hw::dso2::regCMD) or 0xFB);} isStarted() : Boolean {//test hw::dso2::regCMD bit 0 value if(s.getData(hw::dso2::regCMD) and 0x01) return True; else return False;} setValue(in val : DSOState) {//set hw::dso2::regV bit 2 if(val==DSOState::High) z.setData(hw::dso2::regCMD, z.getData(hw::dso2::regCMD) or 0x04); else z.setData(hw::dso2::regCMD, z.getData(hw::dso2::regCMD) and 0xFB);} getValue() : DSOState {//test hw::dso2::regV bit 2 if((z.getData(hw::dso2::regV) and 0xFB)!=0) return DSOState::High; else return DSOState::Low;}

Acknowledgements

The authors would like to thank Airbus Operations SAS for having funded this work.


Pierre Gaufillet
email: pierre.gaufillet@airbus.com

Clotilde Marchal
email: clotilde.marchal@eads.net

How to benefit from Open Source components in your embedded products?

Keywords: open source, business model, governance, intellectual property, export control Summary

Integrating open source components in embedded products is a real opportunity to improve your productivity and to implement attractive new features in your products. But for benefiting safely from this new approach of Intellectual Property, a good knowledge of its characteristics and a minimum of organization are needed. For two years now, an EADS working group has been exploring and implementing such organizations in each business unit. Based on this experience, we will go in this article through the risks induced by the availability of open source components, and will expose an approach for implementing the control mechanisms that are required in your company.

The last 10 years have seen the emergence of open source in most industries. Software tools, Telecommunication, IT and more recently aerospace, energy, automotive and healthcare have at least made a step toward open source. It is not a fashion effect: due to the features of open source licenses, open source code is accumulating innovations and value with the time. It makes more and more difficult for companies not using it to remain productive enough compared to their competitors leveraging open source. In other terms, open source has become a valuable source of productivity. Recent surveys have also shown that even if you think you are not using open source components, there are nevertheless probably some of them in your applications and in some of your embedded products -even if safety/mission critical softwares are obviously better controlled due to their strict development and verification process. Beyond the fact that some major pieces of code -like Linux, Apache or Eclipse Rich Client Platform -are open source, it is due to the advent of generalized high bandwidth Internet accesses combined to efficient search engines and a cultural change of developers. Combine that with more and more complex supply chains and you will soon realize that it is difficult to know where the source code of your application is coming from.

In itself, it may remain technically manageable, as far as you ensure that all parts in your code are integrated and verified in a consistent way. But there are several families of open source licenses, and some of them can have unexpected legal effects on your Intellectual Property. Copyleft licenses for example, also known as reciprocal licenses, cover not only the open source components themselves, but also the original code linked to them, potentially extending to the whole application. Integrating code under copyleft licenses may therefore result in having an obligation to give access to your customers to the whole source code of your application. Of course, it is most of the time possible to solve that either by modifying the architecture of the application, or by changing your license to open source -and therefore probably change your business case, which is not so obvious. Beyond the management of the Intellectual Property, integrating open source components -and more generally 3 rd party components -implies to take care of other important aspects:

• Export control: if your applications are to be delivered to customers in a list of foreign countries, you may face regulation issues, most often related to the exportation of cryptographic algorithms. It is quite common to integrate components that include such algorithms even if you are not using them.

In practice, you may even ignore their presence. PDF generators are a good example, as most of them provide RC4 encryption capabilities. Depending on the kind of algorithm exported, you may be required either to declare it, or to ask for an export authorization to the regulator.

• Security: depending on the architecture of the application, 3 rd party components may introduce vulnerabilities. Of course, it can be easily managed at design time, first by checking the list of known vulnerabilities, coming for example from the NIST database. But it doesn't solve everything. You will also have to set up an organization capable of analyzing the impacts of newly discovered vulnerabilities during the whole life time of your product. And when required, you will need the capability to integrate security patches, rebuild and distribute new releases of your application.

• Professional support: one of the most common arguments heard against open source in the industry is the lack of professional support. Of course, this vision is the result of the decentralized nature of open source. It means that in most case it is not one but several companies that can provide support -including on demand warranties and liabilities. Open Source foundations may also play a role here, ensuring that some fundamental features are maintained, like IP control and technical hosting of their projects.

• Certification: depending on the criticality of your applications, integrating 3 rd components can be more or less difficult, and can be addressed thanks to several strategies ranging from a full technical appropriation of the source code -a kind of corporate fork -to the integration as a black box.

For these reasons, after preliminary studies made in several business units, EADS headquarters have launched in 2011 a working group aiming at implementing the organization required to benefit safely of open source components in its tools and products. During almost 2 years, this working group has explored most of these topics and it has quickly become clear from the list of risks identified above that properly using -and not using -open source requires some organization and means. This is now part of software development as other activities like specification, design or functional verification. This experience has shown that there are several ways to implement it, depending on the size of the company and its business models. EADS business units are now in a pilot deployment phase aiming at refining the governance and verifying that the required tools can be integrated smoothly in the corporate IT infrastructure.

But the first and most important step is certainly to create a group of experts gathering IP legal counsel, export control officer, procurement, open source specialists and software architects. The correct analysis of the risks and the resulting decisions require indeed numerous skills and can be seen as a shared responsibility. Of course, SMEs may not have all the dedicated resources for this purpose, and big companies may consider these activities as outside of their core competencies. It is still possible in this situation to rely on external services, which can be provided by specialized actors like law firms and open source service experts. Whatever organization has been chosen, the second step is to train all the employees potentially facing open source including software developers, project managers, architects and system designers.

Organization, process and trainings are of course fundamental, but it also makes sense to support at least a part of the activities that have been already identified by specific tools:

• Open Source portfolio management tool: in numerous cases, embedded products have to be maintained for quite a long period. It is therefore important to log a number of information for each product: what open source components are being used, how they are integrates, what version is used, etc. Thanks to this information, it is not only possible to take the right decision years later, but also to automate some expansive activities like security follow-up. Managing an open source component obviously implies costs, so maintaining this portfolio is also a way to reduce future analysis -by replying on past decisions for example -and to limit the number of components in use -by reminding architects during future selection process that a component with similar features has already been deployed.

• Code scanner: a number of very efficient code scanners are available on the market. While not absolutely required (en fait je dirais que c'est plutôt obligatoire non ? ou alors c'est un risque à prendre...), these tools are a very good mean to raise the level of confidence you have in the IP analysis of your application, especially in the context of complex supply chains. It is to be noticed that these code scanners can operate of course on source code, but also on binary resources like dynamic libraries, images and other multimedia resources. Some of them also provide a formal analysis of the compatibility of licenses. Several integrations are possible, from a simple verification on build, to early verification during design review, through continuous verification of each code commit in your version control system.

Of course, if both tools are deployed, integrating those makes sense and gives the ability to improve their efficiency. The code scanner can use open source portfolio information to improve its detection capabilities, and the portfolio can incorporate the results of the scan, giving management an overview of open source usage for all the projects of the company. It is also possible to generate documentation, for example a booklet gathering all the licenses included in the product.

To summarize, whether or not you want to use open source components, protecting the Intellectual Property of your company in the current situation requires introducing at least a few verifications in your acquisition and development process.


Grams CO2 per kilometer, normalized to NEDC

Introducing Multi-Core at Automotive Engine Systems D. Claraz 1 , F. Grimal 1 , T. Leydier 2 , R. Mader 3, G. Wirrer 3 1: Continental Automotive France SAS, 1, av. Paul Ourliac, BP 1149, Toulouse -France 2: Virtualised Reeled, 4, rue du romarin -31650 Saint Orens de Gameville -France 3: Continental Automotive Germany AG, Siemensstr.12, Regensburg -Germany 1. Introduction / Motivation (why Multi-Core)

With the introduction of the new Euro 6, and Euro 7 emission standards for passenger cars, the combustion process of Engine Management Systems (EMS) needs to be controlled with an increased precision.

In addition, new vehicle architectures are introduced (increased integration of functions inside an Engine Management System), as well as new SW architectures concepts like AUTOSAR or the support of ISO26262. All these evolutions result in an increased need for computation power.

To face this challenge, the increase of the CPU frequency (today up to 300 MHz), which has widely been used in the past, is not anymore an option, due to power dissipation limitations. Therefore, the solution emerging on the market now, and promoted by our microcontroller suppliers, is the use of Multi-Core technology. In a first part, we will describe the challenges we have to face to make a legacy engine systems SW Multi-Core compatible.

In a second part, we will give some elements of the solution we have developed.

In a last part, we will give a status on where we are concretely.

Originally, our plan was to introduce the Multi-Core approach together with our new AUTOSAR-based architecture concept EMS3-PowerSAR ® . But the migration of a full project to this new PowerSAR ® architecture is not possible in a short time frame, and we foresee that our next projects will have to deal with a mixture of different architectures: AUTOSAR (different releases, different uses of same release, ...), PowerSAR ® , Continental EMS2-MCR, Continental EMS2, OEM specific, etc.. Then, since December 2011, we focus on a solution to make our EMS2 "legacy" SW platform Multi-Core compatible. This is called EMS2-MCR ("Multi-Core Ready").

EMS2-MCR is based on a PowerSAR

® / AUTOSAR BSW layer, on which the migrated legacy ASW is integrated, together with components of the new ASW PowerSAR ® architecture. Our objective was to distribute a legacy project on a 3-Cores ECU, and run a demonstrator-engine by end of 2012/beginning of 2013.

Challenges

a. Methodological challenges

The methodological challenges are multiple:

Backward compatibility:

Our SW-development process is highly reuseoriented ("reuse by reference"), based on a concept of reusable aggregates stored in generic libraries, and developed by generic teams. Customer projects, managed by customer-oriented teams, select solutions from these generic libraries, and configure them for their own context (configuring being different than modifying).

Such an approach requires that the generic library is an "asset" common to all projects, and means that the functions are developed and maintained once, in the generic teams.

Consequently, our first objective is to ensure that a function migrated to the new EMS2-MCR context must be still reusable as it is in a classical EMS2 Single-Core context (for instance w/o RTE), as all projects will not migrate simultaneously on the new HW platform. Furthermore, the effort to maintain 2 parallel branches of the same function (one Single-Core branch and one Multi-Core branch) would be too high: duplication of teams, of competence, …

Independence vs. Core allocation:

The design of the function must not take any assumption about its own and other's core allocation. This is due to the fact that we are not able to define, once forever, the distribution of the functions on the Cores. The distribution will change over the time, due to new incoming constraints, due to our gain of experience, ISO-26262 considerations, load balancing, RAM consumption, customer requests, diversity of projects (Single-Core projects dual core projects, triple core projects reusing the same functionality), diversity and evolution of the HW (1 to 3 cores today, 5, 6 or more in the future?), …

Automatic protection of code:

The problem of concurrent access to shared resources, a classical problem in real time systems, is kept under control, in Single-Core systems, by two main hypothesis: scheduling strategy (preemptive, non preemptive), and priority scheme. These Single-Core hypothesis are just blown-up in a Multi-Core context, reaching to a special high degree of complexity.

Firstly, intra-core communication is dependant on task priorities, and is directionnal: Depending on the relative priority of 2 tasks, we can know if they interact with each other, and even better, we can identify which one interrupts the other one. With inter-core communication, this is not anymore true: a low priority (low criticality) task of Core 1 can "interact with" a high priority (high criticality) task of Core 2. Furthermore, the interaction is bidirectionnal, now.

The second aspect is the type of interaction between the tasks: In intra-core communication, they are of three types: preemptive, non-preemptive and cooperative 1 : depending on the type of interaction, the risk is mitigated. Finally only in few cases, preemptive scheduling is used, which requires special attention for the developers, in term of data handling: one executable might be executed concurrently to another one (or to itself), and therefore concurrently access to a shared resource (race condition met). In Multi-Core context, the inter-core communication is similar to a preemptive behavior, everywhere.

Another point is that the same aggregate might be integrated differently in different projects with different architectures, and still needs to be properly protected. A manual and a priori protection cannot comply with a big diversity of architectures, and it is likely that a protection pattern works for a context, but not for another one. At the end, the correct handling of such race conditions is in general error prone, and requires additional effort, increasing development time & cost.

For all those reasons, we have no other alternative than an automatic mechanism to protect the SW.

Efficiency of the protection:

Considering the particularity of Engine Systemshigh coupling between the control functions -the efficiency of the solution gets high importance.

Basically, the resources to protect here are data, and they must be protected in an efficient way: The air mass entering the combustion chamber is consumed more than 6.000 times a second, while the engine rotation speed (rpm) is used 30.000 times a second, and in more than 300 different modules. In total an Engine System Software has to deal with 20.000 variables in around 600.000 of lines of code.

Different concepts are introduced to handle such situation in an efficient way. For instance, a standard approach of buffering data at a beginning of a task, or disabling interrupts at each access point, similar to what AUTOSAR implicit & explicit communication [START_REF]AUTOSAR 4.1.1 Specification of RTE -AUTOSAR_SWS_RTE 3[END_REF] proposes is not an option here.

Improved integration:

The difficulties linked to integration in the Engine System domain have already been addressed, in a Single-Core context [START_REF] Claraz | Engine management software dynamic architecture versus integration[END_REF]. The introduction of Multi-Core inevitably increases the complexity of the architecture. A project with 30 operating system tasks in Single-Core will get up to 70 to 80 tasks in the future, or even more depending on the number of cores.

New integration constraints and artefacts will raise up, which will be defined at function level, to be considered at integration level. Different projects will follow different criteria for the distribution of the SW across cores. The total control of integration and architecture will be necessary for the control of data protection.

Human factor / applicability:

The solution should be understandable, and usable by the whole organization in a short time-period. We cannot make every SW developer (~600 World Wide) an expert of Multi-Core architecture. In particular they are used to architectural patterns and design paradigms on which our current platform is founded. The tools, method and processes are based also on this and the transition should be smooth enough to be easy to use and understand. Finally, the migration to the new concept should be fast and supported.

b. Migration

As already mentioned, our purpose is to migrate our SW library to the new Multi-Core Standard. As this migration is done while all projects are in development, we need to ensure that there is no regression introduced with the migration. A default Single-Core behaviour shall be ensured.

In order to speed-up the migration of hundred thousands of lines of code, a tool has been developed, which analyses the legacy SW, and introduces the necessary material into the code to make it Multi-Core compatible. The basic cases, most frequent, are treated automatically, while some more complicated cases need to be treated manually. In all cases, a review of the migrated code is done by the function experts. This has required an exhaustive identification of the use cases, in the code, quite a challenge knowing that some of the SW modules are more than 10 years old, and taking into account that architecture rules, coding rules might evolve with time.

Complex code structures and complex design patterns have been considered, and their applicability in a Multi-Core context has been studied. For some of them, new patterns have been introduced. For instance, the classical « double buffering » pattern has been replaced by exclusive areas, as it does not apply in all cases of core distribution.

c. Technical challenges

Which distribution?

The first question to answer when we switch from Single-Core to Multi-Core (e.g. 3 cores) is the distribution strategy: Do we have a dynamic, or a static distribution? What is the rationale to distribute this or that Aggregate on this or that Core?

As the objective of the migration to Multi-Core is to gain CPU load, the basic question is to define which policy is the best to reach a balanced load. Angle vs. Time computations? Short deadlines vs. long deadlines? Vehicle functions vs. engine functions? ASIL modules vs. QM modules?

A first approach would be a functional approach: The distribution over the cores is defined by the functional partitioning. For instance, all inlet related functions on 1 st core, all setpoints related functions on 2 nd core, and all exhaust related functions on 3 rd core.

Another topology could be based on the dynamic architecture of the SW: all engine-angle related aggregates (a clear specificity of combustion engines) on one core, all pure time dependant aggregates on another core. A third approach could be based on the speed / deadlines of functions: Short deadlines on the first core, middle deadlines on the 2 nd core, and long deadlines distributed on the 3 rd core.

Each of these topologies has advantages and drawbacks. Due to the strong coupling of the functions (another clear specificity of combustion engines), they are not easy to apply, in particular when computation sequences matter. In effect, a classical 10ms Task might gather up to 150 Runnables which in many cases need to be executed in a well defined sequence. Therefore, the distribution of such task over 3 different cores can be done, only if the execution order is kept.

At the end, the code distribution is a multidimensional problem 2 , and the allocation will be a balance between the buffering effort, the sequence needs, the customer request, etc... We foresee that we will need a high flexibility, and we will not be able to ensure for a long time that this or that function will always be mapped to Core 1. Finally, the objective is to distribute the CPU load in an equilibrated way across the cores.

Therefore, we target a distribution based on runnables, rather than modules, or even compositions. At integration time, the project will have the possibility to move one runnable from one core to another, taking into account its own policy.

Split of components?

Another question we faced concerns the ability to split SW-Components on different cores, something today not authorized by AUTOSAR.

As most of the SW-Components are not monolithic in terms of dynamic architecture, they need to be integrated in different Tasks / Integration containers. If we mix this status with the need to ensure a correct sequence between runnables, we see that it shall be possible to locate different runnables of the same component on different cores, depending on the integration Task.

Moreover, complex cases like multi-rate data (data produced at different rates, e.g. top dead centre and 10ms), or even multi-rate executables needs to be supported. This includes executables called by 2 Will be addressed in a further conference. different tasks on the same core, or even on different cores.

Scheduling strategy

A last question concerns the Task scheduling: Is a dual core architecture a simple duplication of the simple core architecture? By evidence, no, because the complexity of the whole system would not be controllable : A typical Single-Core project contains up to 30 OS Tasks, plus some 20 containers for system transitions, which means around 50 integration containers, where individual runnables need to be plugged. A simple duplication of these containers on each core would lead to a high complexity, and probably an unfeasible system, in term of deadline fulfilment.

So, an adequate architecture is set-up, with new concepts. For instance, for a given rate, some tasks might be either parallelized, or chained. Both techniques have advantages and drawbacks.

d. Starting point : Legacy SW

A classical approach, when introducing a new technology like Multi-Core would be to start from a white page, design all functions new, and even take some assumptions concerning their Core allocation. But, the corresponding effort and delay would be too high, and as already mentioned, a fixed allocation does not fulfil our needs. Therefore, our starting point is a legacy SW. But what does it mean exactly? A typical legacy Engine Systems SW project is built of around 2.000 SW modules (1.300 for asw), more than 8.000 executables, and 1.500

3 of them to be integrated in a task. Around 150.000 data access points need to be considered for data access protection.

In term of mechanisms, ahead of the multi-rate data and executables already mentioned, the reality of a legacy SW is a complex call structure sometimes reaching in some cases more than 10 nested call levels, with indirect calls, with complex data types, etc… One typical topic is the « consolidation » of the data and control flow in such « non flat » architecture.

Another difficulty, inherent to legacy-SW is the mixture of formats: AUTOSAR files mixed up with legacy files, and/or with object code from our OEMs.

Solution : Integration & Protection

In this chapter, we will show the main principles of the solution developed to integrate runnables and to protect data in the EMS2-MCR SW, satisfying the above constraints. As a prerequisite, the legacy code had to be prepared to be MCR, which means (roughly) the replacement of all direct accesses to global variables by GET/SET APIs, to allow their protection by an adequate process.

a. Concepts

This solution is organized around 2 main axes: Integration and Protection.

Runnable Integration

Runnable integration gets a higher degree of complexity in Multi-Core context, compared to a Single-Core context: -The total number of tasks and integration containers is largely increased compared to Single-Core (even if not multiplied by the number of cores) -The criteria to choose between one and the other task on one or the other core might be more complex (multi-dimensional problem)

In addition, we want to benefit from the "new" platform to improve our integration process.

So, the solution to this problem has 2 facets:

At Component or Composition level, integration constraints are specified: System Events (stimulus), , Phases [START_REF] Claraz | Deterministic Execution Sequence in Component Based Multi-Contributor Powertrain Control Systems[END_REF], Timing properties (periods, deadlines …), Sequence Needs, Core Affinity Needs are defined, using a component modelling tool, CoMod.

On project side, these constraints are reused by a runnable integration tool, RunIn, enabling the integration of Runnables at the correct position in the correct Task. Conflicts are shown and can be solved by the integrator. Runtime of Runnables can be imported in order to properly balance the computations across the cores. Additional constraints can be defined at integration time as well.

Data access Protection

As explained before, data protection in Multi-Core context becomes also much more complex, compared to the "automatically protected" mode of Single-Core Cooperative context. We remind here, that cooperative scheduling is widely used at Continental, as it has the following benefits: First of all, in most of the cases, it is largely sufficient to fullfil our timing constraints. Secondly, it is resource efficient (limited context switches). And last but not least, it provides us a data protection "free of charge": no particular design constraint, no tool is needed to ensure data protection. Computations simply do not interrupt each other.

With Multi-Core now, as any task on any Core can disturb any other task on any other Core, the situation is quite different.

Two kinds of problems are identified: stability (an information gets a stable value along a code sequence , like 2 different Runnables), and coherency (2 information are coherently acquired at a certain point in time). One cornerstone of the strategy is that only those artefacts which require protection will be protected. We made this choice because we estimate the cost of protecting everything too high, due, once again, to the high coupling and complexity of Engine Systems. In addition, an unnecessary buffering may have negative impacts on the SW behaviour, not only on the resource consumption point of view. Finally, not all data and data accesses are critical, and we have to focus on those ones. So, the component modelling tool, CoMod, supports the specification of so-called "Consistency Needs". To be noted that this concept of Consistency Needs has been promoted and then introduced in AUTOSAR (and available in 4.1.1).

At project side, these constraints are taken into account by the integration tool. RunIn analyses the project and computes all required protection, taking into account the complete call and data graph, the specified ConsistencyNeeds and the project architecture. It generates all necessary C and ARXML files for the further SW build.

The strategy chosen to protect the data is based on a buffering concept: When a variable is accessed in one executable, if we identify a race condition, and if a protection is required for this variable, then it is copied into a buffer, and the executable works on this local copy. If the executable modifies the data, the modification is done on the buffer, and the value of the buffer is copied in the global variable later on.

The principle is similar to the AUTOSAR concept of implicit communication.

Fig. 5: Buffering concept

To enable this, in the migrated code, special access APIs have been introduced, which allow an eventual re-direction. Depending on the conditions, the GET and SET macros will be redirected to buffers. Fill and flush routines are added to the Runnable scheduling, in order to initialize the Buffers, and to copy back the value in the global memory.

In order to minimize the buffer consumption, the same Buffer can be reused across different executables, for different data, in the same task. This is part of our optimization process.

The code patching strategy, similar to what is done by a classical RTE, presents several advantages compared to the object file patching strategy, also used at automotive engine systems. Some of these advantages are: -It can be used early in the process, in particular before the sw Build. Therefore, the integration choices can be influenced by the Buffering results. -The output can be verified easily -The process is independent of any compiler version, or compiler option -It is an open solution which easily supports complex use cases, like multi-rate executables b. Architecture control One element of the strategy is to identify and control properly the project architecture. The tasks and integration containers, their allocation to the cores, their timing properties, and their priorities have to be defined, as they are important factors for the integration, as well as for the protection. For the data protection, for instance, the interactions between the tasks have to be identified (direction, type, …). The resulting buffering and copy routines will depend on it.

Fig. 7: Task configuration

In order to ensure that the theoretical view on the architecture, used for integration and protection, is consistent with the real implementation in the ECU, different configurations are generated in a seamless environment: typically RTE and OS configurations, as well as all the required « glue code ». Concerning the integration, for each of its Runnables, the developer specifies the required timing and integration properties. In order to avoid a big variety of needs, a set of standard System Events is provided through a Reference Architecture.

The developer has only to select the one of interest, as well as the Phase the Runnable corresponds to. Doing this, he defines a « RunnableEvent », which is a similar concept than the AUTOSAR concept of RteEvent (with the notable difference that no invocation mechanism is specified here, which gives more flexibility on how to solve this invocation).

d. Integration & Protection

The integration and protection process takes as input the previously defined project architecture, the specified Needs of the individual modules, and the SW cartography. This last element consists in resolving for the whole SW all data accesses. All types of accesses have to be identified (arrays, pointers, structures, …), as well as their multiplicity and consolidation.

The previously defined RunnableEvents are used by the integrator to select the right task for each runnable. The specified Phase and Sequence constraints are used to define the position in the task. In case a mistake is done, the integrator is informed by special warnings. When all Runnables are integrated, the protection process is launched. The tool takes into account all parameters, and defines which variables need to be protected, how, and at which point in the task. For instance, in the below picture, we see how the fill routines are inserted at certain points in the tasks.

Like already mentioned, we see that the buffers are not initialized only at beginning/end of a task. In addition to these 3 elements, various configurations are generated, which ensure a perfect fit between model and real implementation in the ECU.

Status

Since we started to develop this approach, in December 2011, most of the 1.300 Sw-modules have been migrated, in the scope of a first pilot (gasoline) project. A new (diesel) project is currently started, which will reuse partly the already migrated aggregates, and which will require new migrations.

The migrated aggregates are reused in the running Single-Core projects, w/o noted bad effects: That demonstrates their backward compatibility.

In the first pilot project, more than 400 consistency needs and 2700 RunnableEvents are specified.

When applied, together with complementary automatic protection strategies, near to 2.000 buffers are used to buffer around 8.000 accesses (out of 130.000). The measured overhead is in the range of 6% of CPU load, distributed over the 3 cores, which is an acceptable value.

The first distribution applied on our pilot shows the following results, in term of CPU load evolution: Most of our engineers are getting trained to the concepts of Multi-Core, and are able to specify Protection and Integration Needs, while the project Teams are able to cope with the new architectural artefacts, and integration means.

Concerning real customer projects, a first project with a premium german OEM started to use this method by beginning of 2013 (SOP End 2014, 200ku/year). This first project is split over 3 cores, and uses preemptive scheduling. With the same OEM, we start another project, which also uses 3 cores, but with a different distribution of the SW. Another project with another German premium OEM is also started based on our pilot, also distributed on the 3 cores. Finally, another project for a US OEM will use also this technology, but in a limited way, by using only 2 cores.

Conclusion

Ahead of a simple Tool Suite, the EMS2-MCR solution is a methodology based on a series of new EMS3--PowerSAR ® concepts implemented coherently across the process: Reference Architecture, System Events, Synchronized Transitions, Phases, Runnable Events, Consistency Needs, Sequence Needs, Core Affinity Need etc ... These concepts, originally planned to be used within an AUTOSAR-based platform, have been quickly tailored and applied on a legacy non-AUTOSAR Platform. This has been made possible by an abstraction of our needed concepts vs. AUTOSAR. These concepts, and the method and tools supporting them are now at common use at Continental, and different Customer projects are already developped following this new standard.

But, this is the beginning of the story, and we need to improve and enrich the solution. For instance, the integration process has to be re-considered due to Multi-Core needs. Schedulability, SW distribution, ASIL introduction, shared development, validation, are on our table for the coming year.

Of particular importance will be the integration of AUTOSAR SW-Components in our framework. The questions will be about the mixture between legacy non-AUTOSAR SW and AUTOSAR SW, the efficiency of the RTE (and therefore, which use?), the introduction of the new concepts (Consistency Needs, ...), and improved integration means, the maturity of AUTOSAR in term of Multi-Core, ... Finally, the step to Multi-Core suddenly provides us a duplicated computation power, for the same ECU price. This opens the door to an increased integration of PowerTrain domain, at least. The Multi-Core revolution is to be expected in the full system architecture, much ahead of the pure SW area.

Fig. 1 :

 1 Fig. 1: Evolution of Emission standards (Source: European Commission, EPA)

Fig. 2 :

 2 Fig. 2: Evolution of cpu freq vs. Power dissipation

Fig. 3 :

 3 Fig. 3: Example of design pattern valid for preemptive Single-Core, but not applicable on Multi-Core A last point to consider in the migration has been the training of all the function developers to the new standard. More than 200 developers have been trained in the last 2 years, not only on the code migration but on the whole Multi-Core concept, which means new methods, architecture, and associated tools. On the project side, Project Architects have also been trained to these new concepts.

Fig. 4 :

 4 Fig. 4: Stability & Coherency issues Here again, our solution has 2 facets: At component development time, protection constraints are specified, and at project integration time, the constraints are used to protect the SW.

Fig. 6 :

 6 Fig. 6: Migrated code.

Fig. 8 :

 8 Fig. 8: Project Architecture: Task allocation to cores

Fig. 11 :

 11 Fig. 11: A Runnable Event (Integration Need)

Fig. 12 :

 12 Fig. 12: Integration of Runnables in a taskIn the above picture, we see the Runnables integrated in a task, and their respective Phases.

Fig. 13 :

 13 Fig. 13: Data protection by BufferingAhead of the simple graphical view, all the necessary files for the build process are generated: the buffer fill and flush routines; the redirection of the GET and SET macros in the modules; the task bodies, etc...

Fig. 14 :

 14 Fig. 14: Fill and Flush routines inserted in tasks Then, the bodies of the copy routines are produced:

Fig. 17 :

 17 Fig. 17: Core-wise CPU load (as function of engine rotation speed) after distributionThe different curves correspond to the CPU load of the different cores. This current distribution is only a first step, and under permanent evolution. Thanks to our methodology, we have a high flexibility to reorganize the distribution. Nearly just a question of "drag-and-drop" .

Cooperative scheduling could be called also « controlled preemptive scheduling », as interruption points are fixed at design time.

Might be divided by a factor 3 by means of adequate design pattern. See[START_REF] Claraz | Deterministic Execution Sequence in Component Based Multi-Contributor Powertrain Control Systems[END_REF]