In the CERTAINTY project, an application is defined as a network of independent processes with the following features:

Similar documents
Functional Simulation of a Flight Management System

Appendix. Grammar. A.1 Introduction. A.2 Keywords. There is no worse danger for a teacher than to teach words instead of things.

A brief introduction to C programming for Java programmers

A Fast Review of C Essentials Part I

Programming refresher and intro to C programming

COMP-520 GoLite Tutorial

Short Notes of CS201

Auto-Pipe Software Block Interface v2. Interface. Contents. Auto-Pipe Types. From Auto-Pipe Wiki

Java Primer 1: Types, Classes and Operators

CS201 - Introduction to Programming Glossary By

CSCI 171 Chapter Outlines

APPENDIX A : Example Standard <--Prev page Next page -->

Pebbles Kernel Specification September 26, 2004

GOLD Language Reference Manual

Chapter 2. Procedural Programming

Features of C. Portable Procedural / Modular Structured Language Statically typed Middle level language

Creating a C++ Program

Basic Types, Variables, Literals, Constants

COMP322 - Introduction to C++ Lecture 02 - Basics of C++

Review of the C Programming Language for Principles of Operating Systems

Language Reference Manual simplicity

Libgdb. Version 0.3 Oct Thomas Lord

CSCI-243 Exam 1 Review February 22, 2015 Presented by the RIT Computer Science Community

Tokens, Expressions and Control Structures

CMPT 125: Lecture 3 Data and Expressions

CAN Module Documentation

ATOMS. 3.1 Interface. The Atom interface is simple: atom.h #ifndef ATOM_INCLUDED #define ATOM_INCLUDED

egrapher Language Reference Manual

COMP26120: Pointers in C (2018/19) Lucas Cordeiro

Advanced use of the C language

Review of the C Programming Language

Assembler Programming. Lecture 10

More about BOOLEAN issues

CSci 4061 Introduction to Operating Systems. Programs in C/Unix

BLM2031 Structured Programming. Zeyneb KURT

CE221 Programming in C++ Part 1 Introduction

P.G.TRB - COMPUTER SCIENCE. c) data processing language d) none of the above

Lectures 5-6: Introduction to C

by Pearson Education, Inc. All Rights Reserved.

CODE TIME TECHNOLOGIES. Abassi RTOS MISRA-C:2004. Compliance Report

Objectives. Introduce the core C# language features class Main types variables basic input and output operators arrays control constructs comments

Chapter 2 Using Data. Instructor s Manual Table of Contents. At a Glance. Overview. Objectives. Teaching Tips. Quick Quizzes. Class Discussion Topics

Static Code Analysis - CERT C Secure Code Checking

Data Types. Every program uses data, either explicitly or implicitly to arrive at a result.

Lecture Notes on Generic Data Structures

Final Exam. 11 May 2018, 120 minutes, 26 questions, 100 points

Sprite an animation manipulation language Language Reference Manual

DOL-Critical Tool Chain Description and Installation

Array. Prepared By - Rifat Shahriyar

C Formatting Guidelines

COMP520 - GoLite Type Checking Specification

Getting started with Java

THE CONCEPT OF OBJECT

Procedural programming with C

SOFTWARE QUALITY OBJECTIVES FOR SOURCE CODE

58 Building an Application

CS242 COMPUTER PROGRAMMING

Operating Systems. Lecture 06. System Calls (Exec, Open, Read, Write) Inter-process Communication in Unix/Linux (PIPE), Use of PIPE on command line

Section 3: File I/O, JSON, Generics. Meghan Cowan

Full file at

Introduce C# as Object Oriented programming language. Explain, tokens,

Variables Data types Variable I/O. C introduction. Variables. Variables 1 / 14

C++ Basics. Data Processing Course, I. Hrivnacova, IPN Orsay

Motivation was to facilitate development of systems software, especially OS development.

QUIZ. What are 3 differences between C and C++ const variables?

Chapter 2: Using Data

IAR Embedded Workbench MISRA C:2004. Reference Guide

The Warhol Language Reference Manual

1. Overview This project will help you understand address spaces and virtual memory management.

DAB/MOT Data Carousel System Support Library Interface Definition

Lectures 5-6: Introduction to C

Homework #3 CS2255 Fall 2012

