Daniel Kästner

Laurent Mauborgne

Stephan Wilhelm

Christoph Mallon

Christian Ferdinand

Static Data and Control Coupling Analysis

Keywords: data coupling, control coupling, DO-178C, static analysis, taint analysis, program slicing, abstract interpretation, interference analysis, software architecture

niveau recherche, publiés ou non, émanant des établissements d'enseignement et de recherche français ou étrangers, des laboratoires publics ou privés.

Introduction

A failure of a safety-critical system may cause high costs or even endanger human beings. With the unbroken trend towards growing software size in embedded systems more and more safety-critical functionality is implemented in software. Preventing software-induced system failures becomes an increasingly important task. Contemporary safety norms from all industry domains -including DO-178B, DO-178C, ISO-26262, IEC-61508, the FDA Principles of Software Validation, IEC62304, and EN-50128 -require to identify potential hazards and to demonstrate that the software does not violate the relevant safety goals.

Functional safety implies demonstrating the functional correctness: the functional software requirements have to be satisfied. Demonstrating functional correctness can be addressed by requirements-based testing, in particular automatic and modelbased testing, and by formal methods such as model checking or theorem proving. In addition, safety-relevant quality requirements, the so-called non-functional requirements, have to be addressed. Examples of safety-relevant non-functional software requirements are adherence to resource bounds, especially worst-case execution time bounds and stack size, as well as freedom of run-time errors. Runtime errors are typically caused by undefined or unspecified behaviors of the programming language used. In the case of the programming language C they include faulty pointer manipulations, numerical errors such as arithmetic overflows and division by zero, as well as data races, deadlocks, and further synchronization errors in concurrent software.

The data and control flow of the software is of crucial importance for the verification of functional and non-functional correctness properties. In the DO-178C, the verification goal 6.3.3.b (Consistency) demands that "a correct relationship exists between the components of the software architecture. This relationship exists via data flow and control flow." It is complemented by the verification goal of Sec. 6.3.4.b (Compliance with the software architecture) which demands to "ensure that the source code matches the data flow and control flow defined in the software architecture". Obviously the data and control flow of the implemented software must match the intended data and control flow as specified in the software architecture, and unintended data and control flow must be avoided. This also implies demonstrating freedom of interference between software components in mixed-criticality software. According to DO-178C, Sec 2.4.1, if partitioning and independence between software components cannot be demonstrated, all of them are subject to the highest criticality level assigned to any of them. Similar requirements can also be found in ISO-26262 (cf. Sec. 7.4.9 and Annex D of [START_REF]Road vehicles -Functional safety[END_REF]) and other safety norms.

Furthermore, the data and control flow also determines the required effort for functional testing. In DO-178C, Objective 8 of Annex A Table A-7 requires that "Test coverage of software structure (data and control coupling) is achieved", referencing Sec. 6.4.4.2.c which states that structural coverage analysis should "confirm that the requirements-based testing has exercised the data and control coupling between code components". These terms are defined as: Data coupling The dependence of a software component on data not exclusively under the control of that software component.

Control coupling

The manner or degree by which one software component influences the execution of another software component.

The term "software component" is not precisely defined for these requirements. As stated in the CAST19 report [START_REF]Clarification of Structural Coverage Analyses of Data Coupling and Control Coupling[END_REF],

there is currently no established understanding of the granularity of "component", it depends on the architecture being implemented. As a consequence, [START_REF]Clarification of Structural Coverage Analyses of Data Coupling and Control Coupling[END_REF] suggests that certification projects should define what they mean by "component" in their specific architecture for demonstrating compliance to DO-178C.

The intent of structural coverage analysis is to provide a measure of the completeness of the testing process to ensure that requirements-based testing adequately exercised the software program under test [START_REF]Clarification of Structural Coverage Analyses of Data Coupling and Control Coupling[END_REF]. Statement coverage, decision coverage and modified condition/decision coverage (Objectives 5-7 of Table A-7 of [START_REF]Airborne Systems and Equipment Certification[END_REF]) can be addressed at the module level by reviewing test cases and executing requirements-based tests of that module in isolation from other program modules. In contrast, Objective 8 of Table A-7 is primarily intended to be a verification of the integration activity: The intent of the structural coverage analysis of data coupling and control coupling is to provide a measurement and assurance that the software modules/components affect one another in the ways in which the software designer intended and do not affect one another in unintended ways, thus resulting in unplanned, anomalous or erroneous behavior. Hence, satisfying this objective is intended to provide a measure of the completeness of integration verification. As software increases in size and complexity, the quality of data and control coupling analysis is a growing concern for certification authorities [START_REF]Clarification of Structural Coverage Analyses of Data Coupling and Control Coupling[END_REF].

In general, the data and control flow of the software can be determined by semantical static analysis. Semantics-based methods can be further grouped into unsound and sound approaches. Abstract interpretation is a formal method for sound semantics-based static program analysis which provides assurance that there are no false negatives with respect to the classes of defects under consideration. For data and control flow analysis the soundness of the analysis ensures that all potential targets of data and function pointers are taken into account.

This article is structured as follows: In Sec.2 we will give a brief overview of abstract interpretation and illustrate its application to runtime error analysis with the example of the analyzer Astrée. As discussed in Sec. 3 runtime error analysis can be seen as a prerequisite for data and control flow analysis, since it aims at detecting code defects that can corrupt the intended data and control flow. Sec. 4, Sec. 5 and Sec. 6 give a general overview of the core methodologies used in our work: sound global data and control flow analysis, sound taint analysis, and semantically refined program slicing. Based on those methodologies, Sec. 7 presents a novel approach for static data and control coupling analysis and interference analysis, that builds on a specification mechanism for software components appropriate for automatic static code analysis. It augments global data and control flow analysis by the software component level and presents a scalable and automatic taint analysis to determine data and control dependences between software components. Sec. 9 concludes.

Sound Static Source Code Analysis

The term static analysis is used to describe a variety of program analysis techniques with the common property that the results are only based on the software structure. Purely syntactical methods can be applied to check syntactical coding rules as contained in all relevant coding guidelines, including MISRA C/C++ [START_REF] Misra | MISRA-C:2012 Guidelines for the use of the C language in critical systems[END_REF][START_REF] Limited | MISRA C++:2008 Guidelines for the use of the C++ language in critical systems[END_REF], or SEI CERT C/C++ [START_REF]SEI CERT C Coding Standard -Rules for Developing Safe, Reliable, and Secure Systems[END_REF]. A deeper understanding of the code such as knowledge about variable values, pointer targets, etc. requires semantical static analysis. It can be applied to check semantical coding rules which are also contained in the coding guidelines mentioned above, or to identify semantical code defects.

The semantics of a programming language is a formal description of the behavior of programs. The most precise semantics is the so-called concrete semantics, describing closely the actual execution of the program on all possible inputs. Yet in general, the concrete semantics is not computable. Even under the assumption that the program terminates, it is too detailed to allow for efficient computations. Unsound analyzers may choose to reduce complexity by not taking certain program effects or certain execution scenarios into account. A sound analyzer is not allowed to do this; all potential program executions must be accounted for. Since in the concrete semantics this is too complex, the solution is to introduce a formal abstract semantics that approximates the concrete semantics of the program in a well-defined way and still is efficiently computable. This abstract semantics can be chosen as the basis for a static analysis. Compared to an analysis of the concrete semantics, the analysis result may be less precise but the computation may be significantly faster.

Abstract interpretation is a formal method for sound semantics-based static program analysis [START_REF] Cousot | Abstract interpretation: a unified lattice model for static analysis of programs by construction or approximation of fixpoints[END_REF]. It supports formal correctness proofs: it can be proved that an analysis will terminate and that it is sound, i.e., that it computes an overapproximation of the concrete semantics. Imprecisions can occur, but it can be shown that they will always occur on the safe side. Abstract interpretation-based static analyzers provide full control and data coverage and allow conclusions to be drawn that are valid for all program runs with all inputs. Nowadays, abstract interpretation-based static analyzers that can detect stack overflows and violations of timing constraints [START_REF] Souyris | Computing the worst case execution time of an avionics program by abstract interpretation[END_REF] and that can prove the absence of runtime errors and data races [START_REF] Delmas | ASTR ÉE: from Research to Industry[END_REF] [START_REF] Kästner | Finding All Potential Runtime Errors and Data Races in Automotive Software[END_REF], are widely used for developing and verifying safetycritical software [START_REF] Kästner | Applying Abstract Interpretation to Demonstrate Functional Safety[END_REF].

Runtime Error Analysis

