0% found this document useful (0 votes)
11 views64 pages

(Legal Code) Disclaimer

This document outlines the licensing conditions for a work under the Creative Commons Attribution-NonCommercial-NoDerivatives 2.0 South Korea license, allowing users to copy and distribute the work non-commercially while requiring attribution and prohibiting modifications. It also presents a master's thesis by Chung Yoohee on modeling the OSEK/VDX operating system in C and verifying applications using the OS model, emphasizing the importance of rigorous verification in safety-critical embedded software. The thesis includes sections on related work, modeling components, properties of the OS model, validation, and verification of applications.

Uploaded by

jeong ok
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views64 pages

(Legal Code) Disclaimer

This document outlines the licensing conditions for a work under the Creative Commons Attribution-NonCommercial-NoDerivatives 2.0 South Korea license, allowing users to copy and distribute the work non-commercially while requiring attribution and prohibiting modifications. It also presents a master's thesis by Chung Yoohee on modeling the OSEK/VDX operating system in C and verifying applications using the OS model, emphasizing the importance of rigorous verification in safety-critical embedded software. The thesis includes sections on related work, modeling components, properties of the OS model, validation, and verification of applications.

Uploaded by

jeong ok
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 64

저작자표시-비영리-변경금지 2.

0 대한민국

이용자는 아래의 조건을 따르는 경우에 한하여 자유롭게

l 이 저작물을 복제, 배포, 전송, 전시, 공연 및 방송할 수 있습니다.

다음과 같은 조건을 따라야 합니다:

저작자표시. 귀하는 원저작자를 표시하여야 합니다.

비영리. 귀하는 이 저작물을 영리 목적으로 이용할 수 없습니다.

변경금지. 귀하는 이 저작물을 개작, 변형 또는 가공할 수 없습니다.

l 귀하는, 이 저작물의 재이용이나 배포의 경우, 이 저작물에 적용된 이용허락조건


을 명확하게 나타내어야 합니다.
l 저작권자로부터 별도의 허가를 받으면 이러한 조건들은 적용되지 않습니다.

저작권법에 따른 이용자의 권리는 위의 내용에 의하여 영향을 받지 않습니다.

이것은 이용허락규약(Legal Code)을 이해하기 쉽게 요약한 것입니다.

Disclaimer
Thesis for the Degree of Master of Science

Modeling OSEK/VDX Operating


System in C and Verifying
Applications Using the OS Model

School of Computer Science and Engineering


The Graduate School

Chung Yoohee

December 2017

The Graduate School


Kyungpook National University
Modeling OSEK/VDX Operating
System in C and Verifying
Applications Using the OS Model

Chung Yoohee

School of Computer Science and Engineering


The Graduate School

Supervised by Professor Choi Yunja

Approved as a qualified thesis of Chung Yoohee


for the degree of Master of Science
by the Evaluation Committee

December 2017

Chairman ________________________○

________________________○

________________________○

The Graduate School Council


Kyungpook National University
Contents

1 Introduction 1

2 Related Work 6
2.1 OSEK/VDX Operating System ................................................. 6
2.2 Model Checking ............................................................................. 8
2.3 CSP ........................................................................................... 10
2.4 Verification and Validation of Automotive Software ................. 11
2.5 Automatic Code Generation of API Functions ....................... 12
2.6 Sequentialization of Concurrent Programs .................................. 13

3 Modeling of OSEK/VDX Components 14


3.1 System Model ................................................................................. 15
3.2 Modeling Task Scheduling and API Handling ............................ 16
3.3 Modeling Attribute Tables of OSEK/VDX Object ................. 25
3.4 Modeling of Alarms ..................................................................... 26
3.5 Modeling of Interrupt Service Routines .................................. 27

4 Properties of OS Model 29
4.1 Classification of Properties .......................................................... 29
4.2 Functional API Properties ....................................................... 31
4.3 Invariant Properties .................................................................. 33
4.4 OS Temporal Properties .......................................................... 35
4.5 Code Safety Properties ................................................................. 37

5 Validation of OS Model 40
5.1 Validation of OS Model through Model Checking ...................... 40
5.2 Validation of OS Model through Application Simulation……..42
6 Verification of Applications 44
6.1 Implementation ............................................................................. 44
6.2 Verification of Application .......................................................... 45

7 Conclusion 50

Bibliography 51

Abstract
List of Figures

1 Overall Approach ................................................................................ 5


2 Model Checking ................................................................................... 9
3 Structure of OSEK/VDX System ................................................. 15
4 Classification of OS Properties .......................................................... 30
5 The Structure of a Unit Checking Driver ........................................ 33
6 Time Consumption of Code Safety Property Verification ............. 48
7 Memory Consumption of Code Safety Property Verification……. 49
List of Tables

1 Assertion of API Functions ........................................................... 32


2 Invariant Properties of OSEK/VDX Operating System ............... 34
3 Temporal Properties of OSEK/VDX Operating System .............. 36
4 Validation Performance of APIs ....................................................... 40
5 Validation Performance of Invariant/Temporal Properties………40
6 Validation Performance of Code Safety Properties ...................... 41
7 Functional Verification of Applications ............................................ 47
Chapter 1

Introduction

In safety-critical embedded software, such as automotive control software,

rigorous verification is necessary to ensure its correct and safe operation [1].

Nevertheless, most existing approaches have overlooked an important fact when

verifying embedded software: operating system (OS) and applications are coupled

tightly since they are compiled together and executed as a unified executable

program. The verification of embedded system must also consider the interaction

between an application and its underlying OS. The absence of OS behavior

consideration may cause false alarms or missed errors. [2]

A major difficulty in verifying application software together with its

underlying operating system is the handling of the increased program size

and complexity. This issue can be addressed by using abstractions such as

1
model-based approaches, where operating systems are formally modeled

and used in the verification of embedded software [3–7]. The OS model

reduces the complexity of verification, and once a model is written, it can be

reused for any control software that uses the same OS.

The model-based approach, however, introduces another issue:

the heterogeneity between the language used for modeling the OS

and the languages used for writing the application code. In most

cases, operating systems are modeled in formal modeling languages

such as Promela [8], NuSMV [9], and CSP [10], while applications

are implemented in C, meaning that there is a linguistic

heterogeneity between the formal OS model and the application

codes. Thus, to verify an application code with its OS model, it is