Lexical Considerations

TS Further Interoperability of Fortran with C WG5/N1917

Thrift specification - Remote Procedure Call

PRINCIPLES OF OPERATING SYSTEMS

COMP520 - GoLite Type Checking Specification

Coding Standards for C

COMP520 - GoLite Type Checking Specification

The New C Standard (Excerpted material)

Object Oriented Design

Pointers, Pointers, Pointers!

VueMetrix Firmware Uploader

Design and development of embedded systems for the Internet of Things (IoT) Fabio Angeletti Fabrizio Gattuso

Motivation was to facilitate development of systems software, especially OS development.

C Review. MaxMSP Developers Workshop Summer 2009 CNMAT

EL6483: Brief Overview of C Programming Language

C# and Java. C# and Java are both modern object-oriented languages

6.096 Introduction to C++ January (IAP) 2009

GridLang: Grid Based Game Development Language Language Reference Manual. Programming Language and Translators - Spring 2017 Prof.

Anybus CompactCom. Host Application Implementation Guide. Doc.Id. HMSI Doc. Rev Connecting DevicesTM

Inno Setup Preprocessor: Introduction

Specifications for Managed Strings

Computers Programming Course 6. Iulian Năstac

Communications API. TEAM A : Communications and Integration Group. April 15, 1995

Adding Alignment Support to the C++ Programming Language / Consolidated

We do not teach programming

Fundamental Data Types. CSE 130: Introduction to Programming in C Stony Brook University

Kurt Schmidt. October 30, 2018

Lexical Considerations

Transcription:

C/C++ Coding Guide G. Giannopoulou, P. Huang, N. Stoimenov, L. Thiele April 15, 2014 This document describes how to program DOL-Critical applications using C/C++ as programming language. To be able to achieve a good performance of applications running on the MPPA-256 architecture platform, a certain coding style is required to program these applications. This coding style has been devised for the CERTAINTY project in which application code is expected to be programmed once, but can be used without any modification for different tool chains, e.g. functional simulation, hardware dependent software generation, and final system synthesis. Another key aspect of the CERTAINTY project is the design space exploration (DSE) used for generating a mapping of the application onto the MPPA architecture platform. To enable automatic DSE, an efficient extraction of key parameters of the application is required. Both aspects necessitate consistent code and a well-defined application programming interface. In the CERTAINTY project, an application is defined as a network of independent processes with the following features: Each process is characterized by a criticality level (safety levels DAL-A to DAL-E). Each process is associated with a controller process, which is responsible for activating the former according to a periodic, pseudo-periodic, asynchronous or restartable pattern, and conveying control information from other processes or from the system scheduler to it. A process can be executed in different modes, depending on the availability of input data or the run-time scheduling behavior. The different modes correspond to different, well-defined functionalities that need to be performed in each case. Each process is defined according to the superblock model of execution. Namely, it is defined as a sequence of communication and computation phases, where either accesses to a shared memory system or local 1

computation is performed. Based on static analysis, the characterization of these phases (lower and upper bounds on memory accesses and CPU execution cycles) is included in the application specification. The superblock model enables efficient timing/interference analysis. Processes can communicate directly through data channels, implemented as mailboxes or blackboards. Also, they can communicate with controller processes by transmitting event messages through control channels. The processes define the application s functionality. This document describes how to program these processes and their controllers as well as the communication between processes and between processes and controllers within the DOL-Critical framework. The key properties of the coding style are: The internal state of a process is stored in structure DOLCProcess. The details about this structure are given in Section 1. The behavior of a process is abstracted into three methods, namely init(), fire(), and terminate(). Execution modes and superblock phases are explicitly defined within fire() by a switch statement and the PHASE() function, respectively. The details about these functions are given in Section 2. Communication among processes is achieved by two main functions i.e., the non-blocking DOLC read() and DOLC write(). Communication between a process and a controller process is achieved by the two functions DOLC send event() and DOLC yield(), respectively. The details about these functions are given in Section 3. 1 Process Structure The interface to the internal state and the behavioral functions of a process is abstracted in the structure DOLCProcess. This structure DOLCProcess can be seen as an interface in the object-oriented sense that allows a unified access to any process, independent of the actual process-specific implementation. DOLCProcess contains five pointers, namely local, init, fire, terminate, and wptr, as shown in Listing 1: The local member, line 13, is a pointer to a structure that will store local information of a certain process. Local means that the data of the referenced structure is visible for just one process instance. 2