At the source code level, the data and control flow of a program might be accidentally affected by unintended behavior, including unspecified and undefined behaviors of the programming language. Hence, a safe analysis of data and control flow must be embedded in a runtime error analysis that captures such undefined/unspecified behaviors.

In runtime error analysis, soundness means that the analyzer never omits to signal an error that can appear in some execution environment. If no potential error is signaled, definitely no runtime error can occur: there are no false negatives. When a sound analyzer does not report a division by zero in a/b, this is a proof that b can never be 0. If a potential error is reported, the analyzer cannot exclude that there is a concrete program execution triggering the error. If there is no such execution, this is a false alarm (false positive).

Throughout this article, we will focus on the Astrée analyzer as an example of sound static runtime error analyzer [START_REF] Kästner | Finding All Potential Runtime Errors and Data Races in Automotive Software[END_REF] [START_REF] Miné | Taking Static Analysis to the Next Level: Proving the Absence of Run-Time Errors and Data Races with Astrée[END_REF]. Astrée's main purpose is to report program defects caused by unspecified and undefined behaviors in C/C++ programs. The reported code defects include integer/floating-point division by zero, out-of-bounds array indexing, erroneous pointer manipulation and dereferencing (e.g., buffer overflows, null pointer dereferencing, dangling pointers), accesses to uninitialized variables, and further sequential programming defects. In addition, Astrée's sound thread interleaving semantics enables it to also report concurrency defects, such as data races, lock-/unlock problems, and deadlocks. Hence, Astrée not only determines the data and control flow within one thread of control, but can also capture interferences between different threads and their effects on the data and control flow within those threads.

Practical experience on avionics and automotive industry applications are given in [START_REF] Kästner | Finding All Potential Runtime Errors and Data Races in Automotive Software[END_REF][17] [START_REF] Kästner | Analyze This! Sound Static Analysis for Integration Verification of Large-Scale Automotive Software[END_REF]. They show that industrysized programs of millions of lines of code can be analyzed in acceptable time with high precision for runtime errors and data races.

Data and Control Flow Errors

The purpose of data and control coupling analysis is to determine the effective data and control flow between software components which might be desired or undesired, depending on the properties of the software architecture. In addition, cases where there is an actual defect in the data or control flow behavior with respect to the semantics of the programming language, must be reported as an error.

In general, Astrée reports defects related to undefined or unspecified behavior of the programming language. Since their behavior is undefined or unspecified, all of them might have an effect on data or control flow -an example is a division by 0, which can cause the program to stop with a trap, obviously causing an unexpected change in control flow. In the following we will give an overview of the alarm classes of Astrée that specifically address memory safety or control flow behavior of the program.

Data Flow Errors

• Out-of-bounds array access: The value of the index used to access an array can be outside the feasible index range.

• Invalid pointer dereference and manipulation: This defect category includes dangling pointer accesses, invalid pointer dereferences and arithmetics, null pointer dereferences, misaligned dereferences, buffer overflows, etc.

• Invalid dynamic memory allocation: Allocation size is negative or too large.

• Memory leak: Memory may not be freed after dynamic allocation.

• Uninitialized variable access: This category includes read accesses of uninitialized local variables and read accesses to global/static variables without explicit initializer or prior assignment.

• Data race: Write-write or read-write data race, i.e. access to the same variable from at least two threads without proper synchronization.

• Spectre vulnerability: Occurrences of Spectre V1, V1.1, or SplitSpectre vulnerabilities.

• Writes to constant memory: Attempts to write to a constant.

• Pointer aliasing: Two pointer variables may alias which have been declared as distinct by the directive ASTREE check separate.

Control Flow Errors

• Non-returning functions: Functions that may never return, e.g. due to infinite loops, calling exit, etc.

• Incompatible function calls: This category includes function calls with wrong number or incompatible types of parameters, incompatible return types, etc.

• Deadlocks: A deadlock occurs when two threads wait for each other indefinitely, e.g. due to blocked resources.

• Recursions: Recursive function calls are reported.

• Infinite loops: This category includes alarms about loops which definitely never terminate, and alarms about loops that might never terminate (e.g. only terminate upon reading a particular value from a truly volatile variable).

• Lock/unlock problems: This category includes attempts to unlock a mutex variable that has not been locked, locks without unlocks, locks acquired by a wrong task, etc.

• C++ Exception: The alarm reports C++ statements that can raise a C++ exception.

• Pure virtual function call: A pure virtual function is called in a specific context (C++).

It is apparent that these defects may invalidate any assumptions about the data and control flow behavior of the program, and hence, must also be considered for data and control coupling analysis. The same may also hold for other cases of undefined/unspecific behavior which are reported by Astrée. Hence sound static runtime error analysis can be seen as prerequisite for data and control coupling analysis. As emphasized in Sec. 2 the defect classes are not limited to sequential program execution but also include program defects induced by concurrent thread execution.

Data and Control Flow Analysis

Classical global data and control flow analysis determines the variable accesses and function invocations throughout program execution. It is centered on concepts included in the programming language, as compared to data and control coupling analysis that focuses on software components which are not expressed by programming language constructs. It constitutes the required basis for data and control coupling analysis. In its basic data and control flow analysis module, Astrée tracks accesses to global variables, static variables, and local variables whose accesses are made outside of the frame in which the local variables are defined (e.g., because their address is passed into a called function). All data and function pointers are automatically resolved. The soundness of the analysis ensures that all potential targets of data and function pointers are taken into account. Astrée's data and control flow reports show the number of read/write accesses for every global, static, and out-of-frame local variable, lists the location of each access and shows the function from which the access is made. All variables are classified as being thread-local, effectively shared between different threads, or subject to a data race (cf. Fig. 1). Variable accesses can be interactively explored, e.g. , by selecting a variable and filtering for accesses from a particular thread or function, or for a given access type. The control flow is described by listing all callers and callees for every C function along with the threads in which they are called. In AUTOSAR projects, additionally the application and the core to which the executing thread belongs is listed. An example is shown in Fig. 2. The control flow can be interactively explored, e.g. , when selecting a function and filtering for its callers or callees or for threads in which it is called, all relevant call sites are displayed. There is also a call graph visualization which can be interactively explored as well (cf. Fig. 3).

In case of C++ programs, a class graph visualization shows a selected class with all its fields and methods as well as its suband superclasses with the relevant template instantiations in a More sophisticated information about selected flows of values can be provided by two dedicated analysis methods: taint analysis and program slicing. Taint analysis is a forward analysis and can answer questions about program parts affected by reading corrupted input values. Program slicing is a backward analysis which can answer questions about the program parts which might influence the value of a particular variable at a particular program point.

All data and control properties described in this section are agnostic of the definition of software components; they are limited to native concepts of the programming language. Lifting this information to the level of software components is the topic of Sec. 7 which leverages the techniques of taint analysis and program slicing described in Sec. 5 and Sec. 6.

Taint Analysis

Taint analysis was first introduced as a dynamic analysis technique (e.g., in PERL), to try to find out which part of a code could be affected by some inputs. The original technique consisted in flipping normally unused bits, that would be copied around by operations and assignments. The same idea can be extended to static analysis by enhancing the concrete semantics of programs with tainting, the formal equivalent of the unused flipped bit in the dynamic approach. In the context of abstract interpretation, it is easy to abstract this extra information in an efficient and sound way, using dedicated abstract domains. Conceptually, taint analysis consists in discovering data dependencies using the notion of taint propagation. Taint propagation can be formalized using a non-standard semantics of programs, where an imaginary taint is associated to some input values. Considering a standard semantics using a successor relation between program states, and considering that a program state is a map from memory locations (variables, program counter, etc.) to values in V , the tainted semantics relates tainted states, which are maps from the same memory locations to V × {taint, notaint}, and such that if we project on V we get the same relation as with the standard semantics.

To define what happens to the taint part of the tainted value, one must define a taint policy. The taint policy specifies:

• Taint sources which are a subset of input values or variables such that in any state, the values associated with that input values or variables are always tainted.

• Taint propagation describes how the tainting gets propagated. Typical propagation is through assignment, but more complex propagation can take more control flow into account, and may not propagate the taint through all arithmetic or pointer operations.

• Taint cleaning is an alternative to taint propagation, describing all the operations that do not propagate the taint.

In this case, all assignments not containing the taint cleaning will propagate the taint.

• Taint sinks is an optional set of memory locations. This has no semantical effect, except to specify conditions when an alarm should be emitted when verifying a program (an alarm must be emitted if a taint sink may become tainted for a given execution of the program).

A sound taint analyzer will compute an over-approximation of the memory locations that may be mapped to a tainted value during program execution. The soundness requirement ensures that no taint sink warning will be missed by the analyzer.