necessary to convert the OS model into C or construct a model of an

application program by using a formal modeling language. The

former is known as model-based code generation [11], which does

not necessarily help improve verification complexity because the

generated code is not optimized and often includes redundant code

for sanity checking or environment simulation. The latter requires

abstractions and the modeling of application codes. It is also a

common practice to model application programs and generate code

from the model using commercial tools such as SCADE [12] and

2
Simulink [13]. However, the verification of code safety properties

that may arise from interactions between applications and the

operating system, such as null pointer dereferencing or an array

bound error caused by interaction behaviors, is left untouched.

This study views this problem from a new angle by suggesting a

model-based approach using C as the modeling language. Since the

language used to model the OS and implement applications is the

same, the heterogeneity between the OS model and the application

program is eliminated, making the verification of control software

using the existing C code model checker straightforward. The

modification of the original application code is minimized, and it is

therefore possible to keep most of the code-level features. A major

concern with this approach is the maintenance of the level of

abstraction. Due to the low-level characteristics of the C language,

there is a high risk of writing an OS model with unnecessary details.

To avoid this, a two-step approach is used; reference models of OS

components in modeling language CSP [10] are first defined using

the standard, which is OSEK/VDX [14], and the C model is defined

by using the reference model.

After the C model is defined, it is necessary to validate the

correctness of the model. To validate the model with regards to the

3
OSEK/VDX standard, two validation approaches were proposed;

property-based validation via bounded model checking (BMC) [15]

and simulation. The standard properties are classified into four

categories according to their contents and temporal attributes. These

properties are used to validate that the OS model satisfies the basic

requirements of the standard using CBMC [16], a model checker for

C/C++ language. In the simulation, the behavior of OS model is

checked and compared to the behavior of the implemented

OSEK/VDX OS.

Figure 1 illustrates the overall process of modeling and validating

the EK/VDX OS in C; the formal models of the OS components in

CSP are defined first, and the properties to be satisfied are defined

by the OSEK/VDX specifications. Using the CSP model as a

reference, the basic constructs of the OSEK/VDX are manually

defined in C. The correctness of model is validated with regards to

the identified properties using the model checker CBMC, and

falsified properties are used to check the correctness of the OS

model. When CBMC reports the violation of a property, the model is

manually analyzed and the counterexample is used to identify

whether it is a real alarm. If it turns out to be a false alarm, both the

CSP model and C model are reviewed to identify the source of the

4
problem. If the source of the error is an incorrect translation from

CSP to C, the C model is fixed. Otherwise, it is regarded that the

source of the error is the CSP formal model and it is modified

accordingly. This process continues until all issues in the model are

fixed. When the OS mode is considered to be correct, this model

will be combined with applications and used to verify them.

Figure 1. Overall Approaches.

5
Chapter 2

Related Work

2.1 OSEK/VDX Operating System

OSEK/VDX [14] is an open standard published by a consortium founded by

the automobile industry. This OS is intended for use in any type of control unit,

and therefore, it is focused on the presence of a standardized interface,

scalability, error checking, and the portability of the application software. The

major characteristics of the OSEK OS are that (1) it assumes that it is running

on a single processor, and (2) all system variables are required to be statically

assigned at the start-up time.

The OSEK/VDX system is composed of five types of objects; Task, Alarm,

Interrupt Service Routine (ISR), Resource, and Event (Figure 3). The OS kernel

manages the information on these objects. A task provides the framework for the

instructions and execution of API functions. An alarm is an object for processing

6
recurring events. An ISR is similar to a basic task, but it has higher priority and

occurs at any time during execution. A resource is an object that may be

occupied by tasks or ISRs. The priority of the task or ISR that occupies the

resource cannot be higher than the ceiling priority of the resource. An event is

an object that can be used only by extended tasks and is used apply binary

information to the task.

OSEK OS also provides 26 API functions that can be invoked by an

application. Some representative API functions are as follows:

1. API functions for task management, such as:

a) ActivateTask activates a task and may cause a rescheduling.

b) TerminateTask terminates a currently running task. If successful, it

enforces a rescheduling.

c) ChainTask terminates a task and activates another. If successful, it

enforces a rescheduling.

d) Schedule may cause rescheduling of tasks.

2. API functions for resource management, such as:

a) GetResource serves a task to enter critical sections assigned to the

resource.

b) ReleaseResource serves a task to leave critical sections assigned to the

resource. If the task is preemptive, rescheduling may occur.

7
3. API functions for event mechanism, such as

a) WaitEvent makes the caller task wait until the event mask is set. This

call enforces rescheduling if the waiting condition is satisfied.

b) SetEvent sets the mask of an event.

c) ClearEvent clears the mask of the event.

2.2 Model Checking

Model checking is an automatic and exhaustive technique that checks

whether the given system model satisfies a property or not [3]. It has been

successfully used to verify complex systems such as circuit designs,

concurrent software, or communication protocols.

In model checking, the system under verification is represented as the

formal model M and the verification property is represented as the formula

φ. The model checker exhaustively checks whether the system model

satisfies the property or not. Formally, this problem can be stated using the

following formula: M |= φ. Figure 2 illustrates the model checking

mechanism.

The model checker checks whether the system model satisfies the given

property and provides notification of the result. If a property is violated, the

model checker provides a counterexample trace.

8
2.2.1 BMC

Figure 2. Model Checking.

The model checker used in this study is CBMC. CBMC [16] is a tool for the

formal verification of ANSI-C programs using BMC techniques [15]. Symbolic

model checking through Binary Decision Diagrams (BDDs) [17] could alleviate

the state-space explosion problem more successfully than explicit model checking.

However, BDDs can grow exponentially. BMC uses a propositional SAT solver

rather than BDD. Since it restricts the bound of the target system model, BMC can

handle the growth of memory usage more easily. Moreover, the SAT formula is

9
canonical in itself while BDD manipulation may consume memory, according to

the shape of the diagram.

CBMC demonstrates the violation of assertions in C programs or proves the

safety of the assertions given a search bound and is the most widely used model

checker to verify safety and the correctness of software


soft implemented in C [18, 19].

In CBMC, the transition relations of C code and its specifications are jointly

unwound to obtain a Boolean formula whose satisfiability is checked using an SAT

solver [20].

CBMC checks properties defined in ANSI


NSI-C assertions and returns a