The init, fire, and terminate function pointers, lines 14, 15, 16, point to the corresponding behavior functions which are described in Section 2. These three functions differentiate the behavior of each process. The wptr pointer, line 17, is a place holder for tool-chain specific process information. In the DOL-Critical functional simulation, for instance, wptr is used to point to an instance of the C++ process class wrapper. 01 #ifndef DOLCRITICAL H 02 #define DOLCRITICAL H 03 04 struct d o l c p r o c e s s ; 05 typedef struct d o l c l o c a l s t a t e s DOLCLocalState ; 06 typedef void DOLCWPTR; 07 typedef void ( DOLCProcessInit ) ( struct d o l c p r o c e s s ) ; 08 typedef void ( DOLCProcessTerminate ) ( struct d o l c p r o c e s s ) ; 09 typedef int ( DOLCProcessFire ) ( struct d o l c p r o c e s s, int ) ; 10 11 // p r o c e s s handler 12 typedef struct d o l c p r o c e s s { 13 DOLCLocalState l o c a l ; 14 DOLCProcessInit i n i t ; 15 DOLCProcessFire f i r e ; 16 DOLCProcessTerminate terminate ; 17 DOLCWPTR cwptr ; 18 } DOLCProcess ; 19 20 #define PHASE( var ) { } ; 21 22 #endif Listing 1: Header File dolc.h (DOLCProcess) 2 Behavior Function The functional behavior of a process is split into three phases, an initialization phase, an execution phase, and a termination phase, which are defined in the three corresponding functions init(), fire(), and terminate(). Users are, however, free to add other methods, which can be called within init(), fire(), and terminate(). The init() function of each process is called once only. The purpose of this function is to initialize a process before running. The fire(int mode) function will be called repeatedly during runtime according to the activation pattern of a process. By calling fire(), 3

the runtime behavior of a process for a particular mode is activated. The execution modes of a process are defined as in Section 2.1. The terminate() function cleans up the runtime context of a process when this process is not to be executed (fired) again. It will be called once by the runtime scheduler before the process is terminated. The init(), fire(), and terminate() must not contain infinite loops. For inter-process and controller-process communication, the communication functions described in Section 3 can be used inside the init(), fire(), and terminate() functions. 2.1 Superblock Structure and Execution Modes Each process in the DOL-Critical XML application specification is defined as a sequence of non-preemptable execution units, known as superblocks. Each superblock is divided into phases with known computation and memory accessing requirements (upper and lower bounds on execution cycles and memory accesses). Additionally, we assume that each defined process can be executed in several modes, depending on input data availability, criticality mode, etc. The different implementations of a process for the different execution modes as well as the division of each implementation into superblock phases have to be clearly and consistently defined in the process code. For this purpose, function fire() has an input parameter mode, defining the execution mode of a process that needs to be triggered in every occasion. The mode parameter must comply with the following rules: For each execution mode of a process, a mode macro must be declared in the header file of the process. This declaration must take the following form: 01 #define MODE X mode id The identifier of the mode mode id is an integer and it must be the same as defined in the application XML file (e.g., 0 for degraded mode, 1 for normal mode, etc.). The name of the defined macro must have the prefix MODE and an arbitrarily selected suffix. It is prohibited to define any other macro having MODE as its prefix. Upon calling the fire() function, only the defined macro may be used, not the integer identifier itself: 01 f i r e ( p, MODE DEGRADED) ; 4