Astrée provides a generic abstract domain for taint analysis that can be freely instantiated by the users. It augments Astrée's process-interleaving interprocedural code analysis by carrying and computing taint information at the byte level. Any number of taint hues can be tracked by Astrée, and their combinations will be soundly abstracted. Tainted input is specified through directives (__ASTREE_taint((var;hues))) attached to program locations. Such directives can precisely describe which variables, and which part of those variables is to be tainted, with the given taint hues, each time this program location is reached. Any assignment is interpreted as propagating the join of all taint hues from its right-hand side to the targets of its left-hand side. In addition, specific directives may be introduced to explicitly modify the taint hues of some variable parts. This is particularly useful to model cleansing function effects or to emulate changes of security levels in the code.

The result of the analysis with tainting can be explored in the Astrée GUI, or explicitly dumped using dedicated directives. Finally, the taint sink directives may be used to declare that some parts of some variables must be considered as taint sinks for a given set of taint hues. When a tainted value is assigned to a taint sink, then Astrée will emit a dedicated alarm, and remove the sinked hues, so that only the first occurrence has to be examined to fix potential issues with the security data flow.

The main intended use of taint analysis in Astrée is to expose potential vulnerabilities with respect to security policies or resilience mechanisms. Thanks to the intrinsic soundness of the approach, no tainting can be forgotten, and that without any bound on the number of iterations of loops, size of data or length of the call stack. Based on its taint analysis, Astrée provides an automatic detection of Spectre-PHT vulnerabilities [START_REF] Kästner | Detecting Spectre Vulnerabilities by Sound Static Analysis[END_REF].

Program Slicing

The following definitions introduce the basic principles of static program slicing. Definition 1 (Slicing Criterion) Let P be a program. A slicing criterion in P is a tuple (s,V ) which consists of a statement s and a set of variables V from P Definition 2 (Slice) A slice S is a subprogram of P that exhibits the same behavior with respect to the slicing criterion (s,V ).

Computing a statement-minimal slice is an undecidable problem. However there are well-established algorithms for computing non-minimal, but still useful slices. A common approach is to compute a System Dependence Graph (SDG), which contains all data and control dependences of the program. Then a slice can be expressed as a reachability problem in this graph [START_REF] Horwitz | Interprocedural slicing using dependence graphs[END_REF]. The precision of the slice directly depends on the precision of the SDG. However, computing precise system dependency graphs is a non-trivial task since it requires deriving intricate program properties. These may include points-to information for variable and function pointers, code reachability, context information or possible variable values at certain program points. As an example, over-approximating the set of possible destinations of a pointer variable blows up the size of the system dependence graph as it may add false dependences to statements which contain variables that would otherwise not be included in the slice. This may cause a drastic transitive increase in the number of dependences and vertices.

Astrée provides a novel concept of program slicing, that can be termed sound semantically refined slicing: its slicer can be run in the sequel of a finished Astrée analysis run, which makes it possible to leverage the invariants computed by its main fixpoint analysis. The system dependence graph computed by our approach is a sound abstraction of the data-and control dependences of a computer program. This follows from the soundness of the Astrée core analysis. As a consequence, the resulting slices are also sound. Minimizing false alarms is an important design goal of Astrée, which mandates a highly precise point-to analysis. Furthermore, Astrée detects code which is guaranteed to be unreachable for any possible program execution, and which, consequently, can be ignored when computing the slices. Hence, compared to slicing without leveraging Astrée invariants, a significant precision and efficiency gain is achieved by reducing the amount of vertices and the amount of data-and control dependences in the system dependence graph. This efficiency improvement makes it possible to compute precise slices for very large programs in feasible time.

Semantically refined slicing can be run in context-insensitive mode (considering all possible call contexts) and contextsensitive mode (considering exactly one call context). To compute context-sensitive slices we enhance the slicing algorithm of [START_REF] Horwitz | Interprocedural slicing using dependence graphs[END_REF] with a description of call contexts (stacks). In each step of the reachability analysis we additionally check that the de- In contrast to context-insensitive slices, context-sensitive slices do not capture all possible behaviors of the original program which influence the slicing criterion. Instead, the behavior described by the slice is restricted to execution paths which are in accordance with the set of considered call contexts. Context-sensitive slices tend to be significantly smaller than context-insensitive ones.

The different slicing modes presented in this section are relevant for demonstrating safety and security properties. Sound slices can be computed by context-insensitive analysisenhanced slicing. With these slices it is possible to show that certain parts of the code or certain input variables might influence or cannot influence a program section of interest. They yield a global overview of these properties for the entire program.

In contrast to that, context-sensitive analysis-enhanced slicing, which only considers a subset of possible contexts, is more suitable for investigating the influence of a certain code section, e.g. a function, or a module, on the program location of the slicing criterion. Hence it is perfectly suited as a basis for automatic alarm slicing, which is available in Astrée. To give an example, the critical situation for a division by zero alarm, which is reported for a given context, is precisely the context where the denominator becomes 0. Therefore the alarm slice is a partial slice for the variables used in the denominator, which only considers program paths leading to this particular context. This concept of alarm slicing has been implemented in Astrée and is available from the GUI: from the context menu of an alarm in the Astrée graphical user interface the computation of a slice for the alarm can be automatically triggered, as shown in Fig. 5.

A detailed experimental survey of Astrée's semantically refined program slicer with programs from automotive and avionic industry is given in [START_REF] Kästner | Advanced Sound Static Analysis to Detect Safety-and Security-Relevant Programming Defects[END_REF]. It demonstrates that semantically refined slicing (termed analysis-enhanced slicing in [START_REF] Kästner | Advanced Sound Static Analysis to Detect Safety-and Security-Relevant Programming Defects[END_REF]) can be applied to industry-size code with high precision and with feasible memory and computation time requirements.

Data and Control Coupling

The CAST19 report [START_REF]Clarification of Structural Coverage Analyses of Data Coupling and Control Coupling[END_REF] reviews the data and control coupling requirements of the DO-178C and provides clarifications about the intended use. It emphasizes that the purpose of data coupling analysis includes (among others) identifying data dependences, verifying the data interfaces between modules/components through testing and analyses, identifying inappropriate data dependencies, evaluating the need for and accurate use of global data, and evaluating input/output data buffers.

The purpose of control coupling is stated to include identifying control dependencies, identifying inappropriate control dependencies, verifying correct execution call sequence, defining and evaluating the extend of interface depth, and assisting in WCET analysis.

In addition, as outlined above, data coupling and control coupling together aim at providing a completion check of the integration testing effort. The CAST19 report further clarifies that the "Data Coupling and Control Coupling Analyses" objective of the DO-178C (Objective 8 of Annex A, Table A-7 [START_REF]Airborne Systems and Equipment Certification[END_REF]) may be satisfied as a static activity, a dynamic activity, or a combination.

In the following we propose a concept for sound static data and control coupling analysis that builds on Astrée's data and control flow analysis as described in Sec. 4, and which satisfies all requirements mentioned above. First, in Sec. 7.1, we present a flexible and extensible concept for specifying software components and critical data and control flow interactions between them. Sec. 7.2 outlines static data and control flow analysis augmented by the concept of components. Sec. 7.3 presents an automatic taint analysis that efficiently tracks the flow of values between components, and automatically reports undesired data flow and undesired control dependencies. In case of taint sink alarms indicating undesired data or control flow, alarm slicing can be used to track down the cause of the undesired behavior.

Specifying Software Components

Since there is no established understanding of the granularity of "component", a specification mechanism is needed that allows users to specify their concept of software components and the "interesting" data or control flow between them. For the purposes of data and control coupling, the full power of special-purpose architecture description languages (ADL) is not needed (cf. AADL [START_REF] Feiler | Technical Note[END_REF], ArchiMate [START_REF]The ArchiMate Enterprise Architecture Modeling Language[END_REF], SysML [START_REF]OMG Systems Modeling Language (OMG SysML™) Version 1.6[END_REF], or UML-based architecture specifications), since the aim is to ascertain the desired properties by automatic static analysis from the source code.

A simple starting point is to define a software component as a collection of all variables and functions defined in a set of source files. This can be provided by (conceptual) annotations of source files or functions: "xfile1.c" insert : __ASTREE_attributes((component("trusted"))); "yfile1.c" insert : __ASTREE_attributes((component("non-trusted")));

This schema can be easily extended to more complex component definitions, e.g., based on individual functions, all files in a sub-directory, etc.