counterexample trace if an assertion is violated. CBMC also provides several

verification options, such as checking errors caused by out-of-array indexing,

NULL pointer dereferencing, memory leaks, over/underflow of variables, and

division by zero.

2.3 CSP
Communicating Sequential Processes (CSP) is a formal modeling language that

10
describes the interaction of processes in concurrent systems [10] and is used to

specify and verify the concurrent aspects of a system. Each process is defined as an

order of events, choices and a concatenation of subprocesses. Processes

communicate via message channel objects. The BNF describes the syntax of the

CSP components that are used in this work.

2.4 Verification and Validation of Automotive Software

2.4.1 Verification of OSEK/VDX OS

The approaches used in [21] formally specified the OSEK/VDX requirements in

CSP from the code-level OS and performed formal verification of the OS’

properties. The reference model of this work is based on their findings. In this study,

some modifications were made to the model to make it smoother to translate into C.

The behavioral model of context switching was added explicitly, and there were

changes in some processes to increase the modularity of the model.

Choi [4] presents a method for converting the Trampoline OS into Promela

formal models and reports on the potential safety issues found in the Trampoline

OS.

2.4.2 Model-based verification without OS

11
Several approaches apply formal verification directly to the source code level in

the automotive domain; Lettnin et al. [22] proposed an approach to derive a

SystemC model from the original C code and verified its temporal properties with

CBMC and BLAST [23]. Schlich et al. [24] proposed an approach to verify the

automotive microcontroller applications using [mc]square, a model checker for

assembly codes [25]. Kim et al. [2] checked the correctness of the API-call

constraints of automotive control software using CBMC.

2.4.3 Model-based verification considering OS

Zhang et al. [26] modeled OSEK/VDX applications in Promela and verified

them with an OS model using Spin [27]. Kim et al. [5] presented an approach for

the API-call constraint checking of automotive control software by using an OS

model written in NuSMV.

Quickcheck [28] uses the property specifications of operating systems instead of

fully functional models to randomly generate test inputs. It is a useful tool for the

random testing of automotive software, but is difficult to apply for safety property

verification.

12
2.5 Automatic Code Generation of API Functions

Zhai et al. [29] proposed a technique to automatically generate models of API

functions from documents. In this work, the OS was manually modeled to maintain

consistency between the API model and other models for the objects managed by

the OS, since the OS model requires schedulers and behaviors embedded in the

specifications. As they are generally written in a natural language without

following a specific format, it is very difficult to define the template required in

Zhai et al.’s approach. Unless this work defines a template for arbitrary natural

language specification with acceptable accuracy, it is too early to apply their

approach in this domain.

2.6 Sequentialization of Concurrent Programs

Inverso et al. [30] suggested a lazy sequentialization technique for multi-

threaded C programs. Their approach used auxiliary data structures, goto

statements, labels and assumptions to simulate context switching in a similar

fashion as our work. In addition, the tool they implemented was used to

sequentialize threads that express interrupts in our study to reduce verification costs.

13
Chapter 3

Modeling of OSEK/VDX
Components

This work took a two-step approach to maintaining the level of abstraction of the

OS model in C. This section explains the formal CSP models of OS components

and how they are used to define an OS model in the C language. Our definition of

the CSP model is influenced by the work of Huang et al. [21], but with some

changes required for the smooth translation to C.

1. A program counter is added to our CSP model to explicitly

specify the saving and restoration of context. This is required

for the translation of the CSP model into C as the implicit

change of context in CSP must be explicitly defined in C.

2. A task is assumed to be ready to run without explicitly creating

new task object. This is to avoid dynamically creating a task

14
at runtime as the OSEK/VDX specification requires that they

are statically created at system startup. This is modeled in CSP

by adding the instruction to restart it.

3. The process that modifies data tables in [21] is changed into

action sequences embedded in the APIHandler process to

improve modularity.

3.1 System Model

Figure 3. Structure of OSEK/VDX System.

The control system is a concurrent composition of an OS and an application

program. The OS manages objects, and the application interacts with its underlying

OS by invoking the API functions provided by the OS (Figure 3). Therefore, the

15
control system is defined as a parallel composition of OS and Application.

OS is defined again as the parallel composition of APIHandler, Scheduler,

Alarm, and ISR. Application is composed of multiple tasks that invoke API

functions to interact with the OS. APIHandler handles API functions that deal with

task states (ActivateTask, TerminateTask, ChainTask, and Schedule), resource

allocation and deallocation (GetResource and ReleaseResource), and event

mechanisms (WaitEvent, SetEvent, and ClearEvent). Scheduler is a logical concept

that supports system multitasking. The CSP model and detailed explanation about the

behavior of the scheduler will be introduced in the following sections. The scope of OS will

be limited to APIHandler and Scheduler in this paper.

3.2 Modeling Task Scheduling and API Handling

3.2.1 Task (Application)

16
A task is an object that provides the framework for the execution of API

functions. Like threads in other operating systems, tasks perform instructions,

activate other tasks, occupy and release resources, wait, set, or clear the masks of

17
events, preempt another task, and finally terminate.

This is the CSP model of tasks at the application level. The symbol  means

external selection and → means precedence relationship between events/actions.

channel?value and channel!value are defined as receiving from and sending to a

channel, respectively. SKIP is a special kind of process that does nothing but

terminates successfully. START is a predefined constant signifying the least value

of program counters. Because of the space limitation, I used abbreviations of API

function names such as AT, TT, CT, S, GR, RR, WE, SE, and CE for ActivateTask,

TerminateTask, ChainTask, Schedule, GetResource, ReleaseResource, WaitEvent,

SetEvent, and ClearEvent, respectively.

Each task runs in its turn (run tid = tid). Tasks send a message to APIChan,

with parameters (APIChan!AT.tid.reftask). Before calling an API function, the

program counter of a task is updated to save the progress of the task.

Some of API calls may cause preemption of a task; ActivateTask is one of them.

A task can get two kinds of messages as a response from API function: Switch or

Keep. If a task gets Switch as a response, it ceases its execution until it is its turn

again (run tid = tid). If the returned message is Keep, the task keeps running. Since

pctid has been updated whenever an API function is called, it keeps the point

where to start performing instructions again. The action goto LABELpctid makes the

control flow go directly to the starting position of the task. If a task terminates, the

program counter is reinitialized to START. The Tasktid attached at the end of the