In the body of the fire() function, a switch(mode) structure defines the behavior of a process under the different execution modes, as shown, for instance, for the square process in Listing 4. For each execution mode of a process, the corresponding code is divided into superblock phases by using the pre-defined macro PHASE(phase id) at the beginning of every phase. The identifier phase id of each phase is a string (contained in ) and it must be the same as the corresponding phase name defined in the application XML file. 3 Communication Interface There are two sets of communication interface, (i) one for transmitting data over blackboard and mailbox data channels, and (ii) one for transmitting events among processes and process controllers, e.g., control data from a process to the controller of another process, dictating the restart of the latter. The primitives of the two interface sets are presented in the following sections. 3.1 Data Channel Communication Interface All processes use uniform communication primitives, which are summarized below: void DOLC read(void *port, DOLCData *buf, int len, DOLCProcess *p) attempts to read len DOLCData elements from port descriptor port into the buffer starting at buf. Reading is non-blocking (the function returns immediately if no data are available, with buf->valid = false) and semaphore-protected (data of a channel cannot be read and written simultaneously). It is non-destructive if port is an input port from a data channel of type blackboard and destructive for a data channel of type mailbox. int DOLC write(void *port, DOLCData *buf, int len, DOLCProcess *p) attempts to write len elements from the buffer starting at buf to port descriptor port. Writing is nonblocking and semaphore-protected (only one writer can update a channel s contents at a time and a channel cannot be read and written simultaneously). It is overwriting if port is an output 5

port to a data channel of type blackboard and non-overwriting (elements are appended) for a data channel of type mailbox. As a special case, writing invalid data (buf->valid = false) to a data channel of type mailbox can be used to effectively erase its previous contents (overwriting operation). If one attempts to exceed the capacity of a mailbox (by setting len to a value greater than the free elements of the mailbox), DOLC write returns 1. On the other hand, a return value of 0 indicates that writing was completed successfully. Note that the parameter DOLCProcess *p of the DOLC read() and DOLC write() primitives is used to store the address of the caller process. 3.1.1 Transmitted Data The data that can be read from or written to data channels (either blackboards or mailboxes) are defined by the data structure shown in Listing 2. The DOLCData structure includes a boolean variable valid, indicating the validity of the data, along with a pointer ptr to the data values that are to be read or written and an integer variable size, defining the size of a single channel element (token) in bytes. The data values may be of any type, integrated or used-defined. Therefore, type casting from the void* pointer to the pointer of the corresponding data type is necessary upon every assignment to ptr. New variables of type DOLCData can be declared and properly initialized using macro DOLCDataVar. 01 #ifndef DOLCRITICAL H 02 #define DOLCRITICAL H 03 04 typedef struct d o l c d a t a { 05 bool v a l i d ; // v a l i d i t y b i t 06 void ptr ; // p o i n t e r to a c t u a l data 07 unsigned int s i z e ; // s i z e o f one element in b y t e s 08 } DOLCData ; 09 10 #define DOLCDataVar( type, var ) type d a t a ##var ; \ 11 DOLCData var ; var. v a l i d=f a l s e ; \ 12 var. s i z e=s i z e o f ( type ) ; var. ptr = & d a t a ##var 13 14 #endif Listing 2: Header File dol.h (DOLCData) 6

Note that the third argument of all communication primitives is DOLCData *buf. 3.1.2 Port Access The first argument of the communication primitives is void *port. The following rules apply for this parameter. For each port which is accessed within a process, a port macro must be declared in the header file of the process. This declaration must take the following form: 01 #define PORT X portname The name of the port must be the same as defined in the application XML file. If the name of the port is an integer, portname is simply the corresponding integer. If the name of the port is a string, portname is the string in quotes. The name of the defined macro must have the prefix PORT and an arbitrarily selected suffix. It is prohibited to define any other macro having PORT as its prefix. Within a call to a communication primitive, only the defined macro may be used, not the string itself: 01 DOLC read ( ( void )PORT X, &b u f f e r, 1, p ) ; 3.2 Control Channel Communication Interface This communication interface is used to exchange control data among processes and controllers through the XML-defined control channels. we define two primitives that can be called within the fire() function of a process, namely DOLC send event() and DOLC yield(). void DOLC send event(void *port, void *event, DOLCCProcess *p) attempts to send an event encoded as a string to port descriptor port. The event is sent asynchronously, in zero time to a controller process other than the process s own controller, e.g., in order to change the execution mode or restart another process of the application. port specifies the control channel, through which the event is sent. 7