In addition to defining the elements of a software component, the specification also allows to declare component interactions that should be "observed" during the analysis, i.e., specifically tracked and reported. To this end, the analyzer can be instructed to report control and data flow from the component "trusted" to the component "non-trusted", and vice versa: <observe> <item key="trusted">"non-trusted"</item> <item key="non-trusted">"trusted"</item> </observe> A dedicated view in the graphical user interface of Astrée allows to conveniently create the software component specification, and then export them to an XML file. Alternatively, the XML file may also be generated automatically from an existing ADL specification.

The specification of component interactions to be observed mostly aims at explicitly reporting unexpected or forbidden interactions. By placing components with expected interactions under observation, Astrée can also address intended interactions, however, in that case, the result of Astrée only contributes potential interactions due to its sound over-approximation: a reported component interaction can also be a "false alarm". A dedicated tag to support simultaneous tracking of unexpected and intended interactions is currently not available but could be easily added.

Augmented Data and Control Flow Analysis

The first step towards detecting and reporting data and control flow relations between software components is to enhance the standard data and control flow analysis by taking the component definitions into account, which we term augmented data and control flow analysis.

The augmented data and control flow analysis of Astrée will thus report any interaction between two software components of the following classes:

• Calling a function of a given component, including indirect calls through pointer dereferences.

• Writing to a variable defined in a given component, which can be a global variable that belongs to the component or a local variable defined in a function of the component. That includes indirect writes through pointer dereferences.

• Reading from a variable defined in a given component. That includes indirect reads through pointer dereferences.

These interactions already capture most interferences between components, including indirect ones, such as scenarios when the address of a variable of component A is stored in component C, and then read from C by component B which writes to it through dereference. They will not capture more subtle value dependencies, such as component C copying the value of a global variable of component A, store it in one of its variables and then give the value to component B that may take different control flow based on that value. To track such interferences, we need to follow the flow of values, and we can do that using taint analysis techniques -cf. Sec. 7.3.

The data and control flow views in the Astrée GUI presented in Fig. 1 and Fig. 2 of Sec. 4, and the corresponding data and control flow reports will be augmented by additional columns which make the component assignment explicit. Each access to a variable X then is reported with the following information in the data flow view:

-variable name -component to which the variable belongs -location of access (may be pointer dereference) -access type (read/write) -function containing the access -component to which the accessing function belongs -task in which the accessing function is executed -application of task -core to which application has been assigned -access locality (thread-local, effectively shared, data race) -notification for components under observation Each function call is reported with the following information in the control flow view:

-caller -component of caller -callee -component of callee -call site (may be function pointer call) -task in which the call is executed -application of task -core assigned to application -notification for components under observation The data and control flow reports can be generated in various open formats that support post-processing, so it is easy to query for any component interaction of interest. If a flow from a component X to a component Y has been introduced with an observe tag in the component specification, a dedicated notification is generated about any observed flow from X to Y.

Also the visualizations of Fig. 3 and Fig. 4 will be augmented by component information so that it will be possible, e.g., to highlight the nodes for selected components, or show different components in different colors.

This mechanism gives a sound overapproximation of all variable accesses and function calls, and establishes their link to the software component definition. It makes it easy to spot flows under observation, hence call attention to flows that should be investigated.

Data and Control Coupling Analysis

As outlined in Sec. 5, taint analysis allows to track the flow of values in a project. One solution to compute data dependencies between components is to assign a distinct taint hue to each component, and use all global and local variables of a component as taint source with the component hue. To be automatically notified about all components where these values flow, all reads in each component are declared as taint sinks for all other components hues. The required __ASTREE_taint and __ASTREE_taint_sink directives can be generated automatically. To focus on particular component interactions, the automatic generation of taint source and taint sink directives can be restricted to only those component flows placed under observation, which reduces the number of taint sink alarms about component dependences. Of course, it is also possible to manually select specific component flows to observe, or perform the taint analysis on a per-variable base for individual variables deemed critical.

This approach not only detects additional interferences compared to the augmented data and control flow analysis, it also allows to account for authorized interactions in a fine-grained way. One example is that data flow from component Y to X is forbidden, unless the access is made by specific gateway functions. Such interactions can be modeled by taint-cleaning operations which remove the taint in those gateway functions (sanitization points), reducing the number of legitimate interferences that need to be examined. To further facilitate this examination, automatic alarm slicing on taint sink alarms can be used to help identify the program regions responsible for undesired component interactions.

In addition to the data flows reported by the automatic tainting as described above, taint analysis also allows to focus on control coupling. The generation of taint sink directives can be adapted, so that only values used in guards (for conditional statements, while loops or switch statement) and in function pointer dereferences are considered as taint sinks.

Hence, the taint analysis of software components can be performed in data coupling and control coupling mode, satisfying the requirements of the CAST19 report as described above.

It should be noted that taint analysis is a complement to the augmented data and control flow analysis (cf. Sec. 7.2), but cannot replace it, since it focuses on the data flow aspect and does not report invocations of functions from other components. Its data flow results are more powerful: taint analysis can keep track of call-by-value parameters of functions and of function return values and hence report dependences with respect to constants or local variables. It not only shows that at a certain location a given variable is accessed, but also provides the corresponding call context -as an example, if a function is called with a pointer argument, and only in one call site an address of a variable from another component is passed, then the alarm context will show precisely this call site. Furthermore, it makes it possible to narrow the focus on selected component interactions and tracks the relevant data flows also through code that does not belong to one of the components under observation. Both of them together, i.e. , the combination of augmented data and control analysis and the taint analysis for software components provide a sound interference analysis. They report all interactions between software components executed in one or multiple concurrent threads, pinpoint interactions under observation, hence enable users to find undesired interactions, and browse the code locations where they happen. They also provide a basis for checking intended interactions and allow computing metrics about the data and control flow between the software components.

As an example, consider the following code sequence: The augmented data and control flow analysis provides the information that component C depends on A through variable read and function call, since F_c reads variable g_a and calls function F_a. Component tainting raises four taint sink alarms: first it reports that component C depends on A at the assignment g_c=g_a in F_C, which is information also available in the augmented data flow view. It also reports a dependence from A to C at g_c = F_a(3); in F_C because the return value of F_A is assigned to g_c. This is more precise information than provided by the augmented control flow view which just reports a call to a function from C at this location. Third, the taint analysis reports a dependence from C to A at the assignment y=x in F_a, since C passes a constant value to F_a, which then is assigned to a local variable of A. Finally, the component tainting reveals that component B depends on component A through variable x: a taint sink alarm is raised at the assignment g_b = x in main.c, which is outside of components A, B, and C. Note that in the example, all variables are directly accessed, however, the analysis results would not change if all variable accesses and function calls were made via pointers.

Experimental Results

The augmented data and control flow analysis is part of the sound runtime error analysis, hence, it is not associated with additional runtime or memory overhead.

To assess the performance of the taint-based components analysis we investigated four industry projects of various sizes, two from the avionics domain and two from the automotive domain. We partitioned the code in software components and determined the increase in analysis time and memory consumption caused by component tainting. Tab. 1 shows the character-istics of the projects, the results obtained with component tainting are summarized in Tab. 2. Column S of Tab. 1 gives the size of the projects in million physical lines of code 1 after preprocessing, column N C indicates the number of software components. The large number of software components in project AE2 results from declaring every application source file as an own component; in the other projects the components consist of larger code parts. Column T and M show the analysis time and memory consumption in their original configuration.

Project show that the overhead of component tainting is low. The increase in memory consumption is below 1% for all test cases except AE2. For AE2 an extremely high number of components has been defined, which also entails a large number of component interactions: there are 78283 alarms about variable accesses creating component dependencies (cf. Tab. 3). However, even in that scenario the memory overhead is only 4.76%.

The increase in analysis time is between 4.93% and 8.07% for the larger projects. The largest increase of 8.07% occurs in project AU2, where the analysis time increases by 45 min from a total analysis time of 10 hours 44 minutes. On the smallest project, AE1, there is no measurable difference in memory consumption. Taint sink alarms for component dependences can be limited to flows under observation. However, in the experiments, we configured Astrée to generate taint sink alarms for every crosscomponent flow, since the goal was to assess performance on large projects with many component interactions. The number of cross-component variable accesses derived from the augmented data flow view is listed in column N V of Tab. The difference between columns N V and N TA , on the one hand, is due to additional dependences discovered by tainting, e.g., due to values passed through library functions not assigned to a specific components, call-by-value function parameters and function return values. On the other hand, as discussed in Sec. 7.3, component tainting focuses on data dependences and tracks the effect of all function calls, but does not separately report the calls themselves. The effect of infrastructure code without component assignment is particularly visible in project AE2. The components do not explicitly invoke one another, the invocations are made in an infrastructure layer we did not assign to an own component. Dependencies carried through that infrastructure layer, e.g., by copying component variables via infrastructure variables, are visible with component tainting, but not in the augmented data flow view.