18
process specification makes it go back to its initial state after termination.

This CSP model is used as a reference to define the C code of the task model

shown in Code 1; when the task function is called, the control flow jumps to the

point to resume running and the program counter of the task is updated. When an

API function is called, the task gets the return value from the function. A task

keeps running or stops according to the return value. It starts to run from the point

Code 1. A Task Model in C


to resume when it is its turn again.

19
3.2.2 APIHandler

APIHandler is a component of OS that handles API functions. It gets parameters

from tasks such as resource/event identifier and handles the error code

(errorHandle). If there is no error, then APIHanler takes the action modifyTable to

modify the value of the data table. After that, it invokes Scheduler and returns a

message to task whether to switch context or keep running.

The CSP model above shows the general behavior of APIHandler. The

following is the CSP model of a sub-process of APIHandler that handles a specific

API function, WaitEvent. If the condition between ⊲ and ⊳ is true, then the

sequence of the left side is executed. If the condition is false, the sequence of the

right side is executed. When WaitEvent is called, APIHandler first checks whether

the task is an extended task, and whether it is occupying resources or not. If the task

is not an extended task, then it generates an E_OS_ACCESS error. If the task is still

occupying a resource, then the error code is E_OS_RESOURCE. Otherwise,

APIHandler changes the state of the task from running to waiting and invokes

Scheduler. Only the model of WaitEvent API because of the limited space in this

paper, but all API functions of OSEK/VDX have a similar structure; they get

20
function calls from applications, handle errors, modify tables, and return

whether rescheduling occurs or not. In this work, nine API functions that each have

a direct impact on task rescheduling were modeled. Others can be modeled in a

similar manner.

These CSP models are used to define C functions for API handlers. The major

difference between the CSP model and the C model is the message passing

mechanism; though messages are sent/received by using an explicit channel object

in CSP, function calls are used to express message passing in C. Thus, the behavior

21

Code 2. WaitEvent API in C


of APIHandler is modeled in functions. Code 2 is an example of an API function in

C, WaitEvent, which is a straightforward translation of the CSP model.

3.2.3 Scheduler

Scheduler in our model checks whether the rescheduling condition is true or not, pushes

the preempted task into the ready queue, and gets the task that will be running from the

ready queue. The behavior of Scheduler is expressed in CSP as follows:

Calling TerminateTask, ChainTask, or WaitEvent enforces rescheduling. Scheduling

may happen without explicitly calling these API functions; if there is a task with higher

priority in the ready queue, it preempts the running task. If the scheduler gets a task from the

ready queue successfully, it returns Switch to the API function that invoked it. Otherwise,

22
Scheduler returns Keep and terminates. If rescheduling is required but the ready queue is

empty, Scheduler returns Keep to notify that task-context switching is failed. Code 3 shows

the Scheduler model in C defined from the CSP model, which is (almost) syntactic

translation from CSP to C.

Code 3. Scheduler in C Model

3.2.4 Task-Context Switching

To support multitasking, it is necessary to model task-context switching. Unlike

modeling language based on CSP, such as Promela [8], C is a single-threaded

sequential language by default and does not maintain information on the program

counter or control flow at the language level. Therefore, it is necessary to explicitly

23
model context-switching in our C model. For this purpose, labels are located in

positions where task-context switching may occur, and the program counter of

each task is saved to know the progress of a task, which makes it possible to jump

to the location to resume the task.

Code 4. Explicit Model of Task-Context Switching

Code 4 is an example code with two tasks. This example code assumes that

Task2 has a higher priority than Task1, and both tasks are following full-

preemptive scheduling policy. The original program has only API function calls.

Code 4 shows how task-context switching is explicitly instrumented. Before the

call of an API function, the program counter of Task1(pc[1]) is updated to 2 (the

24
initial value is 1). ActivateTask(2) causes a context switching since Task2 has a

higher priority. After the call of the function, run_tid is 2 and task2() is called in this

turn. After TerminateTask(), run_tid becomes 1 again. Using the value of pc[1]),

the task function task1() begins running again from the Label2, in line 9. After

ChainTask(1), pc[1] becomes 1 again and Task1 starts running from the first

statement again.

3.2 Modeling Attribute Tables of OSEK/VDX Object

This subsection explains how attribute tables of OSEK/VDX objects are

structured and defined in formal N-tuples and C arrays.

Task: A task object needs four kinds of information; an identifier of the task,

current state of the task, static configuration which is defined by configuration

file (e.g., autostart, preemptive, etc.), and dynamic attributes that are changed by

API function calls (e.g., activation count and dynamic priority).

Resource: OSEK/VDX allows nested occupation of resources, but a resource

cannot be occupied by multiple tasks. It also uses priority ceiling protocol [31] to

prevent deadlock and priority inversion. To support them, information on the

ceiling priority and the owner of each resource is saved in a table.

25
Event: An event has its own identifier and a state; an event can be set, cleared,

or waited by a task. Unlike a resource, an event can be waited by/set to multiple

tasks simultaneously.

Object tables are expressed in arrays. Each element of arrays contains

information of a single object, which is expressed in struct of C. C language has

various kinds of primitive data types. Thus, this work also has to consider the data

type and available values that can be assigned to each field. For example, the

priority of a task has an integer value. Since the lowest priority of an object is 0,

the data type of priority is an unsigned integer.

3.3 Modeling of Alarms

26
An alarm is an object used to process recurring events. An alarm is based on a

specific counter, which measures “ticks” derived from a hardware or software

timer. If its predefined counter value is reached, the alarm is expired and performs

its behavior. OSEK/VDX provides three kinds of alarm behaviors; 1) activating a

task, 2) setting an event, 3) calling an alarm-callback routine, a short function

provided by the application. If an alarm is a single alarm (which means the cycle of

the alarm is defined as 0), then the alarm stops. Otherwise, the alarm does its

behavior per the cycle.

In C, alarms are also expressed in a function called with tasks repetitively. When

an alarm function is called, it checks the current time and it is compared with the

time at the last time when it was called.

Code 5. Alarm in C Model

27
3.4 Modeling of Interrupt Service Routines

OSEK/VDX provides an object to handle interrupts. The object is called

Interrupt Service Routine (ISR ). Since interrupts may occur at any point in the

system execution, there is a necessity to use multi-threading techniques to model an