void* DOLC yield(void *event, DOLCProcess *p) interrupts the execution of function fire() of process p in order to check if its controller has received any new event. For example, the controller process may have to restart process p because of an event that it received from another process of the application or from the system scheduler. Process p will be informed about this decision upon calling DOLC yield with the event argument being set to null. If process p needs to also send an event to its controller, the event argument should be set accordingly. The response from the controller is encoded by the appropriate event identifier and returned by DOLC yield (null if no action needs to be taken). Note that undefined events will be discarded by the receiving process. Port access is defined as described in Section 3.1.2. 3.2.1 Event Access The second (first) argument of DOLC send event (DOLC yield() is void *event. The following rules apply for this parameter. For each event which is accessed within a process, a event macro must be declared in the header file of the process. This declaration must take the following form: 01 #define EVENT X eventname The name of the event must be the same as defined in the application XML file (e.g., restart) and has to be surrounded by quotes. The name of the defined macro must have the prefix EVENT. It is prohibited to define any other macro having EVENT as its prefix. Within a call to a communication primitive, only the defined macro may be used, not the string itself: 01 DOLC send event ( ( void )PORT P1, ( void )EVENT RESTART, p ) ; 4 Further Rules Besides the guidelines described above, there are some additional rules concerning program code that should be executed either using func- 8

tional simulation or on the MPPA platform. Some of them are summarized below: The structure for saving the user-defined local data of a process needs to be named complying with the following naming convention: Processname State, that is, the name of the process with the first letter capitalized followed by State. When a function has a pointer to a DOLCProcess structure as an argument, such as square init() and square fire() in the example of Listing 4, the argument name needs to be p. 5 Example An example implementation of a process complying with the described coding style is shown in Listings 3 and 4. The listings present the header and the C file of process square, which, in normal mode, reads a floating-point value from a data channel, computes the square value of it and then, writes it to a data channel. In degraded mode, square writes invalid data to the output data channel. In the header file, the ports and the execution modes of this process, the local data structure, and the behavior functions are declared. In the corresponding C file, the behavior functions are defined. 01 #ifndef SQUARE H 02 #define SQUARE H 03 04 #include<d o l c. h> 05 06 #define PORT INPUT p1 07 #define PORT OUTPUT p2 08 #define MODE NORMAL 1 09 #define MODE DEGRADED 0 10 #define EVENT FINISH f i n i s h 11 12 typedef struct d o l c l o c a l s t a t e s { 13 int index ; 14 } S q u a r e S t a t e ; 15 16 void s q u a r e i n i t ( DOLCProcess ) ; 17 void s q u a r e f i r e ( DOLCProcess, int ) ; 18 void s q u a r e t e r m i n a t e ( DOLCProcess ) ; 19 20 #endif Listing 3: Header File of square Process 9

01 #include <s t d i o. h> 02 #include square. h 03 04 void s q u a r e i n i t ( DOLCProcess p ) { 05 p >l o c a l >index = 0 ; 06 } 07 void s q u a r e f i r e ( DOLCProcess p, int mode ) { 08 f l o a t i ; 09 DOLCDataVar( float, i d a t a ) ; 10 11 switch ( mode){ 12 case MODE NORMAL: 13 PHASE( mode normal phase1 ) ; 14 DOLC read ( ( ( void )PORT INPUT, &idata, 1, p ) ; 15 i f ( i d a t a. v a l i d ) { 16 i = ( ( f l o a t ) i d a t a. ptr ) ; 17 ( ( f l o a t ) i d a t a. ptr ) = i i ; 18 i d a t a. v a l i d = t r u e ; 19 } 20 DOLC write ( ( void )PORT OUTPUT, &idata, 1, p ) ; 21 22 PHASE( mode normal phase2 ) ; 23 p >l o c a l >index++; 24 p r i n t f ( P r o c e s s square has been f i r e d %d times., p >l o c a l >index ) ; 25 26 DOLC yield ( ( void )EVENT FINISH, p ) ; 27 return ; 28 29 case MODE DEGRADED: 30 PHASE( mode degraded phase1 ) ; 31 i d a t a. v a l i d = f a l s e ; 32 DOLC write ( ( void )PORT OUTPUT, &idata, 1, p ) ; 33 DOLC yield ( ( void )EVENT FINISH, p ) ; 34 return ; 35 } 36 } 37 void s q u a r e t e r m i n a t e ( DOLCProcess p ) { 38 // f r e e i n g p o i n t e r s o f Square State, e r a s i n g data from mailboxes 39 // would happen here ( not needed in t h i s simple example ) 40 } Listing 4: C File of square Process 10