Project

Project

Conclusion

At the source code level, the data and control flow of a program might be affected by behavior unintended by the programmer, including unspecified and undefined behaviors of the programming language. Hence, a safe analysis of data and control flow must be embedded in a runtime error analysis that captures such undefined/unspecified behaviors. Determining the data and control flow in the source code and making sure that it is compliant to the intended control and data flow as defined in the software architecture is a common requirement in all contemporary safety norms. The aim of data coupling and control coupling analysis objective of DO-178C is to provide a measure of the completeness of integration verification by ensuring that the software components affect one another only in intended ways. Furthermore all safety norms require demonstrating the freedom of interference between software components of different criticality levels.

In this article we have presented a novel approach for data and control coupling analysis and interference analysis, that builds on a specification mechanism for software components appropriate for automatic static code analysis. It is based on the sound static analyzer Astrée that allows to prove the absence of critical runtime errors that could cause memory corruption and control flow corruption. Our approach augments sound global data and control flow analysis by the software component level, proposes a scalable and automatic taint analysis to determine data and control dependences between software components, and incorporates semantically refined program slicing to help identify the program regions responsible for undesired component interactions. It enables a sound approximation of data and control coupling and a sound interference analysis that help demonstrating the correctness of the data and control flow of the program and contribute to satisfying the data and control coupling and freedom of interference verification goals of contemporary safety norms. The experimental results show that our approach is highly efficient and can be applied to industrysize software projects.

Figure 1 :

 1 Figure 1: Astrée's Data Flow View.

Figure 2 :

 2 Figure 2: Astrée's Control Flow View.

Figure 3 :

 3 Figure 3: Astrée's Call Graph Visualization.

Figure 4 :

 4 Figure 4: Astrée's Class Graph Visualization.

Figure 5 :

 5 Figure 5: Alarm Slicing in Astrée

  3, column N C gives the number of cross-component function invocations, and the number of taint sink alarms denoting cross-component data flows is listed in column N TA . All numbers indicate the number of code locations which exhibit a cross-component interaction, e.g., all accesses to a variable g A of component A from component B are separately counted. 1 I.e., comment lines and empty lines are not counted.

Table 1 :

 1 Project CharacteristicsColumn T t and M t of Tab. 2 show the analysis time resp. memory consumption with component tainting. The increase in analysis time and memory consumption associated with component tainting is given in column ∆ T resp. ∆ M . The results

		S [MLOC]	N C	T	M [GB]
	AE1	0.14	11	33m	2.43
	AE2	1.08	4309 8h 27m	15.53
	AU1	5.46	11	7h 1m	39.81
	AU2	5.03	35 10h 44m	31.52

Table 2 :

 2 Results with Component Tainting

		T t	M t [GB]	∆T	∆M
	AE1	33m	2.43	0%	0%
	AE2	8h 52m	16.27	4.93% 4.76%
	AU1	7h 24m	40	5.5% 0.48%
	AU2	11h 36m	31.78	8.07% 0.82%

Table 3 :

 3 Code locations with cross-component interactions

		N V	N C	N TA
	AE1	147	289	415
	AE2	40929	0 78283
	AU1	9569 1695 10285
	AU2	8485 4242 16852


Jules Sery
email: jules.sery@ifpen.fr

Pierre Leduc

Fuel cell behavior and energy balance on board a Hyundai Nexo

Keywords: Fuel cell vehicle testing, hydrogen consumption measurement methods, fuel cell system energy balance

Hydrogen fuel consumption measuring methodologies of a fuel cell vehicle without modifying the fuel path has been tested and benchmarked. In this work, they are applied to a Hyundai Nexo fuel cell electric vehicle driving different mission profiles on a chassis dynamometer. Three methods respectively based on hydrogen tank pressure, tailpipe oxygen concentration, and IR-shared (infrared) tank data are compared to the reference method relying on fuel cell current measurements. In addition to the hydrogen fuel consumption results, the installed electrical measuring equipment made possible to yield the fuel cell efficiency map at both stack and system levels as well as the energy consumption of its balance-of-plant (BoP) components during steady-state operation. A maximum steady-state efficiency of 66.8% is reported along with a rated system power of 82 kWe involving a 9.1-kWe power consumption for the electric compressor. It is shown that the compressor and the 12-V accessories are the most energy consuming devices among the BoP components accounting for 2%-3% of the total electric energy generated by the fuel cell. Furthermore, the behavior of the powertrain system is monitored and discussed during warm-up phases and during a long idling period. Finally, based on non-intrusive temperature measurements, a short analysis is conducted about the temperature impact on the fuel cell efficiency.

Introduction