ISR. In this work, the pthread library is used to model interrupts. When interrupts

are enabled, the function pthread_create is called. When the system shuts down,

the function pthread_cancel is called to cancel the threads that are not terminated

yet.

28
Chapter 4

Properties of OS Model

When it is combined with an application, the OS model in C can serve multiple

purposes; it can be used to verify the functional correctness of application source

code through model checking, to validate the design of task sequences through

simulation, and to verify functional/code safety of the system. However, before

using the model for those purposes, it is necessary to validate the correctness of the

model. Properties to validate the model were derived from the OSEK/VDX

Specification [14] and general characteristics of C programs. These properties were

classified them into four categories, as shown in Figure 4.

29
4.1 Classification of Properties

The properties are first classified into two categories: those dependent

on specific API functions and those that are totally independent of API functions

and call sequence of functions. API-dependent properties are classified again into

two sub-categories: functional API properties defined in the Specification of

System Services [14] and OS temporal properties. The former check whether states of

objects are changed correctly according to its description, and w h e t h e r

errors are handled correctly. OS temporal properties require expressions in

temporal logic such as LTL, CTL, or in automata. API-independent properties

are also classified into two subcategories: invariant properties and code safety

properties. The former should be true from the start to the termination of the

system. The latter are not derived from the specification, but the general safety

properties of C codes. A misuse of arrays, pointers, and a specific kind of data

structure can be a source of code safety properties.

30

Figure 4. Classification of OS Properties.


For each category of properties, they may require different validation

techniques because of their different contents, dependencies, and temporal

attributes. The following sections cover validation approaches of each

property class.

4.2 Functional API Properties

There are two types of functional API properties: 1) Assertions that check a

normal behavior of the target API function according to the functional description,

and 2) assertions that check error code handling according to the Status of the API

specification. Table 1 is a partial list of functional API assertions. For example,

property 1 and 2 are assertions of ActivateTask; property 1 checks whether the

error handling works correctly when TaskID is a wrong task identifier, and

property 2 checks whether task state changes correctly when there is no error.

To validate functional API properties, an approach that is similar to unit testing

but more exhaustive was used. The idea to check a unit function in a model-based

approach is not a new idea. Gunter and Peled [32] also proposed an approach

named unit checking, which is a symbolic approach for model checking a unit of

code. Based on their idea, the unit checking driver was developed to validate the

correctness of a single API function. The structure of the unit checking driver is

illustrated in Figure 5.

31
Table 1: Assertion of API Functions

32
The driver first declares parameters that will be passed to the target API function.

The initial value of a parameter is defined to be a non–deterministic value. After

the declaration of variables, assumptions about parameters are specified. These

assumptions restrict the ranges of parameters and eliminate false alarms caused by

infeasible values. After them, the unit checking driver calls the target API function

and checks whether the API handles the error correctly or behaves in a specified

way in normal cases by using assertions.

Figure 5. An Example of a Unit Checking Driver.

4.3 Invariant Properties

Invariant properties are a special kind of requirements that must be satisfied throughout

the entire system execution. They have the form “The model must/must not satisfy a

condition

33
Table 2: Invariant Properties of OSEK/VDX Operating System

A in any case”. From the specification, it was possible to define six invariant properties

(Table 2).

A difficult problem is where to locate the invariant properties in the model as it

is not possible to express “always” or “in any case” in assert statements in C. To

ensure that a given property holds during the entire lifetime of the system,

assertions should be put between every single statement. However, this approach

will severely undermine the efficiency of the verification. Instead, assertions for

invariant properties were located only after assignments of variables whose values

have a dependency on their conditions. For example, property 18 of Table 2 is

dependent on the value of task_static_info[TaskID].prio. Assertions are located right

after assignment of the variable. Meanwhile, from the property 21 to 23, Start is added in

front of a Boolean expression. This means these properties need to be checked when a task

starts. In this case, assertions are located right after the statement that assigns running to a

34
state of a task.

Among invariant properties, there are also some properties which need to be

checked at the specific point of the system. For instance, the property “The number

of running task cannot exceed 1.” can be checked when a task is transferring from

ready state to running state and it is sufficient. Thus, it is also necessary to define

where to put assertions of these properties. From properties 21 to 23, the specific

position start is added in front of a Boolean expression. This means these properties

should be checked when a task starts; in other words, when the state of a task is

changed into running, then the assertions are located.

Invariant properties must be satisfied under arbitrary application codes. To cover

arbitrary call sequences, non–deterministic API call sequences were used.

4.4 OS Temporal Properties

There are properties that can be expressed neither in a single assertion nor in an invariant

property. These properties are classified as OS temporal properties. Properties 24–27 in

Table 3 are OS temporal properties since they include temporal operators other than

Globally (G). For example, property 24 means “Whenever a task goes to ready state, then

it eventually goes to running state.” and it has a temporal

35
Table 3: Temporal Properties of the OSEK/VDX Operating System

operator Eventually (F). Validation of these temporal properties is performed by

modeling the properties in finite automata and inserting them in the C model as a

monitoring code, which is a general approach taken by SPIN [27] and CBMC [16].

The monitoring code samples the transition of state after each API function call.

Code 4.1 is an example of the monitoring code of property 24(Table 3). When a

task terminates, the final state of automata should be in the predefined safe state.

Since these OS temporal properties are not perfectly independent of API functions,

inappropriate use of API functions may cause false alarm when attempting to

validate temporal properties with non-deterministic call sequences. For example,

property 24 of Table 2 is violated when tasks are not terminated with the API

functions TerminateTask or ChainTask. Terminating a task without those API

functions is strictly forbidden. Therefore, the failure is not caused by the

36
incorrectness of the OS model. To eliminate these false alarms, inappropriate API

call sequences are aborted before the execution of applications while validating OS

temporal properties. Assertions are located at the end of the task or at the end

of the system. Properties 24 and 25 are local properties are subordinate to a

single task, and 26 and 27 are global properties that have a dependency on all

three tasks and other objects.

4.5 Code Safety Properties

C language is notorious for many corner cases that can easily go unnoticed but

result in system failure. As the OS is modeled in C, it is required to check that the

model does not include any typical safety issues from the language itself.

Examples of such safety issues include:

1. Use of arrays: As arrays are used to represent object tables and the ready

queue in the model, there might be a use of an index that is out of array

bounds.

