PEARL
PEARL

The Realtime- and Multitasking-Programming Language PEARL

Thomas Probol, Stefan Eilers, Torsten Lilge lilge@irt.uni-hannover.de,
last modification: 2000-03-6, location: http://www.irt.uni-hannover.de/pearl/pearlein.html

Inhalt

Basic data types and language structures

Better hardware independency

Multitasking-commands

Scheduling on events and time instants

Task synchronisation to avoid inconsistencies

In- and Output

Special data types

The name PEARL stands for Process and Experiment Automation Realtime Language and must not be mistaken for Perl, the Practical Extraction and Report Language.

PEARL is a higher programming language, which allows a comfortable, secure and almost processor independent programming of multitasking- and realtime problems and has been standardized since 1977 at various stages of its development, the last time 1998 as PEARL-90 (DIN 66253-2 1998, Berlin, Beuth-Verlag, 1998).

Besides the simple possibility to map process technical problems, an important principle at the development of PEARL was the easy learning by the programmer. Everyone who already knows a procedural programming language will get acquainted with PEARL in a very short time.

All basic data types and language structures of other procedural programming languages exist in PEARL (<). In addition PEARL offers comfortable language elements for the handling of multitasking- and realtime tasks (<).

/\


Basic data types and language structures

Data types:

Block structure, validity of objects:

Control structures:

Detailed information about the construction of PEARL is contained in

/\


Better hardware independency

To reach a separation from hardware dependent components, like for example in- and output interfaces, to the hardware independent program, a PEARL-module is subdivided into two parts:

  • In the so called system part, beginning after the keyword SYSTEM, the names for the hardware dependent I/O-interfaces are declared and their features defined. Here also interrupt sources can be defined.
  • The so called problem part, beginning withPROBLEM, contains for example variables, constants, tasks and procedures . Tasks and procedures have access to the interfaces defined in the SYSTEM-part.

/\


Multitasking-commands

The state of tasks known to the operating system can be modified in a PEARL-program.

/\


Scheduling on events and time instants

The activation and continuation of tasks can be executed to external events or time instants under certain conditions. Schedules to an exact clock-time, also schedules in case of external events (interrupts), are possible.

Examples:

/\


Task synchronisation to avoid inconsistencies

A synchronisation of tasks always becomes necessary when they jointly use data. The following three examples show how tasks can be synchronized with the use of 'semaphore-'(<) and 'boltvariables'(<). If a task A intends the access to a data record, which is just being handled by a TASK B, the operating system blocks task A until B releases the data. In connection with semaphores PEARL allows instead of a blockade also the "testing with entry when free" (keyword TRY in example (<)).

Critical paths

Critical paths arise, when 2 tasks intend to access shared objects at the same time. With the help of 'semaphore-variables'(<) a started access can be terminated unchecked, without interruption by other tasks, which also intend an access.


PROBLEM;
  DCL A           CHAR(255);        ! character string: 255 Bytes 
  DCL SEMVAR      SEMA  PRESET(1);  ! reservation: access allowed
  DCL FAILED FIXED INIT(0);

T1: TASK;
  DCL B1 CHAR(255);
  REQUEST SEMVAR;    A=B1;  RELEASE SEMVAR;
END;

T2: TASK;
  DCL B2(CHAR255);
  REQUEST SEMVAR;    A=B2;  RELEASE SEMVAR;
END;

TEST: TASK;
  IF TRY SEMVAR THEN
    RELEASE SEMVAR;  !release semaphore again
  ELSE
    FAILED=FAILED+1;
  FIN;
  AFTER 10 SEC ACTIVATE TEST;   ! self activation after 10 seconds
END;

Producer-consumer-schemes

If a task A produces data, which are provided for subsequent treatment by one or several other tasks, one talks about a producer-consumer-scheme. Following is the example of a ring storage with 1024 characters, of which the reading task always needs 2 at the same time.


PROBLEM;
  DCL PLACE_AVAILABLE   SEMA PRESET(1024);  
                             ! init: 1024 places free
  DCL CHARACTER_AVAILABLE SEMA PERSET(0);   
                             ! init: empty
DATAFETCH:  TASK;
  REQUEST CHARACTER_AVAILABLE; 
  REQUEST CHARACTER_AVAILABLE;
  FETCH_TWO_CHARACTERS_FROM_THE_RINGBUFFER;
  RELEASE PLACE_AVAILABLE; 
  RELEASE PLACE_AVAILABLE; 
END;

DATAPUT: TASK; 
  REQUEST PLACE_AVAILABLE; 
  PUT_ONE_CHARACTER_INTO_RINGBUFFER;
  RELEASE CHARACTER_AVAILABLE;
END;

Producer-consumer-schemes also occur at the digital measuring and the automation of production processes.

Data base management

When the programmer wants to allow the reading of a data record by several tasks simultaneously (in the example the tasks READER1 and READER2), but only one task can write without another task reading at the same time, BOLT-variables are the choice.


PROBLEM;
  DCL A CHAR(255);   ! character string: 255 Bytes 
  DCL BOLTVAR BOLT;  ! default initialisation: free

READER1: TASK;          
  DCL L1 CHAR(255);
  !ENTER allows, that all other tasks with ENTER 
  !can continue to run
  ENTER BOLTVAR;    L1=A;   LEAVE BOLTVAR;
END;

READER2: TASK;
  DCL L2 CHAR(255);
  ENTER BOLTVAR;    L2=A;   LEAVE BOLTVAR;
END;

WRITER1: TASK;
  DCL S1 CHAR(255);
  !After a RESERVE a task only continues to run if no other
  !reader or writer has executed an ENTER/RESERVE.
  RESERVE BOLTVAR;  A=S1;   FREE  BOLTVAR;
END;

WRITER2: TASK;
  DCL S2 CHAR(255);
  RESERVE BOLTVAR;  A=S2;   FREE  BOLTVAR;
END;

/\


In- and Output

PEARL offers an own keyword for each of the different in- and output forms. In the following examples alphic_dation stands for a harddisk, terminal, LCD-display and serial or parallel interface e. g., a basic_dation stands for an analog or digital process I/O e. g.

  • Output
    • formatted output
      PUT object1, ... TO alphic_dation BY format list;
    • binary output
      WRITE object1, ... TO alphic_dation;
    • output to process periphery
      SEND object1, ... TO basic_dation;
  • Input
    • formatted read-in
      GET object1, ... FROM alphic_dation BY format list;
    • binary read in
      READ object1, ... FROM alphic_dation;
    • read from process periphery
      TAKE object1, ... FROM basic_dation;

The sizes in the individual format lists can be fixed by constants and also by variables and function calls. They don't need to be known already at time of compilation..

/\


Special data types

/\