Associated to a low-carbon electricity generation, electric vehicles account for one of the major ways toward a decarbonized transport for the future. [START_REF]Energy technology perspectives[END_REF][START_REF]Global EV Outlook[END_REF] As far as road transport is concerned, two types of electric vehicles can be considered: pure battery or with a hydrogen fuel cell. The later technology is generally seen as offering higher range and faster refueling/recharge and, for trucks, to an increased freight capacity. On the other hand, its total value chain energy efficiency is dramatically less: with the same amount of grid electricity, a battery electric vehicle (BEV) will drive at least 2 to 3 times longer trips than the equivalent fuel cell electric vehicle (FCEV) [START_REF] Bodineau | Rendement de la chaîne hydroge`ne -cas du power-to-H2-to-power[END_REF][START_REF] Bmw | Hydrogen fuel cell cars: everything you need to know[END_REF][START_REF]Efficiency compared[END_REF] This is due to the energy consumption needed to produce and transport the hydrogen before it can be used to refill a vehicle and also to a lower powertrain efficiency. Then, from a tank-towheel perspective, it is of paramount importance to analyze the energy consumption of FCEVs and how the electricity is used on board, in order to continue the optimization of this part of the value chain.

Hydrogen Fuel Cell Electric Vehicles can be seen as parallel hybrid vehicles with the engine being replaced by a fuel cell. In the Hyundai Nexo the 95-kW fuel cell stack takes the role of the prime mover whereas the 1.56 kWh Li-ion battery purpose consists in helping the fuel cell during transient loads as well as during low loads. More importantly it unlocks regenerative braking opportunities. [START_REF] Daud | Pem fuel cell system control: A review[END_REF][START_REF] Hong | invited) recent advances in fuel cell electric vehicle technologies of hyundai[END_REF] The fuel cell system consists of a stack operating with other components (air compressor, humidifier, cooling system, etc.) called BoP (Balance of Plant) when considered as a whole. [START_REF] O'hayre | Fuel Cell Fundamentals[END_REF] It is of interest to investigate the power consumption of each component to draw an exhaustive energy balance of the vehicle powertrain on various mission profiles.

To supply the fuel cell with hydrogen, three high pressure tanks are located under-floor at trunk level. This hydrogen storage system is capable of holding 6.33 kg of compressed gas at 70 MPa under nominal conditions. The vehicle powertrain architecture is illustrated in Figure 1.

Hydrogen-powered vehicle testing necessarily involves the use of a specific method to measure the fuel consumption. WLTP standard advocates for employing the gravimetric method which requires using external hydrogen storage tanks. [START_REF]United nations global technical regulation on worldwide harmonized light vehicles test procedures (WLTP)[END_REF] Those tanks are weighted before and after the test to determine the average fuel consumption over the test. Alternatively, manufacturers can opt for two different methods provided that they can prove them to be sufficiently accurate. Those two methods are respectively the pressure method and the flow method. Along with the gravimetric one they are the recommended normative methods in ISO 23828 and SAE J2572 standards. [START_REF]Fuel cell road vehicles -energy consumption measurement -Vehicles fueled with compressed hydrogen[END_REF][START_REF] Sae | Recommended practice for measuring fuel consumption and range of fuel cell and hybrid fuel cell vehicles fueled by compressed gaseous hydrogen[END_REF] Pressure method is based on the measurement of both tank pressure and temperature. Assuming that the tank volume is known, the fuel consumption can be easily derived. The flow method requires measuring the hydrogen flow by using a dedicated sensor placed somewhere inside the fuel path (e.g. a Coriolis mass flow sensor as recommended in SAE J2572). Except for the pressure one all of the last cited methods require very intrusive instrumentation or the use of external specific device. Another method, investigated in this paper, consists in measuring the oxygen concentration at exhaust to determine hydrogen consumption. [START_REF] Kuroda | An oxygen balance method: Fuel consumption measurement for fuel cell vehicles based on exhaust emissions with no vehicle modification[END_REF] In this paper a method based on the fuel cell current measurement has been set up to be used as a reference. In parallel the pressure method has been tested thanks to the signal derived from the hydrogen tank pressure sensor. In order to improve accuracy a tank model is used to calculate hydrogen gas temperature evolution throughout the driving cycle to correct the hydrogen mass derived from the hydrogen equation of state (EoS). Furthermore, a module, dedicated to communication with the hydrogen tanks through the infrared emitter located at fueling nozzle level, was developed for this work. The tank pressure and temperature could be then monitored but only with vehicle ''ignition'' off.

Various driving cycles have been run on a chassis dynamometer with a dedicated instrumentation of the fuel cell system to investigate the performances and the fuel consumption of the vehicle on a variety of use cases including a long idling period.

The literature on fuel cell vehicle chassis dynamometer testing is far from abounding. In 2018 Argonne U.S. DOE laboratory exhaustively tested a Toyota Mirai on a roller test bench. [START_REF] Lohse-Busch | Technology assessment of a fuel cell vehicle: 2017 Figure 18[END_REF][START_REF] Lohse-Busch | Automotive fuel cell stack and system efficiency and fuel consumption based on vehicle testing on a chassis dynamometer at minus 18 °C to positive 35 °C temperatures[END_REF] An on-road evaluation of several FCEVs was performed by NREL [START_REF] Kurtz | Fuel cell electric vehicle 2016 annual merit review[END_REF] but with anonymized and normalized data. Green NCAP [START_REF] Greenncap | Nexo vehicle testing[END_REF] tested a Hyundai Nexo over different driving cycles and published associated fuel consumption results. Yet no details regarding fuel cell system efficiency values and energy balance were reported.

Chassis dynamometer test campaign

Vehicle instrumentation

Electrical currents have been measured in the electric powertrain for the following components: The different clamp-type current sensors have been connected to an electrical Power Analyzer Hioki Ò PW3390 (except for the fuel cell stack). All the BoP components are supplied with the voltage produced by the fuel cell. Thus, measuring the fuel cell stack voltage as well as electrical currents listed above is sufficient to draw quite-complete component-wise energy balances. It is noteworthy to point out that the communication with vehicle through its OBD-II interface could not be achieved during this testing campaign.

Besides the electrical instrumentation that was carried out on the electric powertrain, the hydrogen pressure was collected from the original vehicle sensor by reverse-engineering of its transfer function. The temperature was measured at three levels (Figure 2): Tank envelope (T 1 ). Tank inlet/outlet pipe (T 2 ). Tank bottom nozzle, a metallic part in contact with the gas (T 3 ).

To monitor vehicle warm-up three temperatures were measured at fuel cell system level using type T thermocouples:

Fuel cell housing surface (T fc ). Cooling pump housing (T cp ). Radiator fins (T rad ).

Measuring actual coolant temperature at stack level would have been too much intrusive with respect to study security constraints. Yet, T cp turned out to be the closest to fuel cell expected temperature ;80°C.

All the study measurements were recorded at 10 Hz.

Tests carried out on chassis dynamometer

The study involved various driving cycles in order to investigate the vehicle performances on multiple use types such as typical driving conditions, urban, and dynamic driving, highway driving and fuel cell efficiency mapping cycle. The following driving cycles were tested twice to achieve repeatability on a chassis dyno (where not specified temperature is 23°C) (Table 1):

The vehicle road-load parameters and mass were taken as being equal to the settings employed for the approval WLTC cycle (Table 2).

Fuel consumption measurement methods

The reference method: Fuel cell current-based Each electron produced by the fuel cell basically comes from the consumption of a proton H + at the catalytic layer level of the membrane electrode assembly (MEA). One can derive a direct relationship between the current flowing through one cell of the stack and the corresponding amount of hydrogen mass flow. Knowing the cells number, it yields the hydrogen mass flow rate:

_ m H 2 = I stack N cell M H 2 nF ð1Þ
With M H 2 [g/mol] the hydrogen molar mass, n the number of mole of electron per mole of H 2 consumed, F [C/mol] the Faraday constant, I stack [A] the stack current and N cell the number of cells (=440). Inconvenience of this method lies in the fact that it cannot account for any possible hydrogen purge operated at anode side. Likewise, any hydrogen leakage through the fuel cell membrane cannot be quantified using this method.

Yet, without considering hydrogen purges impact on fuel flow, this method constitutes a good reference and a robust way of evaluating instantaneous hydrogen flow and consequently of reporting fuel consumption. Indeed, system operation is usually done suchlike the anode pressure is always above cathode one so that to mitigate nitrogen and water vapor permeation through the membrane. This generally reduces the need to purge the anode. [START_REF] Peng | Hybrid dynamic modeling-based membrane hydration analysis for the commercial high-power integrated PEMFC systems considering water transport equivalent[END_REF] The pressure method Taking advantage of pressure measurements, the hydrogen mass trapped in the tanks can be instantaneously derived using the gas EoS. Even though the internal temperature cannot be recorded, an approximation based on a thermodynamic model of the hydrogen tank is calculated. Assuming that the hydrogen temperature is uniform inside the tank and invoking the hydrogen EoS, one can apply the conservation of energy to the tank:

m H 2 c v dT dt = _ m H 2 c p À c v À Á T + GS tank T 1 À T ð Þ ð2Þ
PV tank = Zm H 2 rT ð3Þ
With T [°K] being the equivalent hydrogen temperature in tank, m H 2 [kg] the hydrogen mass trapped into the tank, V tank [m 3 ] the volume, P [Pa] the tank pressure, Z [-] the compressibility factor, c p and c v [J/°K/ kg], respectively the constant pressure and volume heat capacities and GS tank [W/°K] the global heat exchange coefficient. Thermodynamic properties (c p , c v , Z) are determined using CoolProp, [START_REF] Bell | Pure and pseudo-pure fluid thermophysical property evaluation and the open-source thermophysical property library coolprop[END_REF] a C + + library (a Python wrapper was used) offering calculation capabilities of physical properties for various fluids including hydrogen. The model is implemented and solved using the Python SciPy library ODE solver featuring an explicit Runge-Kutta numerical integration method. To determine the global heat exchange coefficient GS tank a sequenced tank recharge has been carried out in a hydrogen station. The same model as described above, but considering _ m H 2 as being equal to zero, has been fitted to the pressure measurements during tank resting periods (Figure 4).

Values ranged from 50 to 80 W/°K. Uncertainties in these results originate from the different hydrogen flow regimes that are encountered inside the tank. Therefore, depending on the regime, the heat exchanged by natural convection occurring at internal wall level will vary in intensity. Similarly this coefficient is subject to variation depending on the mass flow rate at which hydrogen exits or enters the tank. For the sake of simplification it is considered that GS tank is a constant equal to 70 W/ °K.

For all the tests run on the roller test bench both current and pressure methods were used to compare their results in terms of fuel consumption.

The IR-PT method

In order to optimize the hydrogen tanks fueling strategy the FCEVs are usually equipped with an IR emitter at fueling nozzle level. This emitter provides the fueling station with some data related to the tank type as well as further physical measurements such that tank pressure, temperature, and volume. The communication protocol follows the SAE J2799 standard. [START_REF] Sae | Hydrogen surface vehicle to station communications hardware and software[END_REF] This protocol has been implemented within an infrared IR module specifically developed for this study. Nevertheless the vehicle was found to communicate only with the ignition turned off. Consequently, measurements were made just before and after a test to determine the difference in hydrogen pressure and temperature. Using the hydrogen EoS and knowing the tank volume it is then possible to calculate a normative fuel consumption that complies with the SAE J2572 standard pressure method. Yet, even though results are expected to be close to the pressure method ones, they could deviate depending on the tank temperature sensor location (this location could not be identified in the vehicle).

The O 2 method

Oxygen concentration was measured at exhaust level using an oxygen analyzer (magneto-pneumatic detection type). Exhaust gas flow was measured using a Pitot tube at vehicle tailpipe along with pressure and temperature. All the flow outlets upstream the measuring equipment were blocked to ensure that the measure yields the actual flow rate. Knowing the fuel cell oxygen consumption it is possible to determine the hydrogen one. Yet, this method suffers from the same inconvenience as the fuel cell current-based method in that it cannot account for hydrogen purges and leakages. Indeed, the oxygen consumption is a direct image of the part of consumed hydrogen which participated to the electron creation (equation ( 5)). Oxygen consumption is determined following equation ( 4):

_ m O 2 = r O 2 20 o C, 1 atm ð Þ Q air X O 2 , lab À X O 2 , tp, s À Á ð4Þ
_ m H 2 = 2 M H 2 M O 2 _ m O 2 ð5Þ
With Q air [Nm [START_REF] Bodineau | Rendement de la chaîne hydroge`ne -cas du power-to-H2-to-power[END_REF] /s] being the measured flow rate at normal conditions for temperature and pressure (20°C, 1 atm), X O 2 , lab [-] the oxygen concentration in the laboratory, X O 2 , tp, s [-] the time-shifted oxygen concentration at tailpipe and M O 2 [g/mol] the oxygen molar mass.