2. Use of pointers: As the model uses pointers to change the value of given

parameters in some functions, it may cause dereferencing of inappropriate

addresses like NULL.

3. Variables: The model uses a lot of integer type variables to express objects

of OSEK OS. They may cause over/underflow.

37
4. Circular queue: The task ready queue is modeled with a circular

queue to save memory space. Unexpected overwriting of an

element of the queue can cause a serious flaw in the model.

There were four code safety requirements from these potential issues. Since

code safety properties of the OS model should be satisfied with any arbitrary

application, properties are validated with non–deterministic API call sequences,

like in the validation of invariant or OS temporal properties.

38
Chapter 5

Validation of the OS Model

5.1 Validation of the OS Model through Model


Checking

The OS model was validated with the properties defined in Chapter 4. All

experiments were performed with Linux Fedora-release-24- 1.noarch, x86 64

architecture, 16 Intel(R) Xeon(R) CPU E5-1680 v4 @ 3.4GHz CPUs, and 128

GB of total memory, CBMC 5.7 version.

All 20 functional assertions were proved to be satisfied in a given loop

unwinding bound 100. CBMC also reported that the loop bound is sufficient. Table

4 shows the performance of the validation.

Table 7 is the validation performance of invariant and temporal properties.

Non-deterministic API function call sequences with two tasks, resources, and

events were used to validate the properties. Each task calls five API functions to
39
cover scenarios with nested resource allocation.

Table 4: Performance of Functional API Property Validation

API VCC Time(Sec) Memory(MB)


ActivateTask 4 3.9 420.6
ChainTask 2 3.6 404.4
TerminateTask 2 3.7 339
Schedule 2 0.8 127.2
GetResource 2 3.8 397.4
ReleaseResource 2 3.7 407.4
SetEvent 2 3.7 321
WaitEvent 2 2.3 219.9
ClearEvent 2 2.2 318.2

Table 5: Performance of Invariant/Temporal Property Validation

Property No. VCC Loop bound Time Memory


18-20 261 8 12’ 18” 8.5 GB
21 484 8 924’ 47” 13.0 GB
22 484 8 1081’ 6” 10.0GB
23 484 8 1450’ 8” 14.0 GB
24 16 8 42’ 28” 11.0 GB
25 16 8 43’ 07” 11.0 GB
26-27 1 5 9’ 46” 30.8 GB

Properties 18–23 are invariant properties, and 24–27 are OS


temporal properties. Properties 18–20 are validated together since
they are originated from the same requirement. Properties 26 and 27
are validated together because each can be expressed in a single
push-down automaton.
For each property, CBMC generates VCC (Verification Condition
Counts) and all of the verification conditions are satisfied under a

40
given bound.
However, CBMC reported that there is an unwinding assertion,
meaning that the loop unwinding bound is not sufficiently big.

Table 6: Validation Performance of Code Safety Properties

Property No. VCC Loop bound Time Memory


Pointer Validity - 8 N/A N/A
Array Bounds 7176 8 89’ 8” 6.4 GB
Variable Overflow 5137 8 67’ 6” 5.3 GB
Ready queue 359 8 51’ 14” 4.6 GB
overwriting

In the validation of code safety properties, giving options to validate them makes

CBMC generate many verification conditions automatically. Hence, when the

length of the call sequence of each task is 5, it exceeds the power of SAT solver

and returns an error message, even within small bounds. To get around this issue,

the length of the API call sequence of each task was decreased, from 5 to 3, to

reduce the number of possible combinations of API call sequence. Table 6 shows

the performance of the validation of code safety properties. There was no violation

of a property. However, like in the validation of invariant/temporal properties,

CBMC reported an unwinding assertion.

As the result, CBMC was able to validate the invariant properties, temporal

properties, and code safety properties under the condition, two tasks, two resources,

41
two events, 3–5 arbitrary API function calls in each task, and the given bound.

However, CBMC could not guarantee the validation in other conditions due to the

high validation cost caused by non-determinism, which is necessary to validate the

model under arbitrary interactions with applications. Simulation can be a

complementary approach to this issue as shown in the following section.

5.2 Validation of OS Model through Application Simulation

After the C model is validated through a series of property checking processes

using CBMC, the model is integrated with a set of example application codes from

Erika Enterprise [33], which is a real-time OS based on OSEK/VDX. These

example codes were used to check whether the execution of the code on our C

model shows the same behavior as the execution of the same code on the actual

implementation of the Erika OS, which is compliant to OSEK/OS. Eight example

codes for testing the portability of the system in the x86 environment were used.

In the integration process, it is confirmed that our C model can easily substitute

the Erika OS implementation. The steps required for this process are (1) changing

the header file from the Erika specific “ee.h” to our OS header file, (2) redefining

data types defined in the “ee.h” file to match them with the data types in our C

model, and (3) annotating the explicit context switching behavior on the code, like

in Code 3.4.

42
Through the first simulation, it was found out that most of the example codes are

violating a property of OSEK/VDX standard, “Ending the task without a call to

TerminateTask or ChainTask is strictly forbidden and causes undefined behavior.”. After adding

TerminateTask, the behavior of simulation using our OS model and the concrete

execution with Erika OS were identical.

43
Chapter 6

Verification of Applications

6.1 Implementation

This section introduces implementing the tool Switchy, which generates files for

initialization and annotates the application source code.

Before starting the system, static attributes of objects should be initialized at first.

When compiling an application with implemented OS, this information in the

OSEK Implementation Language (OIL) file is compiled together. In contrast, our

OS C model is not compiled with the OIL file. Instead, by using Switchy, a header

file and source code file which initializes objects are generated automatically.

After generating these files, Switchy also annotates jump operation and program

counter updates to embed task-context switching model explicitly. Switchy extracts

Control Flow Graph (CFG) from the source code and finds the OSEK API

44
function call by traversing the CFG. If there is an API function call, a statement

that updates a program counter of the task and a label is added. When verifying

an application, this annotated code will be compiled with the generated header file,

initialization code file, and OS model.

6.2 Verification of Application

In previous chapters, the validity of the model was checked with two

validation approaches. The model was used to verify functional and code-safety

properties of application codes. The application codes are example codes of Erika

Enterprise [33] and Trampoline 2.0 [34]. Application codes were verified with

CBMC [16], and the result compared with the simulation. The experiment

environment is identical to the one of OS model validation.

In some example codes, there are one interrupt or more. Interrupt service

routines were modeled with a thread. When verifying these example codes only

with CBMC and a back-end SMT solver [35], CBMC consumed too much time and

memory in generating verification conditions and converting them to SMT input

format. Thus, to reduce the verification cost, the sequentialization [30] technique

was used in verification of applications with interrupts.

45
6.2.1 Functional properties

Functional properties are properties about the functionality of the application. In

Erika Enterprise example codes, there are EE_assertion functions. These functions

are used to log the execution order of the control flow. If the program runs in the

order that the programmer intended, values saved in EE_assertions [EE ASSERT

DIM] are all EE ASSERT YES. Otherwise, it means that the program behaved in a

different way. Thus, while verifying Erika Enterprise example codes, we check

whether all of the values in EE_assertions are EE_ASSERT_YES. Trampoline

example codes do not provide a similar function. Thus, functional properties of

Trampoline example codes were defined manually.

Table 7 shows the verification result of application code in a given loop bound

10. From the verification result, it was possible to determine that functional

properties of application EE6 were violated. In simulations, there was no assertion

violation. However, model checkers do not consider the concrete time; therefore, it

could find a potential property violation. In practice, when the frequency of

interrupts was increased from the original one, property violations were discovered

also in simulations. The other target application satisfied all of their functional

properties in both BMC and simulation.

46
Table 7: Functional Verification of Applications

Code VCC Time Memory(MB) Result


EE1 5 < 1” 11.7 SUCC
EE2 10 1.94” 45.7 SUCC
EE3 20 20’ 1” 2130 SUCC
EE4 21 2’ 56” 458.8 SUCC
EE5 21 7’ 38” 973.9 SUCC
EE6 22 40’ 4” 8234 FAIL
EE7 11 23’ 57” 1034 SUCC
TP1 10 < 1” 8.8 SUCC
TP2 3 19’ 3” 898.8 SUCC

47
6.2.2 Code safety properties

The four code safety properties defined to validate OS model were used to verify

applications also. Code properties were verified under bound 5 from 20. Until the

loop bound reached 20, there was no violation of code safety properties.

Figure 6 and 7 shows the increase of time and memory consumption of the

verification. If the application has many tasks, API function calls, or interrupts, then

the verification cost is noticeably high. Otherwise, the verification takes only a

few seconds and less than 500 MB of memory.

Figure 6. Time Consumption of Code Safety Property Checking.

48
Figure 7. Memory Consumption of Code Safety Property Checking.

49
Chapter 7

Conclusion

This paper presents a method to model OSEK/VDX OS in C language to

remove linguistic heterogeneity between the OS model and application programs

and avoid potential problems caused thereby. To the best of my knowledge, this is

the first approach to model OSEK/VDX OS in C. The abstraction level of the C

model was gained sufficiently by using a reference model in CSP. The model was

validated by two validation approaches; 1) property-based validation via bounded

model checking and 2) simulation. After the validation, applications for

OSEK/VDX-based OS were verified with the OS model. The model could be used

to verify not only functional properties but also code safety properties of the

applications.

50
Backmatter

Bibliography

[1] N. R. Storey, Safety Critical Computer Systems. Addison-Wesley


Longman Publishing Co., Inc., 1996.

[2] D. Kim and Y. Choi, “Light-weight API-call safety checking for automotive
control software using constraint patterns,” in IT Convergence and Security
(ICITCS), 2016 6th International Conference on. IEEE, 2016, pp. 1–5.

[3] E. M. Clarke, O. Grumberg, and D. Peled, Model Checking. MIT


Press, 1999.
51
[4] Y. Choi, “Model checking Trampoline OS: a case study on safety
analysis for automotive software,” Software Testing, Verification and
Reliability, vol. 24, no. 1, pp. 38–60, 2014.
[5] D. Kim, Y. Chung, and Y. Choi, “Model-based API-call constraint
checking for automotive control software,” in Asia-Pacific Software
Engineering Conference (APSEC), 2016. IEEE, 2016.

[6] S. Siegel, K.-S. Hielscher, and R. German, “Model-based requirements


analysis and testing of automotive systems with timed usage models,” in
Requirements Engineering Conference (RE), 2010 18th IEEE International.
IEEE, 2010, pp. 345–350.

[7] E.-Y. Kang, G. Perrouin, and P.-Y. Schobbens, “Model-based verification of


energy-aware real-time automotive systems,” in Engineering of Complex
Computer Systems (ICECCS), 2013 18th International Conference on. IEEE,
2013, pp. 135–144.

[8] G. Holzmann, “Promela language reference,” Bell Labs, 1997.

[9] A. Cimatti, E. Clarke, E. Giunchiglia, F. Giunchiglia, M. Pistore,


M. Roveri, R. Sebastiani, and A. Tacchella, “Nusmv 2: An opensource
tool for symbolic model checking,” in International Conference on
Computer Aided Verification. Springer, 2002, pp. 359–364.

[10] C. A. R. Hoare, “Communicating sequential processes,” in The Origin of


Concurrent Programming. Springer, 1978, pp. 413–443.

[11] C. Raistrick, “Model-based code generation,” Model-Driven Engineering for


Distributed Real-Time Systems: MARTE Modeling, Model Transformations and
their Usages, pp. 21–42.

[12] F.-X. Dormoy, “Scade 6: A model based solution for safety-critical software
52
development,” in Proceedings of the 4th European Congress on Embedded
Real-Time Software (ERTS’08), 2008, pp. 1–9.
[13] “Simulink,” www.mathworks.com/.

[14] “Osek/VDX operating system specification,” 2005.

[15] A. Biere, A. Cimatti, E. M. Clarke, O. Strichman, and Y. Zhu, “Bounded


model checking,” Advances in Computers, vol. 58, pp. 117– 148, 2003.

[16] D. Kroening and M. Tautschnig, “CBMC–C bounded model checker,” in


International Conference on Tools and Algorithms for the Construction and
Analysis of Systems. Springer, 2014, pp. 389–391.

[17] K. L. McMillan, “Symbolic model checking,” in Symbolic Model


Checking. Springer, 1993, pp. 25–60.

[18] B. Schlich and S. Kowalewski, “Model checking C source code for


embedded systems,” International Journal on Software Tools for Technology
Transfer, vol. 11, no. 3, pp. 187–202, 2009.