The calculated oxygen mass flow rate has to be shifted in time [START_REF] Kuroda | An oxygen balance method: Fuel consumption measurement for fuel cell vehicles based on exhaust emissions with no vehicle modification[END_REF] knowing the measured flow rate and the exhaust pipes total volume V p [m 3 ] upstream the gas analyzer. Indeed the pipes volume induces a time lag t [s] between the oxygen consumed at fuel cell level and the one measured at tailpipe level. This time lag is such that the following equation ( 6) is verified:

V p = ð t + t t Q air t ð Þdt ð6Þ
X O 2 , tp, s t ð Þ = X O 2 , tp t + t t ð Þ ð Þ ð 7Þ
The exhaust pipes total volume was approximated based on pipes diameter and length at V p = 16L. Figure 6 shows fuel consumption results yielded using the four above-described methods on WLTC cycles. Both IR-PT and pressure methods give higher hydrogen consumption as compared to fuel cell current-based method and O 2 -method. Differences are very likely to lie in the fact that hydrogen purges are accounted for in IR-PT and pressure methods. Discrepancies between IR-PT and pressure methods might be explained by the temperature which is considered to determine the hydrogen mass trapped in tanks. Indeed pressure method relies on an estimated hydrogen tank temperature (see related section) whereas IR-PT method involves a temperature measurement at tank level.

Hydrogen consumption measuring methods comparison

Fuel cell system efficiency measurements

During the FC cycle the vehicle was subject to a sequence of increasing constant loads. The measurements were averaged over a time window upon which the fuel cell and all BoP components reached steadystate operation. Furthermore time windows sizes were adapted so that the HV battery was no longer found to supply any current. Fuel cell efficiency at stack level and at system level is defined as follows:

h stack = V stack I stack _ m H 2 LHV ð8Þ
h FCS = P stack À P BoP _ m H 2 LHV ð9Þ
With V stack [V] being the stack voltage, P stack [kW] the fuel cell stack power and LHV [J/kg] the hydrogen higher heating value. The BoP power consumption is calculated leveraging equation (10).

P BoP = P eComp + P heater + P fans + P c, pump ð10Þ
With P eComp [kW] being the eCompressor power at inverter level, P heaer the fuel cell stack coolant heater power, P fans the fans DC motors power and P c, pump the coolant pump power. The stack voltage was measured installing an electrical contact at the direct output of the fuel cell. The reference current method was used to determine the hydrogen consumption _ m H 2 (Figures 789).

At maximum wheel power reached on steady-state operation of the dynamometer, a fuel cell power of 82 kWe was measured at system level and 94 kWe at stack level. The corresponding efficiencies were respectively equal to 48% and 54.4% with respect to hydrogen LHV. The maximum fuel cell efficiency is found to be 66.8% at system level and 67.5% at stack level. This maximum efficiency is located at 8-10 kWe system power which roughly translates to 10% of maximum system power. Additionally, the electric air compressor consumed up to 9.1 kWe (Figure 13). The electric coolant pump was responsible for 600 We of BoP power consumption on maximum power point. Below 50 kWe its contribution was negligible (\ 200 We). Above 40 kWe power the fans motors consumption started to significantly increase: starting from 200 We and soaring up to 1.8 kWe on maximum load points.

Fuel consumption measurements

Comparison of pressure and current methods

This work was split in two different testing campaigns separated by a four-month period. The IR module only worked for WLTC cycles in Figure 6 corresponding to the second testing campaign. Thus for the other tests the initial tank temperature was considered to be equal to T 3 . Figure 12 compares the evolution of hydrogen mass in tank for three model settings: isothermal (constant hydrogen temperature no matter what), adiabatic (no heat exchange with environment) and with heat exchange (GS tank = 70 W/°K). These first 2 incomplete model settings respectively overestimate and underestimate hydrogen mass consumed throughout the cycle. Accounting for heat exchange turns out to yield the closest results to the reference fuel cell current-based method. Regarding temperature measurements T 3 revealed to be the closest to hydrogen temperature with a decreasing tendency. Conversely, T 1 and T 2 measurements revealed to be increasing, regardless of hydrogen temperature evolution, as a consequence of the heat flowing under floor rejected by the coolant radiator.

Influence of battery SOC cycle variation on hydrogen consumption

In order not to introduce an error in the hydrogen fuel consumption evaluation, the energy balance has to be corrected by the battery SOC variation throughout the test. Hydrogen raw consumption FC rawH 2 is then corrected using equation equation (11). Figure 9. BoP components power consumption on steadystate operation. Coolant heater was never found to be operated on these points.

FC H 2 = FC rawH 2 + K H 2 EC ð11Þ
EC = Ð V batt I batt d cycle ð12Þ
With FC H K H 2 is determined by calculating the slope of linear fitting curves on Figure 10 for each phase of the WLTC cycle. In this paper when dealing with a cycle involving mostly urban behavior the coefficient fitted on low WLTC phases is employed. Similarly the extra-high WLTC phase is used to correct consumption for highway cycles (i.e. HWFET and BAB130). For RDE cycles the WLTC cycle correction factor is used.

Figure 11 illustrates the comparison between the fuel consumption correction factors determined experimentally on WLTC and the ones considered in the approval NEDC test.

Results

Hydrogen consumption over typical driving cycles. Globally the FCEV is expected to consume more fuel for tests on which the average wheel power request is high. Referring to Figure 8 it is expected that the fuel cell system will operate with a poor mean cycle efficiency for US06, RDE, WLTC, and BAB130 cycles which are the ones featuring highest mean wheel power requests (Figure 17). On average the Hyundai Nexo roughly consumes 0.98 kgH2/100 km on a typical type of use (average over RDE and WLTC). A 3% difference is reported between measured and approval value (=0.95 kgH2/100 km) of fuel consumption on WLTC. Notably, when lab temperature was set at 10°C a fuel consumption of 1.11 kgH2/100 km was observed on WLTC corresponding to a 21% increase as compared to the value obtained with compliant lab temperature conditions (23°C) (Figure 12).

Fuel cell performances and dynamic capabilities. BAB130 was run to assess the power dynamic capabilities of the fuel cell system as well as to reach a maximum transient system power. The fuel cell achieved a power ramp up to 90 kWe (at system level) in about 760 ms and held it for less than 1 s. On the same very dynamic load the battery power reached 39-kWe power output and was capable of absorbing a 35-kWe power input on regenerative breaking phase (Figure 13).

Fuel consumption over long idling period

The vehicle was put at rest with contact on to study its idling fuel consumption. During this period a periodical operating behavior of the fuel cell was observed. Every 8 min, approximately, the fuel cell system generated a 5-s power peak ranging from 2 to 4.5 kWe. Similarly every 45 min the fuel cell system generated, on average, a 10-kWe power step over a 100-s time period to sustain battery SOC. The smallest and more frequent power peaks are assumed to be meant to keep the fuel cell warm. Over this long idling period a fuel consumption of 12.4 g/h was reported (averaged over a time window upon which SOC variation was zero, Figure 14).

Fuel cell system thermal short analysis

Figure 15 depicts the evolution of the three temperature measurements on a WLTC cycle. For a reference usage such as the WLTC the thermostat opened up at 13 min whereas for the aggressive driving US06 cycle the thermostat opened up on average at 1 min and 30 s. When thermal steady-state was reached T cp ranged between 55°C and 58°C. Figure 16 shows the evolution of the fuel cell efficiency with respect to cooling pump temperature which was considered as the best approximation of actual fuel cell coolant temperature. For cooling pump temperatures ranging from 10°C to 40°C the fuel cell stack efficiency was higher than during warm fuel cell operation (i.e. thermal steady-state operation). Conversely, the efficiency at system level followed the opposite trend. This is because the air compressor is operated at higher pressure ratio boosting the stack efficiency (cathode air pressure effect on oxygen oxidation reaction). This translates into an additional power expense for the system and then reduces the fuel cell efficiency at system level (see bottom left in Figure 16).

Vehicle efficiency and fuel cell system energy balance analysis

Integrating the BoP components power consumption allows for drawing an exhaustive energy balance of the fuel cell system on operated driving cycles. Additionally the fuel consumption and the dynamometer wheel power measurements are necessary variables to calculate the vehicle total efficiency defined as follows:

h veh = E wheel j P wheel . 0 E LHV H 2 ð13Þ
With E wheel j P wheel . 0 [J] being the positive mechanical wheel energy expense measured at the dynamometer and E LHV H 2 [J] the hydrogen fuel energy expense measured thanks to the fuel cell current method throughout a specific driving cycle.

Vehicle efficiency ranges from 57% to 64% depending mostly on the cycle-averaged wheel power request (even reaching 55% for unrealistic highway driving behavior on BAB130). It comes down to 50% on the WLTC @10°C (with HVAC turned on). Furthermore it is worth to notice that the eCompressor accounts for the highest energy consuming component alongside with the 12-V accessories load (;280 W on all the cycles). Indeed, on average, the first one is consuming 2.5%-3% of the electrical energy generated by the fuel cell whereas the 12-V load is ranging from 2% to 6% of this same amount (Figures 17 and18).

Conclusion

This paper has investigated the fuel cell powertrain behavior of the Hyundai Nexo on various mission profiles and characterized its global fuel cell system and vehicle efficiencies. Both the fuel cell current and the pressure methods yielded coherent results on fuel consumption evaluation, although discrepancies was found to reach up to 16% on FTP-75 cycles.

A hydrogen fuel consumption ranging from 0.67 kg/ 100 km for urban-type driving conditions to 1.24 kg/ 100 for very dynamic cycles was reported. Even when operating at reasonably low temperature, the FCEV revealed to consume significantly more fuel than in standard temperature conditions. Indeed, this study highlighted a 20% fuel consumption increase between the 10°C WLTC and the 23°C one. The reasons for this over-consumption are multiple: temperature effect on fuel cell stack efficiency, HVAC heater consumption, specific fuel cell heating strategy and temperature impact on battery ohmic resistance. More importantly, the vehicle fuel cell efficiency curve was derived on a dedicated power-step cycle. Accordingly, a maximum efficiency of 66.8% at fuel cell system level was experimentally witnessed. Yet, bearing in mind that the hydrogen purges were not accounted for, lower efficiency values are likely to arise with a hydrogen-flow measuring method.

As a consequence of uncertainties on initial tank temperature estimation and tank model hypotheses, the pressure method yielded different fuel consumption results as compared to the reference method (i.e. based on fuel cell current). Discrepancies between both methods were about 5% on average. This emphasizes the need for a hydrogen temperature sensor inside the tank to boost pressure method accuracy. Leveraging the fuel cell current-based method to determine hydrogen fuel power, energy balances were drawn at fuel cell stack, BoP and battery levels. Vehicle efficiency revealed to lie in a range spanning from 50% on WLTC@10°C to 64% for urban-type driving cycles (e.g. FTP-75 and JC08). Finally, this paper reported the significant contribution of both the electric air compressor and the 12-Volt accessories load in the fuel cell parasitic BoP energy consumption. Comparison between fuel consumption measurement methods over the test campaign. The discrepancies between both methods are roughly 5% on average. The pressure method results turned out to be strongly driven by initial tank temperature estimation. This estimation was easy for cold start test before which the tanks rested a full night at ambient temperature. Conversely, for hot start tests, an error of 1°C on initial tank temperature (as a result of the tank model inherent uncertainties over the previous operated test) could induce up to a 5% fuel consumption difference.

Fuel

  cell stack (LEM Ò HTR 500-SB sensor). e-Compressor invertor. Low voltage DC/DC converter (LDC) output. High voltage DC/DC converter (BHDC) output. Cooling pump. Coolant heaters. Fans. Li-ion polymer battery output.

Figure 1 .

 1 Figure 1. Powertrain diagram of the Hyundai Nexo.

Figure 2 .

 2 Figure 2. H 2 storage tank instrumentation.

Figure 3 .

 3 Figure 3. Fuel cell system power sweep cycle. The step in vehicle speed is meant to alleviate fuel cell heat load duty on high power points. Constant load measurements are carried out on increasing and decreasing wheel power levels.

Figure 4 .

 4 Figure 4. Closed tank model fitted to pressure measurements during tank resting phases of a sequenced hydrogen recharge. At each stop, the station operator had access to the tank temperature communicated by the vehicle.

Figure 5

 5 Figure 5 compares the evolution of hydrogen consumption determined with both fuel cell current-based

Figure 5 .

 5 Figure 5. Comparison of fuel cell-current based method and time-shifted O 2 method on a WLTC.

Figure 6 .

 6 Figure 6. Comparison of the fuel consumption measurement methods on WLTC cycle for both hot and cold start conditions.

Figure 7 .

 7 Figure 7. Fuel cell steady-state polarization curve measurements. Scattered shaded points in the background are 10 Hz data on averaging time windows. Iso-power lines denote stack power.

Figure 8 .

 8 Figure 8. Fuel cell system and stack efficiency values on steady-state operation.

  2 [kg/100 km] being the corrected hydrogen consumption, K H 2 [kg/Whe] the correction factor, EC [Whe/km] the electrical energy consumption, V batt [V] and I batt [A] respectively the battery potential and the battery current and d cycle [km] the driving cycle distance.

Figure 10 .

 10 Figure 10. Fuel consumption as a function of electrical energy consumption at battery level. Only WLTC cycles @23°C are represented. Positive EC means energy has been consumed at the battery.

Figure 11 .

 11 Figure 11. Calculated correction factors for WLTC as compared with the ones used in the approval NEDC tests.

Figure 12 .

 12 Figure 12. Evolution of hydrogen mass in tank calculated with the current method and compared to the results obtained solving the tank model during a WLTC cycle (top). Evolution of calculated hydrogen temperature throughout the cycle and tank temperature measurements (bottom).

Figure 13 .

 13 Figure 13. Acceleration from 90 km/h to 130 km/h on the ADAC highway BAB130 cycle. Dotted green line is the vehicle speed setpoint. A zoom in is applied to fans and cooling pump power consumption traces.

Figure 14 .

 14 Figure 14. Long idling measurements. An iso-SOC time window was considered to determine idling fuel consumption (greenshaded background).

Figure 15 .

 15 Figure 15. Temperature measurements on a WLTC.

Figure 16 .

 16 Figure 16. Temperature impact on fuel cell efficiency at both stack and system levels. Temperature measurements are rounded to the nearest 10. Shaded areas represent measurements standard deviations.

Figure 17 .

 17 Figure 17. Comparison between fuel consumption measurement methods over the test campaign. The discrepancies between both methods are roughly 5% on average. The pressure method results turned out to be strongly driven by initial tank temperature estimation. This estimation was easy for cold start test before which the tanks rested a full night at ambient temperature. Conversely, for hot start tests, an error of 1°C on initial tank temperature (as a result of the tank model inherent uncertainties over the previous operated test) could induce up to a 5% fuel consumption difference.

Table 1 .

 1 Test campaign summary.

	Cycle	Type	Start
	WLTC ( 3 3 types)	10°C, 23°C, FBS,	Cold
	R_WLTC	Reversed cycle	Cold
	RDE	Compliant	Cold
	FTP75	Urban	Hot/cold averaged
	US06	Dynamic	Hot
	HWFET	Highway	Hot
	JC08	Urban	Hot/cold averaged
	BAB130	Highway	Hot
	FC cycle (Figure 3)	Power sweeps	Hot

FBS: full battery start. Hot/cold averaged: fuel consumption results are averaged between the cold start and the hot start cycles.

Table 2 .

 2 Vehicle mass and road-load parameters used in the test campaign.

	Vehicle mass	2057 kg
	Road-load
	a	178.7 N
	b c	0.919 N/(km/h) 0.04037 N/(km/h) 2

Acknowledgement

The authors would like to thank all the colleagues who contributed to this work with a particular gratitude for those who worked on vehicle instrumentation and who conducted the tests on the dyno: P. Pauvert, X. Dunand, V. Brocchetto, O. Pajot, T. Lepage, S. Sarabi, P. Degeilh, A. Battiston.

Funding

The author(s) disclosed receipt of the following financial support for the research, authorship, and/or publication of this article: This work was supported and funded by IFP Energies Nouvelles.

Declaration of conflicting interests

The author(s) declared no potential conflicts of interest with respect to the research, authorship, and/or publication of this article.

Appendix