[19] H. Post and W. Küchlin, “Integrated static analysis for Linux device
driver verification,” in International Conference on Integrated Formal
Methods. Springer, 2007, pp. 518–537.

[20] D. Kroening and E. Clarke, The CPROVER User Manual, 2001.

[21] Y. Huang, Y. Zhao, L. Zhu, Q. Li, H. Zhu, and J. Shi, “Modeling and
verifying the code-level OSEK/VDX operating system with CSP,” in
Theoretical Aspects of Software Engineering (TASE), 2011 Fifth International
Symposium on. IEEE, 2011, pp. 142–149.

[22] D. Lettnin, P. K. Nalla, J. Ruf, T. Kropf, W. Rosenstiel, T. Kirsten,


53
V. Schönknecht, and S. Reitemeyer, “Verification of temporal
properties in automotive embedded software,” in Proceedings of the
Conference on Design, Automation and Test in Europe. ACM, 2008, pp.
164–169.

[23] D. Beyer, T. A. Henzinger, R. Jhala, and R. Majumdar, “The software


model checker BLAST,” International Journal on Software Tools for
Technology Transfer, vol. 9, no. 5-6, pp. 505–525, 2007.

[24] B. Schlich, F. Salewski, and S. Kowalewski, “Applying model checking


to an automotive microcontroller application,” in Industrial Embedded
Systems, 2007. SIES’07. International Symposium on. IEEE, 2007, pp. 209–
216.

[25] B. Schlich and S. Kowalewski, “[mc]square: A model checker for


microcontroller code,” in Second International Symposium on Leveraging
Applications of Formal Methods, Verification and Validation (Isola 2006),
Nov 2006, pp. 466–473.

[26] H. Zhang, T. Aoki, and Y. Chiba, “A spin-based approach for checking


OSEK/VDX Applications,” in International Workshop on Formal
Techniques for Safety-Critical Systems. Springer, 2014, pp. 239–255.

[27] G. J. Holzmann, “The model checker spin,” IEEE Transactions on Software


Engineering, vol. 23, no. 5, p. 279, 1997.

54
[28] T. Arts, J. Hughes, U. Norell, and H. Svensson, “Testing AUTOSAR
software with QuickCheck,” in Software Testing, Verification and Validation
Workshops (ICSTW), 2015 IEEE Eighth International Conference on. IEEE,
2015, pp. 1–4.

[29] J. Zhai, J. Huang, S. Ma, X. Zhang, L. Tan, J. Zhao, and F. Qin,


“Automatic model generation from documentation for java api functions,”
in Proceedings of the 38th International Conference on Software Engineering.
ACM, 2016, pp. 380–391.

[30] “lazy-cseq: a lazy sequentialization tool for c.”

[31] L. Sha, R. Rajkumar, and J. P. Lehoczky, “Priority inheritance protocols:


An approach to real-time synchronization,” IEEE Transactions on
Computers, vol. 39, no. 9, pp. 1175–1185, 1990.

[32] E. Gunter and D. Peled, “Unit checking: Symbolic model checking for a
unit of code,” in Verification: Theory and Practice. Springer, 2003, pp.
548–567.

[33] (2002) Erika enterprise. http://erika.tuxfamily.org.

[34] “Trampoline open source rtos project,” http://trampoline.rts-


software.org/.

[35] L. De Moura and N. Bjørner, “Z3: An efficient smt solver,” Tools and
Algorithms for the Construction and Analysis of Systems, pp. 337–340, 2008.

55
Modeling OSEK/VDX Operating System in C and Verifying
Applications Using the OS Model

Chung Yoohee

School of Computer Science and Engineering


Graduate School, Kyungpook National University
Daegu, Korea
(Supervised by Choi Yunja)

Abstract

This paper presents a method to model underlying operating systems in C


language and verify applications with the OS C model. The greatest benefit of
using C is the elimination of the heterogeneity between the OS model and
application code. This enables us to formally verify control software while
keeping its own characteristics. For this reason, using the C model, it is possible
to verify not only functional properties but also code safety properties of the target
program. This work proposes a two-step approach to maintain the abstraction level.
Instead of defining the model directly from the OSEK/VDX OS specification, a

formal CSP model is defined first and the C model is defined by using the CSP
model as a reference. The model was validated with two methods: property-based
validation via bounded model checking and simulation. With the validated model,
it was possible to verify application codes for two kinds of OSEK/VDX-based OS,
Erika Enterprise, and Trampoline OS. Not only functional properties, but also
code safety properties could be verified by using the C model.

56
C 언어를 이용한 OSEK/VDX 운영체제의 모델링 기법 및
이를 사용한 응용 프로그램의 검증

정유희

경북대학교 대학원 컴퓨터학부

지도교수 최윤자

(초 록)

본 논문은 C를 사용하여 차량 제어 소프트웨어 영역에서 광범위하게 사용되는 운영체제를


모델링하고, 작성된 모델을 응용 소프트웨어와 합쳐 검증하는 방법을 제시한다. 차량 제어
소프트웨어 영역에서 자주 사용되는 프로그래밍 언어인 C로 운영체제 모델을 작성하는 경우
운영체제 모델과 제어 소프트웨어 간의 불일치를 제거한다는 이점을 얻을 수 있다. 이로 인하여
제어 소프트웨어의 검증 단계에서 함수 호출, 외부 라이브러리 사용, 동적 메모리 할당 등과
같은 프로그램의 고유한 특성을 유지하는 것이 가능하다. 본 논문에서는 모델의 추상도를
유지하기 위하여 차량 전장용 운영체제 표준인 OSEK/VDX를 기반으로 한 운영체제
컴포넌트의 CSP 정형모델을 정의하고, 이를 참고하여 C 모델을 정의하는 2단계 방법론을
제시하였다. 이렇게 작성된 운영체제 모델의 검사에는 바운디드 모델 체커를 사용한 속성 기반
기법 및 시뮬레이션 기법이 사용되었다. 타당성이 확보된 운영체제 모델은 OSEK/VDX 기반
응용 소프트웨어를 검증하는데 사용되었고 프로그램의 기능적 속성 외에 코드 안전 속성을
검증하는 것이 가능하였다. 또한 코드의 수정을 최소화하며 운영체제 모델과 결합할 수 있었다.

57

You might also like