Vous êtes sur la page 1sur 188

PXROS V4 Users Guide Version 1.

3;5269HUVLRQ

9HUVLRQ

Users Guide

HighTec EDV-Systeme GmbH Author: Werner Schwarz


Feldmannstr. 98 Date: 20. May 1996
D-66119 Saarbrcken
Tel: 0681/92613-0
FAX: 0681/92613-26
Email: htc@hightec.saarlink.de

HighTec EDV-Systeme GmbH 1 20. Mai 1996


PXROS V4 Users Guide Version 1.0

HighTec EDV-Systeme GmbH 2 20. Mai 1996


PXROS V4 Users Guide Version 1.0

7DEOH2I&RQWHQWV

1 Introduction.................................................................................................................9
1.1 PXROS................................................................................................................9
1.2 The Users Guide...............................................................................................10
2 PXROS.....................................................................................................................13
2.1 Structures and Mechanisms..............................................................................14
2.2 PXROS Objects.................................................................................................16
2.2.1 Tasks..........................................................................................................16
2.2.2 Messages...................................................................................................17
2.2.3 Mailboxes...................................................................................................17
2.2.4 Memory Classes.........................................................................................17
2.2.5 Object Pools...............................................................................................18
2.2.6 Delay Objects.............................................................................................18
2.3 Name Conventions............................................................................................18
2.3.1 PXROS Services........................................................................................18
2.3.2 PXROS Data Types, Macros, ....................................................................20
3 Tasks........................................................................................................................21
3.1 Creating Tasks with a Standard Function..........................................................22
3.2 Task Code.........................................................................................................23
3.3 Task Communication.........................................................................................25
3.3.1 Data Communication via Messages...........................................................25
3.3.2 Signalling Events........................................................................................25
3.4 Killing Tasks......................................................................................................26
4 Building the Sample Programs.................................................................................27
4.1 Process.............................................................................................................27
4.2 Initialization Phase............................................................................................28
5 Communication through Messages..........................................................................29
5.1 Summary...........................................................................................................29
5.2 Generating Messages.......................................................................................30
5.3 Writing and Evaluating Message Data..............................................................31
5.4 Sending and Receiving Messages....................................................................32
5.5 Releasing Messages.........................................................................................33
5.6 Using an Existing Data Area..............................................................................36
5.7 Message Pools..................................................................................................38
5.8 Examples...........................................................................................................40
5.8.1 ex1.c...........................................................................................................40
5.8.2 ex2.c...........................................................................................................43
5.8.3 ex3.c...........................................................................................................45
5.8.4 ex4.c...........................................................................................................48
6 Events.......................................................................................................................51
6.1 Summary...........................................................................................................51
6.2 Signalling Events...............................................................................................52
6.3 Waiting for Events.............................................................................................52
6.4 Resetting Events...............................................................................................53
6.5 Other Functions.................................................................................................54
6.5.1 Parallel Waiting..........................................................................................54
6.5.2 Aborting Functions with Events..................................................................54
6.6 Examples...........................................................................................................55
6.6.1 ex.c.............................................................................................................55
6.6.2 ex2.c...........................................................................................................57

HighTec EDV-Systeme GmbH 3 20. Mai 1996


PXROS V4 Users Guide Version 1.0

7 Memory Management...............................................................................................59
7.1 Summary...........................................................................................................59
7.2 Memory Requests.............................................................................................59
7.3 Memory Classes................................................................................................60
7.3.1 Creating Memory Classes..........................................................................60
7.3.2 Memory Classes with a Variable Block Size..............................................61
7.3.3 Memory Classes with a Fixed Block Size...................................................62
7.3.4 Allocating and Releasing Memory..............................................................62
7.4 Use of Different Memory Classes in the System...............................................63
7.5 Tips for Developers...........................................................................................64
7.6 Examples...........................................................................................................64
7.6.1 ex1.c...........................................................................................................64
7.6.2 ex2.c...........................................................................................................65
8 PXROS Time............................................................................................................67
8.1 Summary...........................................................................................................67
8.2 PXROS Time Base............................................................................................67
8.3 Standard Services.............................................................................................68
8.3.1 Timeouts....................................................................................................68
8.3.2 Periodic Events..........................................................................................69
8.4 Delay Jobs.........................................................................................................70
8.4.1 Delay Job Resources.................................................................................70
8.4.2 Starting a Delay Job...................................................................................71
8.4.3 Cancelling a Delay Job...............................................................................73
8.5 Examples...........................................................................................................74
8.5.1 ex1.c...........................................................................................................74
8.5.2 ex2.c...........................................................................................................76
8.5.3 ex3.c...........................................................................................................77
8.5.4 ex4.c...........................................................................................................79
8.5.5 ex5.c...........................................................................................................80
9 Mailboxes..................................................................................................................83
9.1 Summary...........................................................................................................83
9.2 Creating Mailboxes............................................................................................83
9.3 Mailbox Handlers...............................................................................................84
9.4 Examples...........................................................................................................85
9.4.1 ex1.c...........................................................................................................86
10 Objects and Object Pools.......................................................................................89
10.1 Summary.........................................................................................................89
10.2 Generating Object Pools.................................................................................90
10.2.1 Virtual Object Pools..................................................................................91
10.2.2 Real Object Pools....................................................................................91
10.3 Generating Additional Objects.........................................................................92
10.4 Using Different Object Pools in the System....................................................92
10.5 Other Services.................................................................................................93
10.6 Examples.........................................................................................................93
10.6.1 ex1.c.........................................................................................................93
10.6.2 ex2.c.........................................................................................................95
11 Interrupt Interface...................................................................................................97
12 Error Handling.........................................................................................................99
12.1 Summary.........................................................................................................99
12.2 Runtime Errors................................................................................................99
12.3 Application Errors..........................................................................................100

HighTec EDV-Systeme GmbH 4 20. Mai 1996


PXROS V4 Users Guide Version 1.0

12.4 Example........................................................................................................100
12.4.1 ex1.c.......................................................................................................101
13 Scheduling............................................................................................................103
13.1 Summary.......................................................................................................103
13.2 Hardware Interrupt Handlers.........................................................................103
13.3 Software Interrupt Handlers..........................................................................104
13.4 Task Scheduling............................................................................................104
13.4.1 Tasks of Equal Priority...........................................................................105
13.4.2 Special Types.........................................................................................105
13.5 Example........................................................................................................105
14 Creating Tasks......................................................................................................107
14.1 ts_name.........................................................................................................108
14.2 ts_fun.............................................................................................................108
14.3 ts_mc.............................................................................................................108
14.4 ts_opool.........................................................................................................109
14.5 ts_taskstack...................................................................................................109
14.5.1 Automatic Stack Request.......................................................................110
14.5.2 Explicit Stack Allocation.........................................................................110
14.5.3 Choosing a Stack Size...........................................................................110
14.6 ts_tblimit........................................................................................................111
14.7 ts_prio............................................................................................................111
14.8 ts_actevents..................................................................................................112
14.9 ts_timeslices..................................................................................................112
14.10 ts_abortstack, ts_abortstacksize.................................................................112
14.11 ts_sched_extension, ts_sched_initarg........................................................114
14.12 ts_privileges.................................................................................................114
14.13 ts_int_dummies...........................................................................................114
14.14 ts_context....................................................................................................114
14.15 ts_addr_dummies........................................................................................114
14.16 Features of the Initialization Task................................................................114
14.17 Example......................................................................................................115
15 PXROS Initialization.............................................................................................117
15.1 A Standard Initialization.................................................................................117
15.2 Initialization Details........................................................................................118
15.2.1 is_sysmc_type,is_sysmc_size................................................................119
15.2.2 is_sysmc_blk, is_sysmc_blksize............................................................119
15.2.3 is_obj_number, is_obj_namelength.......................................................119
15.2.4 is_inittask...............................................................................................119
15.2.5 is_monitoring..........................................................................................120
15.2.6 is_int_dummies......................................................................................120
15.2.7 is_schedext............................................................................................120
15.2.8 is_addr_dummies...................................................................................121
15.3 Example........................................................................................................121
16 Common Task Data..............................................................................................123
16.1 Example........................................................................................................124
16.1.1 Ex1.c......................................................................................................124
17 Abort Mechanism..................................................................................................127
17.1 Summary.......................................................................................................127
17.2 Using the Abort Mechanism..........................................................................127
17.3 Activation and Deactivation of the Abort Mechanism ....................................128
17.4 Implicit deactivation with PXROS Services...................................................129

HighTec EDV-Systeme GmbH 5 20. Mai 1996


PXROS V4 Users Guide Version 1.0

17.5 Protecting resources......................................................................................131


17.6 Example........................................................................................................133
17.6.1 Ex1.c......................................................................................................133
18 Processor Dependent Services............................................................................135
18.1 PXROS for Siemens C16x Processors.........................................................135
18.1.1 Interrupt Interface...................................................................................135
18.1.1.1 Definig Handlers Dynamically.........................................................135
18.1.1.2 Defining Handlers Statically............................................................135
18.1.1.3 Trap Vector Table in EPROM.........................................................136
18.1.2 Task Context..........................................................................................136
18.2 PXROS for Intel 80x86 Processors...............................................................137
18.2.1 Interrupt Interface...................................................................................137
18.2.2 Task Context..........................................................................................137
19 Services for Specific Versions of PXROS.............................................................139
19.1 Scheduling Extensions..................................................................................139
19.1.1 Global Scheduling Extensions...............................................................139
19.1.2 Task Scheduling Extensions..................................................................140
19.2 Handler-Send................................................................................................141
19.3 Time Slicing...................................................................................................141
20 Using PXROS with EPROMs................................................................................143
20.1 Siemens C16x Family with the GNU Development tools..............................143
20.1.1 Interrupt Interface...................................................................................143
20.1.2 Compiler Options...................................................................................143
20.1.3 Linker Map File.......................................................................................144
20.1.4 Potential Problems.................................................................................144
21 Using Pxmon / Pxmon-RT....................................................................................145
22 PXROS and C++..................................................................................................147
23 Creating a PXROS Application.............................................................................149
23.1 Siemens C16x Processors............................................................................149
23.1.1 Makefile..................................................................................................149
23.1.2 Special Notes.........................................................................................152
24 Utility Library.........................................................................................................153
24.1 Management of Global Task Data.................................................................153
24.1.1 PxuAppinfoSetComp, PxuAppinfoUpdateComp ....................................153
24.1.2 PxuAppinfoGetComp.............................................................................154
24.1.3 PxuAppinfoCleanupComp......................................................................154
24.2 New Memory Classes....................................................................................154
24.2.1 PxuCreateFixblkPool..............................................................................154
24.2.2 PxuCreateVarblkPool.............................................................................155
24.3 Cleaning Up After an Abort...........................................................................155
24.3.1 PxuCleanupInit.......................................................................................157
24.3.2 PxuCleanupPush...................................................................................158
24.3.3 PxuCleanupGetId...................................................................................158
24.3.4 PxuCleanupActivate...............................................................................158
24.3.5 PxuCleanupPop.....................................................................................158
24.4 Waiting at Different Mailboxes Simultaneously .............................................159
24.5 Message Pools..............................................................................................160
24.6 Protected Data..............................................................................................161
24.6.1 PxuPobjCreate, PxuPobjDelete.............................................................161
24.6.2 PxuPobjRequestRefData.......................................................................161
24.6.3 PxuPobjReleaseRefData.......................................................................162

HighTec EDV-Systeme GmbH 6 20. Mai 1996


PXROS V4 Users Guide Version 1.0

24.7 Memory Requests.........................................................................................162


24.7.1 malloc.....................................................................................................162
24.7.2 realloc.....................................................................................................163
24.7.3 calloc......................................................................................................163
24.7.4 free.........................................................................................................163
24.8 PXROS Initialization......................................................................................163
24.9 Task Creation................................................................................................164
24.10 Time Conversion.........................................................................................165
24.11 Ring Buffers with waking functions..............................................................165
24.11.1 PXUWrbDefineType.............................................................................166
24.11.2 Initialization..........................................................................................166
24.11.2.1 PXUWrbInit, PXUWrbClear ..........................................................166
24.11.2.2 PXUWrb~Init_Buffer, ~SetPutControls, ~SetGetControl ..............168
24.11.3 PXUWrbGet, PXUWrbPut ....................................................................168
24.11.4 PXUWrbGetReadPointer, PXUWrbAdvanceReadPointer ...................169
24.11.5 PXUWrbGetWritePointer, PXUWrbAdvanceWritePointer ...................169
24.11.6 PXUWrbGetElemNum, PXUWrbIsFull, PXUWrbIsEmpty ....................170
24.12 Measuring the System Load........................................................................170
24.12.1 PxuSysloadCalibrate............................................................................170
24.12.2 PxuSysloadStartMeasure.....................................................................171
24.12.3 PxuSysLoadGetMeasure.....................................................................171
24.12.4 PxuSysloadEnd....................................................................................171
24.13 Messages....................................................................................................171
24.13.1 Synchronous Communication..............................................................172
24.13.1.1 PxuReqSynInit..............................................................................172
24.13.1.2 PxuReqSynOpen..........................................................................172
24.13.1.3 PxuReqSyn...................................................................................172
24.13.1.4 PxuReqSynClose..........................................................................173
24.13.2 Asynchronous communication.............................................................173
24.13.3 Receiver Services................................................................................173
24.13.3.1 PxuReqReceive............................................................................174
24.13.3.2 PxuReqDecode.............................................................................174
24.13.3.3 PxuReqAck...................................................................................175
25 Glossary................................................................................................................177
25.1 Delay Jobs.....................................................................................................177
25.2 Events...........................................................................................................177
25.3 Handlers........................................................................................................177
25.4 Mailbox..........................................................................................................177
25.5 Mailbox Handlers...........................................................................................178
25.6 Memory Classes............................................................................................178
25.7 Messages......................................................................................................178
25.8 Objects..........................................................................................................178
25.9 Object Pools..................................................................................................178
25.10 Private Mailbox............................................................................................179
25.11 Priority.........................................................................................................179
25.12 PXROS Ticks...............................................................................................179
25.13 Resource Distribution..................................................................................179
25.14 Tasks...........................................................................................................180
25.15 Time Slicing.................................................................................................180
26 Index.....................................................................................................................181

HighTec EDV-Systeme GmbH 7 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 ,QWURGXFWLRQ

 3;526

PXROS (pronounced pixros), is the acronym and stands for 3ortable e;tendible
5 ealtime 2perating 6ystem. It is a realtime operating system kernel and may be used
as a platform for a variety of realtime applications. PXROS services are provided in
libraries. This means the the code corresponds largely to the functionality needed.

Two libraries are used for developing applications: the GHEXJ library, used in the
development stage, and the SURGXFWLRQ library, which is used for the completed project.
Both libraries offer the application the same interface and functionality, the difference
lying in the service testing perfomed. To detect errors in the early stages of
development, PXROS conducts extensive checks and tests when executing services
from the debug library. These tests however, increase the run time and the code
requirements; therefore, the production library is used once development is completed.
The production library does not perform these tests, thus providing better run time
performance and lower code requirements.

In addition to standard PXROS, other versions exist with extended functionality. These
include a multiprocessor communication version, a version that provides priority-based
semaphores, and a version extends the normal scheduling with time slicing. Most of
these extended services are not described in this Users Guide.

PXROScompact is another PXROS variation. It differs from the standard version mainly in
that tasks and PXROS objects can not be generated dynamically. The applications
structure must be defined statically. Fewer services means less code, thereby reducing
the size of the final application. PXROScompact is useful in small applications with very
limited space for code. The Users Guide describes the full-featured PXROS services
and does not deal with PXROS compacts features specifically.

3;PRQ is a debugging tool used in conjunction with PXROS. It allows the developer to

examine and alter memory locations and variables while UXQQLQJ the application.
PXmon recognizes internal PXROS structures and provides specific PXROS
information about resource consumption, the state of tasks, or the scheduling of the
system. The extended version, 3[PRQ57 offers UHDOWLPH GHEXJJLQJ during final
testing, including task-specific breakpoints and single-stepping tasks (i.e. without
stopping the whole system). PXmon is described in detail in chapter 21.

HighTec EDV-Systeme GmbH 8 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 7KH8VHU
V*XLGH

The Users Guide is a resource intended to assist in the development of individual


PXROS applications. It describes PXROS mechanisms and services that can help
solve problems. To understand the Users Guide, no previous knowledge of PXROS is
required, and the applied terminology and principles are dealt with in detail. The Users
Guide does not explain how to e.g. translate a C-program for specific target hardwares,
how to use a debugger, or how to load the completed program.

The Users Guide is structured as follows:

The next two chapters briefly introduce PXROS structures and its underlying
mechanisms, as well as some of the more important terms used. This introduction is
intended to prepare you for the following chapters and should not be ignored.

Individual PXROS mechanisms and the services related to them, are explained later in
the corresponding chapters. Each chapter begins with a summary of the most
important information. Processes and various services are briefly described, followed
by detailed explanations of the subject and a full-length description of the relevant
services. At the end of most chapters, the Users Guide contains a description of
sample programs related specifically to the subjects at hand. Their source code can be
found on the accompanying disk. These programs should illustrate specific aspects of
use in relation to the services concerned. The starting phase and the basic execution of
all of the sample programs are similar. For this reason, they are explained in a separate
chapter.

Beginning with chapter 16, information not absolutely necessary to become acquainted
with PXROS is presented. These chapters are intended for advanced PXROS users.
They explain services that make use of processor-specific properties, as well as
services generally considered beyond PXROS standard usage.

As reader of the Users Guide, you should try to implement your own applications as
soon as possible. To do so, one should obtain a general overview of the structures and
mechanisms used in PXROS applications. Users are advised to read the summary at
the beginning of each chapter, and examples at the end. It is also advisable to compile
and run the sample programs on a target system. In this way, the description of the
program flow can be more easily understood, especially when using a debugger (e.g.
JGE). Afterwards, one might implement and experiment with smaller applications. At

this point, one generally runs across questions that can usually be answerd by reading
the detailed service descriptions.

Beginners can generally ignore the subjects at the end of the Users Guide as they
describe concepts only important in more complex applications.

An additional utility library disk, including source code, is also available from HighTec
and can be used to help implement PXROS applications. The utility services are
explained in the final chapter. Together with the source code, these explanations can
provide you with further hints for using PXROS functions.

The Users Guide is intended to help you work your way into PXROS. It can only do so

HighTec EDV-Systeme GmbH 9 20. Mai 1996


PXROS V4 Users Guide Version 1.0

if it meets the readers needs. For this reason, we depend on your assistance in
improving the Users Guide: please report any mistakes you might find, and let us know
if explanations are insufficient or lead to misunderstandings. We would appreciate any
suggestions or ideas you might have.

HighTec EDV-Systeme GmbH 10 20. Mai 1996


PXROS V4 Users Guide Version 1.0

HighTec EDV-Systeme GmbH 11 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 3;526

The PXROS Realtime Operating System assists in the development of an application.


It facilitates a modular software design drastically reducing development and
maintenance requirements:

An application consists of many different functions (e.g. control, EEPROM


programming, communication with the user). These segments are implemented
individually in modules, the services of which are available over a fixed interface. The
completed application then consists of individual modules which can be applied in
GLIIHUHQW FRQWH[WV. Later, a stock of tested modules can be called upon to quickly

implement new applications. Additional modules may then be generated as needed.

PXROS encourages a modular software design with its task concept: different parts of
the application are implemented independently from one another. PXROS allows these
programs to run in quasi-parallel in units called WDVNV. Each task runs within its own
execution context, and thus inherits all associated administrative problems (e.g. the
allocation of processor time, and the reconstruction of the execution context for the
running task).

PXROS provides numerous modules to perform standard functions. These include


resource management, data exchange between tasks and scheduling. By using
existing services, the user is free to concentrate on the application at hand, rather than
constantly "reinventing the wheel".

In summary, PXROS works with a series of small, manageable functional units called
tasks. In addition to coordinating the tasks, the operating system provides the
foundation upon which the application runs. Finally, PXROS offers a number of
services for managing the application and the interaction of its inividual components.

HighTec EDV-Systeme GmbH 12 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 6WUXFWXUHVDQG0HFKDQLVPV

Most of a PXROS application is comprised of tasks. Each task is allocated a certain


amount of processor time in which to execute its code. This method is called
SUHHPSWLYH SULRULW\EDVHG VFKHGXOLQJ. PXROS assigns each task a so-called SULRULW\.

The scheduling principle dictates that higher priority tasks may always interrupt lower
priority tasks to execute their functions.

Priorities
high priority

Hardware Interrupt Handler


(Mutually interrupting based on their respective interrupt priorities)

Software Interrupt Handler


(do not interrupt one another)

Tasks
(mutually interrupting based on their respective task priorities)

low priority

Tasks do not make up all of the applications functions. Highly critical functions (with
respect to time) are performed by functional units called KDQGOHUV.

These include, for example, interrupt routines that intercept hardware interrupts and
periodically-activated regulator routines. Handlers are processed at a higher priority
than tasks, i.e. a handler may always interrupt a running task; in contrast however,
hardware interrupt handlers not only interrupt tasks, but software interrupt handlers as
well. In fact, hardware interrupt handlers even interrupt the operating system itself!

Handlers interrupt other handlers based on the priority level of their respective
hardware interrupts. In other words, a higher priority handler may interrupt a lower
priority handler. This hierarchy does not exist among software interrupt handlers, which
may not interrupt one another. Software interrupt handlers run in parallel as "equals"
and are scheduled according to a "first come, first served" algorithm.

A task rarely works in isolation; rather, it is usually associated with other tasks or
handlers. For example, tasks may cooperate with other tasks by requesting information
from them, a handler may inform the task that a hardware signal has been intercepted,
or a task may regulate a handlers work. PXROS provides the two important
mechanisms for transferring data between tasks and handlers: PHVVDJHV and VLJQDOV.

During PHVVDJH H[FKDQJH, one tasks data are prepared as a message, which is then
sent to a mailbox. A second task receives the message, at which point the message is
evaluated. PXROS provides the necessary services to create, send and receive
messages. Except in special versions of PXROS, the mailbox services are only
available to tasks (i.e. they may not be used by handlers).

HighTec EDV-Systeme GmbH 13 20. Mai 1996


PXROS V4 Users Guide Version 1.0

In addition to messages, the occurance of an HYHQW may be VLJQDOOHG to a task. Both


tasks and handlers may signal an event; however, only tasks can receive them. Events
cannot be signalled to handlers.

$VDPSOHDSSOLFDWLRQ

Implement a system control program which receives instructions via a PCs serial
interface:

System requirements:

one task (Task1) to receive and evaluate messages


one task (Task2) to process messages and control the regulator routine
one interrupt handler for writing and reading to and from the serial receive
and transmit buffers
periodic handler to regulate a motor.

R eceive-Interrupt
U ser Interfacer (S erial Interface)
T ask 1

T ransm it-Interrupt
(S erial Interface)
Job R equests
and
R esponses

C ontrol of the periodische


M otor and T ask 2
R egelungsroutine
Feedback

While Task2 processes jobs and the periodic handler, Task1 is able to continue
receiving messages, thus allowing jobs to be cancelled. Allocating two separate tasks
allows one to logically implement the control and communication modules separately.
Also, by changing the software interface to the PC (or other hardware device), the task
can be used in other applications without modification.

PXROS not only offers services for exchanging data, it administers dynamically
allocatable memory. Furthermore, PXROS is equipped with a system clock for time-
based routines. The use of RQO\ RQH periodic interrupt source (e.g. the hardware timer)
allows the application to fulfill the systems realtime requirements. The application fixes
the system clocks frequency, thus keeping the system load to a minimum.

 3;5262EMHFWV

HighTec EDV-Systeme GmbH 14 20. Mai 1996


PXROS V4 Users Guide Version 1.0

Most PXROS services are associated with either related a task or a PXROS REMHFW

PXROS recognizes the following object types:

PHVVDJHREMHFWV , PDLOER[HV, PHPRU\FODVVHV, REMHFWSRROVand GHOD\REMHFWV.

PXROS services FUHDWH or GHOHWH all PXROS objects. Additionally, PXROS provides
other special services for using the different object types. To ensure security, all
changes to objects must be performed via PXROS services. When an object is
created, it receives an LGHQWLILHU from PXROS which clearly sets it apart from other
PXROS objects.

Certain special objects are available in special PXROS versions, such as priority-based
VHPDSKRUHV , which provide communication via semaphores, or FKDQQHOV which permit
communication with PXROS objects residing on other processor. These object types
are not provided with the standard version of PXROS and are therefore not dealt with in
the Users Guide.

In the following, tasks and object types are briefly described:

 7DVNV

The term task was introduced at the beginning of this chapter: an


application generally performs several jobs. PXROS allows one to
implement these jobs in specific subprograms, each with its own
execution context within the entire system. These subprograms are
referred to as PXROS WDVNV The function associated with a task is
referred to as the WDVN FRGH. Based on the individual tasks SULRULW\,
PXROS allocates the task processing time for executing its code. Tasks
Task
can mutually interrupt one another. In cases such as this, PXROS
restores the tasks context before it becomes active again.
The tasks code is executed with full access to the processors registers and with a
stack of its own. Once reactivated, the task is continued at the point at which was
previously interrupted.

HighTec EDV-Systeme GmbH 15 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 0HVVDJHV

PXROS applications use messages to communicate between


tasks. A PHVVDJH is a message object that is associated with
a specific data area. The sending task is said to "own" (i.e.
control) this data range. The receiving task evaluates the
message as it is received. When required, messages can be
dynamically generated or, alternatively reused. It is possible to
create messages before using them and store them in
separate objects called PDLOER[HV A task may draw one of the prepared messages
from a mailbox at any time. This is generally considerably more efficient than creating
messages as they are needed. Prepared messages have the benefit of shortening the
applications run time.

 0DLOER[HV

A mailbox stores messages in the order they arrive, until they are withdrawn and
evaluated. A task always receives the message that has been stored in the mailbox the
longest (one exception: SULRULWL]HG PHVVDJHV are released before other messages). If
the queried mailbox is empty, the task has the option to wait until a message arrives. In
some cases, a a number of tasks may wait at the same mailbox for a message to
become available. The task with the longest waiting period receives any message
arriving. One can not specify which message a task receives upon arrival at the
mailbox.

 0HPRU\&ODVVHV

PXROS manages the dynamically allocated memory used in


the application. It is possible to divide the memory into
separate memory classes, which may further be assigned to
specific application modules. This permits a local limit to be
placed on memory usage. Every PXROS application uses the
so-called V\VWHP PHPRU\ FODVV, from which memory is taken
for other memory classes. Essentially this feature manages
the memory available to PXROS system functions, e.g. for
creating of tasks.

Memory classes are classified as either YDULDEOH or IL[HGVL]H memory classes. Using
fixed size memory classes improves the processing speed for memory administration.
In contrast, variable size memory classes are more flexible, but can lead to PHPRU\
IUDJPHQWDWLRQ. This occurs when the memory is divided into a number of little blocks

which can no longer be connected together. Consequentially, it is possible that a


memory request can not be fulfilled since no block of adequate size exists, even though
the cumulative amount of free memory would be sufficient to meet the applications
needs.
When the application requests memory dynamically, it must specify the memory class
from which is takes its memory. The macro 3;0F6\VWHPGHIDXOW indicates the system
memory class.
HighTec EDV-Systeme GmbH 16 20. Mai 1996
PXROS V4 Users Guide Version 1.0

 2EMHFW3RROV

All unused PXROS objects are kept in object pools. Objects can be
distributed to different object pools, from where they are in turn
assigned to certain parts of the application. In this way, resource can
be contained locally. Every PXROS application uses a V\VWHP SRRO,
which initially contains all objects generated, and from which objects
for other object pools can be drawn.

PXROS differentiates between two types of object pools: UHDO and YLUWXDO object pools.
Real object pools serve to physically divide objects into different pools. Virtual object
pools on the other hand, are merely an abstraction useful for restricting and controlling
access to objects.

When the application requests objects, it must always specify the object pool from
which the object is to be taken. The macro
3;2SRRO6\VWHPGHIDXOW indicates the system pool.

 'HOD\2EMHFWV

Delay objects are used to implement time-based routines.


PXROS associates an routine with each delay object. This
tells the delay object to call the corresponding function after a given period
of time. The function is executed on the KDQGOHU level and therefore
interrupts the task in process.

 1DPH&RQYHQWLRQV

 3;5266HUYLFHV

The following conventions form the names of PXROS services:

Px[class][verb][object][extension]

PXROS services can be easily recognized by the prefix 3[ . This avoids confusion
between these and other routines.

HighTec EDV-Systeme GmbH 17 20. Mai 1996


PXROS V4 Users Guide Version 1.0

>FODVV@ defines the type of object the service operates on. Service classes include:

7DVN : task
0VJ : messages
0E[ : mailboxes
0F : memory classes
2SRRO : object pools
'HOD\ : delay objects

If a name does not specify a class, the service usually operates on the calling task.

>YHUE@ indicates the actual function of the service, e.g. FUHDWH


, LQLW, UHTXHVW.

>REMHFW@ indicates which part of the service is concerned and is dependent on the class.

>H[WHQVLRQ@ indicates specific variants of the basic service:

For example, B+QG indicates that the service variant can only be used by handlers.
Certain PXROS services may only be called by tasks, others by both handlers and
tasks. In the latter case, the services often have two variants: one for use by tasks, and
the other specially optimized for use on handler level. In this case, the names
extension is BB+QG, and the service may only be used by handlers, otherwise PXROS
will report an error.

B(Y:DLW is another extension that indicates a service that can enter a ZDLW VWDWH to e.g.
receive an object. The wait state is cancelled if e.g. certain user-defined events occur.
The functions return value contains the events that led to termination of the wait state.

([DPSOHV

SUHIL[ FODVV YHUE REMHFW H[WHQVLRQ

>3[@ >0E[@ >&UHDWH@ >@ >@

>3[@ >7DVN@ >6LJQDO@ >(YHQWV@ >@

>3[@ >7DVN@ >6LJQDO@ >(YHQWV@ >B+QG@

>3[@ >@ >*HW@ >,G@ >@

>3[@ >0VJ@ >5HFHLYH@ >@ >B(Y:DLW@

HighTec EDV-Systeme GmbH 18 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 3;526'DWD7\SHV0DFURV

Important data types defined by PXROS are called LGHQWLILHUV, or simply ,Gs. Upon their
creation, PXROS assigns all tasks and objects a specific Id. A data type name is
recognized by its form form:

3[>FODVV@BW

The most important Id types are:

3[7DVNBW task Id
3[0VJBW message Id
3[0E[BW mailbox Id
3[0FBW memory class Id
3[2SRROBW object pool Id
3['HOD\BW delay object Id

PXROS has its own definitions for basic types:

PxChar_t PxUChar_t PxShort_t PxUShort_t


PxInt_t PxUInt_t PxLong_t PxULong_t

These definitions are processor-independent and therefore easily ported in C-ode.

Other important data types include:

3[(YHQWVBW data type for event masks


3[(UURUBW enumerated type for error codes
3[6L]HBW data type for size specifications (processor-dependent)
3[$OLJQHGBW objects of this type are always located at addresses
where the processor-dependent alignment should be
considered (e.g. on some processors e.g. all data
types except char must be located at even addresses.)

In general, a data type with a lower case "t" (i.e 3[BW) indicates a "small" data type
(<= 8 bytes), while "large" data types (> 8 bytes) are specifed by the upper case "T"
(3[B7 . For example, PXROS defines a structure called PxTaskSpec_T. A pointer to
this structure is of the type 3[7DVN6SHFBW 3[7DVN6SHFB7 

The prefix 3; indicates a macro, and serves to distinguish the macro from function
calls, which use the prefix 3[. For example, the system memory class can always be
accessed via the macro 3;0F6\VWHPGHIDXOW

HighTec EDV-Systeme GmbH 19 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 7DVNV

Normally a realtime application consists of several largely


independent processes, for example a system control
process, EEPROM programming and communication with
the user. These processes executed sequentially and
independent of one another. The application itself is
comprised of many smaller parts. PXROS supports this
system design using the WDVN concept:

A variety of sequential jobs can run independently as WDVNV


Each task has its own stack and full access to the
processors register. The WDVN FRGH is executed for the most
part independent of the systems other tasks.

Different tasks in an application run in quasi-parallel. The


Task
processor itself is an indivisible resource: i.e. it can only
execute the code of RQH task at a time. With this in mind,
only one task can actually be active at any given moment.
PXROS uses SULRULWLHV to control which task is actually executed. Allocating the tasks
processing time based on their respective priorities is called SUHPWLYH SULRULW\EDVHG
VFKHGXOLQJ:

Each task is always in one of two states: ZDLWLQJ or UHDG\. The tasks that are ready
compete for control over the processor (i.e. to execute their program code). PXROS
activates the task with highest priority. This task retains control until it returns to a wait
state, or until a task with a higher priority becomes ready. Normally tasks are only
active for a relatively short time, as high-priority tasks interrupt lower-priority tasks.
PXROS scheduling mechanism is explained in detail in chapter 13.

A tasks change of state is DOZD\V related to PXROS services. An active task stops and
waits when directed to do so by certain services. For example, a task will switch to a
wait state to wait for a PXROS object to become available, or to wait for a signal that an
event has occurred. The task resumes processing e.g. once the event has been
signalled or the expected object becomes available.This will only happen if another
task or handler calls an applicable PXROS service.

HighTec EDV-Systeme GmbH 20 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 &UHDWLQJ7DVNVZLWKD6WDQGDUG)XQFWLRQ

Tasks are created dynamically and receive an individual task Id from PXROS.

Various parameters can influence the creation of a task, although usually only a few of
these parameters are generally important. If this is the case the function
&UHDWH6WGWDVN can be used. When applied, this function automatically creates a task.

It only requires a few specific parameters, while default values are used to configurate
the remaining parameters.

&UHDWH6WGWDVN is distributed in addition to the standard version of PXROS, and serves


to make task creation much simpler. This function is described in greater detail in
chapter 14. Its prototype is described in the following:

PxError_t CreateStdtask ( PxTask_t *TaskId,


char *name,
void(*TaskFunc) (PxTask_t, PxMbx_t,
PxEvents_t),
PxUInt_t stksize,
PxUChar_t prio )

7DVN,G is the functions output parameter. If the task is created successfully, this
parameter specifies the newly created tasks Id; otherwise, TaskId is .

The parameter QDPH specifies the tasks name. This parameter is employeded by the
debugger when the realtime monitor 3;PRQ is used. name can not be used to specify
the task within an application.

7DVNIXQF is a function that is assigned to the task. This is given as code to be executed
and must fulfill specific requirements, e.g. it has a fixed prototype. Section 3.2
describes this parameter in greater detail.

SULR specifies the tasks priority. The highest possible priority is  and the lowest
depends on the processor and the PXROS variant used (usually  or ). Only the
tasks relative priorities are important for PXROS scheduling; their absolute values are
irrelevant. There are no strict guidelines for assigning task priorities. The following may
serve as a rough guide. Tasks with a small buffer, tasks that perform time-based or
hardware-related duties, and tasks that are used as servers for other tasks should
generally receive relatively high priorities. Tasks that perform hardware independent
duties, e.g. evaluating data for statistics, operating displays or permanent safety checks
(ROM check) usually receive lower priorities.

As previously mentioned, each task has its own stack. The parameter VWNVL]H fixes the
stack size in the size of an LQWHJHU. The stack size depends on the task code: each
function in a nested call increases the tasks demand for stack space. For example,
space in the stack is required for the function prologue. All local variables and (if
necessary) parameters are placed on the stack as well. This can make it difficult to
estimate stack size requirements at the beginning of development.

HighTec EDV-Systeme GmbH 21 20. Mai 1996


PXROS V4 Users Guide Version 1.0

If the task stack is too small, it can lead to run time errors that are difficult to locate. For
example, this may cause arbitrary memory locations to be overwritten. Although
PXROS checks for stack overflow (in the debug library) whenever a PXROS service is
called, this does not ensure that every stack overflow will be detected. With this in
mind, VWNVL]H should be allocated generously if there is sufficient memory available. As
the final development phase is reached, the developer can always optimize these
values.

A tasks maximum stack requirements can be determined with the help of the PXmon,
and VWNVL]H can be modified accordingly.

If &UHDWH6WGWDVN returns the value 3;(55B12(5525, the task was successfully


created. If an error occurs, it is usually due to a lack of memory. Generating a stack
requires memory for the stack and an internal PXROS control structure.

The error code 3;(55B7$6.B7&%0(0 indicates a lack of memory in the respective


internal control structure. In this case, either the amount of memory used must be
reduced, or more memory must be allocated. The error code 3;(55B7$6.B67.0(0
indicates too little memory for the specified stack size. This problem can be solved by
reducing stksize, although there is a risk of making the stack too small.

 7DVN&RGH

The task code is a function with the following prototype:

void TaskFunc (.PxTask_t myid,


Px Mbx_t mymbx,
PxEvents_t myevents )

PXROS starts this function when newly created tasks are activated. The parameters
are set by PXROS and have the following meaning:

P\LG is the task Id generated during task creation. This can be important information in
a message inteded for another task. The service 3[*HW,G shows the Id of the running
task.

Once created, a mailbox is automatically created to serve as the tasks SULYDWH PDLOER[,
i.e. P\PE[. This contains the private mailboxs ,G, where the task usually waits to
receive messages from other tasks. 3[7DVN*HW0E[ shows the Id of a tasks private
mailbox.

HighTec EDV-Systeme GmbH 22 20. Mai 1996


PXROS V4 Users Guide Version 1.0

After its creation, a task is usually UHDG\ to execute its code. If it has a higher priority
than the creating task, the created task immediately becomes active. One might also
specify DFWLYDWLQJ HYHQWV when creating a task. In this case, the task begins in a wait
state and becomes ready as soon as one of these events is signalled. P\HYHQWV
contain events through which the task is started. Tasks that are created by
CreateStdtask do not have activating events, i.e. they always begin in a ready state and
their parameter P\HYHQWV LVVHWWR.

The task code itself has a typical PXROS task design. The task initializes itself and
finds itself in what can be said to be an endless loop. This starts with the task waiting
for messages from other tasks, and/or the signalling of events to it. Once they are
received, the messages and/or events are evaluated and processed. Afterwards, the
task returns to a wait state.

void TaskFunc ( PxTask_t myid,


PxMbx_t mymbx,
PxEvents_t myevents )
{
INITIALIZE_TASK;

for (;;)
{

WAIT_FOR_MESSAGES_AND_EVENTS;

PROCESS_EVENTS;

PROCESS_MESSAGE;

CLEANUP;
}
}

A task (or group of tasks) will generally make up only part of the whole system (e.g. the
hardware involved). This should always be initialized during the respective tasks
initialization phase, for example during a central initialization. In this way, changes are
contained locally to the respective tasks.

TaskFunc may QHYHU be left, meaning it must not reach the closing brace at the end of
the task code. Tasks are not usually terminated; rather, tasks normally remain active to
complete jobs. However, there are ways to terminate tasks (see section 3.4).

The most simple PXROS task (i.e. with no function) has the following form:

void TaskFunc ( PxTask_t myid,


PxMbx_t mymbx,
PxEvents_t myevents)
{
for (;;) ;
}

HighTec EDV-Systeme GmbH 23 20. Mai 1996


PXROS V4 Users Guide Version 1.0

If such a task becomes active, it blocks all tasks with lower or equal priorities. Only
handlers or high priority tasks can become active!

 7DVN&RPPXQLFDWLRQ

A task usually does not exist in isolation within an application. It requires information
from other tasks or handlers, and it often must pass data on to other tasks. Information
is exchanged via the PHVVDJH WUDQVIHU or HYHQW VLJQDOOLQJ. This will be covered in detail
in chapters 5 and 6, which describe the principle working methods used. In addition to
messages and signals, tasks can swap data over shared memory locations; however,
PXROS has no control over this method of communication. Using shared memory
places the responsibility for synchronization and data integrity entirely in the
applications hands.

 'DWD&RPPXQLFDWLRQYLD0HVVDJHV

A task usually ZDLWV for a PHVVDJH at its


private PDLOER[. The task uses a
corresponding PXROS service to receive
the message, e.g. 3[0VJ5HFHLYH. Upon Message Transfer
calling this function, the task goes into a
ZDLW state until a message arrives at the

mailbox. It is then returned to a UHDG\


state and 3[0VJ5HFHLYH returns. The
message is released after it has been Task Task
processed and evaluated by the task.

To VHQG data, a task needs a message. A task can either create it itself, or it can reuse
a message it has already received. Data will be written to the message and the
message can then be sent. Remember, a message is always sent to a mailbox, i.e. it is
never sent directly to a task.

 6LJQDOOLQJ(YHQWV

In addition to shared memory, tasks can


also receive information through signalled Signalling Events
events. This is usually the only way a
handler can transmit data to tasks. It is
very efficient for tasks to signal events to
other tasks instead of sending messages.
Signalling events does not consume
resources. On the other hand, it is less
flexible than sending messages, because
the amount of possible information sent is Task Task
limited.

A task waits for specific events when a corresponding PXROS service is called, for
HighTec EDV-Systeme GmbH 24 20. Mai 1996
PXROS V4 Users Guide Version 1.0

example 3[$ZDLW (YHQWV. This call places the task into a ZDLWLQJ state. Once one of
the expected events has been signalled, the task is made UHDG\ again, the function
returns and the task can evaluate the event.

,PSRUWDQW messages are sent to mailboxes, events are signalled to tasks.

 .LOOLQJ7DVNV

In general, tasks will continue processing forever. If a task must be NLOOHG


, the PXROS
service 3['LH must be used.

,PSRUWDQW When killing a task, the task code must QRW be exited using UHWXUQ.

When a task is killed, it releases all memory and/or PXROS objects it may have used,
such that they are again at the systems disposal. By calling 3['LH, the task is
terminated by the GLH VHUYHU (a special task). Furthermore, the die server releases
system resources that were used while creating the task. In this way, a task can be
killed without the system losing resources.

In order to kill a task, the die server must permanently occupy system resources itself,
i.e. it is implemented as a task. For this reason, using a die server in an application only
makes sense if several tasks must be killed. If only one task is to be killed within the
system, we recommend placing task into a permanent wait state. This can be achieved
by calling the function 3[$ZDLW(YHQWV  (see chapter 6). The system resources for
that task will remain unavailable, but the task is out of operation.

HighTec EDV-Systeme GmbH 25 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 %XLOGLQJWKH6DPSOH3URJUDPV

This chapter describes PXROS individual mechanisms and services. There are sample
programs located throughout the Users Guide. These are quite useful for introducing
various concepts and services, and to demonstrate how they are applied. At the end of
most chapters, the execution of a sample program is described to illustrate various
services. All of the sample programs are structured similarly:

At the beginning of these examples, PXROS is initialized, two tasks are created and,
with the help of a hardware timer, the system clock is installed. The initialization is then
completed and the tasks created become active. The starting phase is the same for all
sample programs. They differ only in their respective task functions, each of which uses
services described in chapter being read. The descriptions in future chapters are
confined to the two tasks created in the relevant sample program, as these tasks
underscore the use of the concepts defined in each chapter. This chapter describes the
starting phase and initial processes performed in the examples.

 3URFHVV

Every PXROS application begins with Task States During Installation


the initialization of PXROS. The
initialization phase is started by the so- active
called LQLWLDOL]DWLRQ WDVN. It is the first PXROS Initialization
and Task Creation
active task in a system, and the only
task that has a prototype that deviates
from the form described in the previous active ready ready
chapter.
Following PXROS initialization, two
Reducing the Priority
more tasks are created in each of the
sample programs. These tasks are
given the Ids Task1 and Task2. They ready active ready
are created in such a way that they are
immediately ready. In other words,
Init Task Task 1 Task 2
neither task uses activating events.

The task priorities in the sample programs are set such that the initialization task has
the highest priority, and Task1 has a higher priority than Task2. As implied, the
initialization task stays active after the other two tasks have been created.

Once the initialization phase is completed, the initialization task automatically lowers its
priority. At this point, Task1 has the highest priority and is in a ready state. This task
runs its code until it passes into a wait state, at which point Task2 becomes active.
Once Task1 is ready again (i.e. its wait condition has been fulfilled), the task is
reactivated and Task2 is interrupted. After lowering its priority, the initialization task is
only run if both Task1 and Task2 are waiting.

HighTec EDV-Systeme GmbH 26 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 ,QLWLDOL]DWLRQ3KDVH

The C-code for the starting phase is the same for all sample programs:

void main ()
{
/*Initialize PXROS and create 2 tasks */
if (BspInit (&Task1Id, &Task2Id))
{
PxPanic ();
}
/* Stack PXROS Time Base */
TicksInit ();

/* Decrease initialization tasks priority */


PxtaskSetPrio (PxGetId(), MINPRIO);

/* Idle Loop */
for (;;) ;
}

In the examples, initialization is performed withhin the function %VS,QLW. The source
code is in EVSLQLWF, which can be found in the directory LQLW on the accompanying disk.
%VS,QLW is described in detail in the section 15.1. This chapter assumes a greater

familiarity and understanding of PXROS terminology, thus we recommend running


through the intermediate chapters before going on to the description of %VS,QLW.

After PXROS has been initialized, two tasks are created in %VS,QLW. Their task codes
are two C-functions called 7DVN)XQF and 7DVN)XQF respectively. Each contains the
functions required by the sample programs. After the tasks have been created, their Ids
are passed by reference as 7DVN,G and 7DVN,G respectively.

If successful, %VS,QLW returns a , otherwise a - is returned. If failure is reported,


PXROS stops the program via a call to the function 3[3DQLF.

Once initialization is completed in %VS,QLW, the system clock is installed with 7LFNV,QLW.
It is reactivated at regular intervals through periodic incrementations from the function
3[7LFN'HILQHB+QG . Operating the system clock requires programming a processor

timer. For this reason, 7LFNV,QLW is dependent on the processor used. The hardware
dependent variants for this function can be found on the accompanying disk in the
directory WLPHGHI. These variants are called WLFNVQDPH!F, where <name> refers to
the respective processor. WLFNVF contains the 7LFNV,QLW program code for a
Siemens C166 processor, WLFNVF is the variant for a C167 and 7LFNV,QLW is written
for an 80386 processor in WLFNVF.

At the end of the starting phase, the initialization task lowers its priority (via a call to
3[7DVN6HW3ULR ) to the value 0,135,2 (i.e. a low priority value). In addition to the new

priority, 3[7DVN6HW3ULR also needs the tasks Id (i.e. the task whose priority is to be
changed). The example illustrates how this Id can be obtained from the service
3[*HW,G.

HighTec EDV-Systeme GmbH 27 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 &RPPXQLFDWLRQWKURXJK0HVVDJHV

 6XPPDU\

In general, the tasks usually communicate


amongst one another by exchanging
PHVVDJHV A message is always made up of a

message object and an exclusive data area.


The data area contains various forms of data,
such as an assignment for a task, or the results
of such an assignment. For example, a task
requests a message, writes to the messages
data area and sends the message to a mailbox.
A second task then withdraws the message
from the mailbox, evaluates the data in the data area, and releases the message again.
A task can avoid repeatedly requesting and releasing messages by reusing a message
after it has been evaluated (i.e. instead of releasing it and requesting a new message).

In using the function 3[0VJ5HTXHVW PVJ VL]H PF RSRRO , the application requests
the message PVJ with a data area of VL]H bytes in size. The memory requested for the
data area is taken from the memory class PF, and the memory used for the message
object originates from the object pool RSRRO. The function 3[0VJ*HW'DWD PVJ
provides the address of the data area associated with the message PVJ thus telling
the calling task where to write its data. The function 3[0VJ6HQG PVJ PE[ sends
the message PVJ to the mailbox PE[

A task waits at the mailbox PE[ with the function 3[0VJ5HFHLYH PVJ PE[ . As soon
as a message arrives, the function returns with the message PVJ 3[0VJ*HW'DWD
allows the task to access and evaluate the messages contents. The task can then
release the message using the 3[0VJ5HOHDVH PVJ service. This returns the memory
used by the message to the appropriate memory class, as well as returning the
messages message object to the object pool from which it originated (i.e. from the call
to 3[0VJ5HTXHVW). As mentioned above, the message can be given new data and
reused.

The process of message exchange is similar to writing letters: one buys an envelope
(request a message object) and paper (requesting memory for data). The letter is given
(PxMsgSend) to the post office (PXROS), which delivers the letter to a mailbox (a tasks
mailbox). Having waited for it to arrive, the user removes the letter from the mailbox
(PxMsgReceive) and reads it. The envelope and paper are then either recycled
(PxMsgRelease) or re-used for a new letter. Fortunately, PXROS uses erasable ink on
its paper! :^)

With this comparison in mind, certain application errors can be avoided: after the letter
has been sent, it is no longer available. If letters are repeatedly produced and not
recycled, resources become scarce. Also, keep in mind that PXROS messages are
always sent to a mailbox and not directly to a task.

HighTec EDV-Systeme GmbH 28 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 *HQHUDWLQJ0HVVDJHV

PxError_t PxMsgRequest ( PxMsg_t *Msg,


PxSize_t size,
PxMc_t mc,
PxOpool_t opool )

PxError_t PxMsgRequest_NoWait ( PxMsg_t *Msg,


PxSize_t size,
PxMc_t mc,
PxOpool_t opool )

PxEvents_t PxMsgRequest_EvWait ( PxMsg_t *Msg,


PxSize_t size,
PxMc_t mc,
PxOpool_t opool,
PxEvents_t events )

The application requests a message with the function 3[0VJ5HTXHVW :

PXROS takes a message object out of


the object pool RSRRO and a memory block 3[0VJ5HTXHVW

with the size VL]H byte out of the memory


class PF. PXROS allocates the memory
block to the message object. When Memory Class
successfully performed, PXROS enters
the message objects Id into 0VJ.
Message
The message is not created if the Opool
memory request cannot be accomplished,
or if the WEOLPLW of the task requesting it is
exhausted (see chapter 14). Both errors
are indicated in their corresponding return values. If RSRRO is empty, the task waits until
an object becomes available again.

In addition to the standard service, PxMsgRequest, there are two other variants
available:

3[0VJ5HTXHVWB1R:DLW and 3[0VJ5HTXHVWB(Y:DLW.

When the object pool is empty, 3[0VJ5HTXHVWB1R:DLW does not wait for an object to
become available. It immediately returns with the error indication
3;(55B2%-B122%-. 3[0VJ5HTXHVWB(Y:DLW , on the other hand, either waits until

an object becomes available in the object pool RSRRO, or until one of the predefined
events in HYHQWV is signalled to a task. If no message object was made available, the
value of 0VJequals in all variants.

HighTec EDV-Systeme GmbH 29 20. Mai 1996


PXROS V4 Users Guide Version 1.0

([DPSOH

PxError_t fun()
{
PxMsg_t msg;
PxError_t err;

err = PxMsgRequest (&msg, 100, PXMcSystemdefault,


PXOpoolSystemdefault);
if (err != PXERR_NOERROR)
{
return (err);
}
}

 :ULWLQJDQG(YDOXDWLQJ0HVVDJH'DWD

YRLG 3[0VJ*HW'DWD 3[0VJBWPVJ

PxMsgGetData gives a task the starting


address of the data area associated
with the message PVJ A handler can PxM s gGetD ata
call the special variant
3[0VJ*HW'DWDB+QG to receive this
address.

The messages arriving in a mailbox can


specify a variety of actions (e.g different
assignments). For this reason,
messages differ from one another in the
structure of their program data. A task
that draws a message from a mailbox
must be able to identify the message type in order to interpret the program data
correctly.

To recognize these differences, all messages arriving at a mailbox require an identifier.


Messages should be structured such that the message head contains all the
information that is needed to interpret the ensuing program data. The message head
can be structured in order to accomodate different contexts.

([DPSOH

typedef struct {
PxUInt_t opcode;
PxUInt_t sender;
....
PxUChar_t *data;
} Request_T;

HighTec EDV-Systeme GmbH 30 20. Mai 1996


PXROS V4 Users Guide Version 1.0

HighTec EDV-Systeme GmbH 31 20. Mai 1996


PXROS V4 Users Guide Version 1.0
SendTask(PxTask_t myid, PxMbx_t mymbx, PxEvents_t myevents)
{
Request_T *req;
PxMsg_t msg;
....
PxMsgRequest (&msg, 100, PXMcSystemdefault,
PXOpoolSystemdefault);
req = (Request_T *) PxMsgGetData(msg);
req->opcode = ...;
req->sender = myid;
....
....
}

ReceiveTask(...)
{
PxMsg_t msg;
Request_T *req;
....
/* Get Message; Id in msg */
req = (Request_T *) PxMsgGetData(msg);
switch(req->opcode)
{
case...:
....
}
}

 6HQGLQJDQG5HFHLYLQJ0HVVDJHV

PxError_t PxMsgSend ( PxMsg_t *Msg,


PxMbx_t mbx )

PxError_t PxMsgSend_Prio ( PxMsg_t *Msg,


PxMbx_t mbx )

PxError_t PxMsgReceive ( PxMsg_t *Msg,


PxMbx_t mbx )

PxError_t PxMsgReceive_NoWait ( PxMsg_t *Msg,


PxMbx_t mbx )

PxEvents_t PxMsgReceive_EvWait ( PxMsg_t *Msg,


PxMbx_t mbx,
PxEvents_t events )

The service 3[0VJ6HQG 0VJPE[ sends the message 0VJ to the mailbox PE[

Messages are stored in a mailbox in the order they arrive. The message that arrived
first is released first. Using 3[0VJ6HQGB3ULR a prioritized message is dealt with first.

HighTec EDV-Systeme GmbH 32 20. Mai 1996


PXROS V4 Users Guide Version 1.0

3[0VJ6HQG can only return an error code when a PDLOER[ KDQGOHU is installed at the
mailbox. The handler is activated before the message enters the mailbox. The handler
can either reject or accept the message. 3[0VJ6HQG returns the mailbox handlers
error code, thus allowing the caller to recognize why the message was refused (see
chapter 9.3).

PxMsgSend PxMsgReceive

Task
Task

Task

Task

Task

A task withdraws a message from the mailbox PE[ using the function 3[0VJ5HFHLYH
0VJ 0E[  If the mailbox is empty, the task waits. Several tasks can wait at the same

mailbox at the same time. Once a message arrives, it is given to the task that has been
waiting the longest, and the remaining tasks a served on a first-come, first-served
basis.

In addition to the standard service, 3[0VJ5HFHLYH, there are two other variants: (1) If
the mailbox is empty, 3[0VJ5HFHLYHB1R:DLW does not wait for the message to arrive.
The error identifier PXERR_MSG_NOMSG is returned immediately. (2)
3[0VJ5HTXHVWB(Y:DLW waits until either a message is received, or one of the events

is signalled to a task from HYHQWV. In either case, 0VJ has the value of , if no
message was taken from the mailbox.

In most applications, a message addresses a specific task. This message is normally


sent to the tasks SULYDWH PDLOER[, as a task is usually waiting there. For messages of
special importance, specific mailboxes can be allocated to senders and receivers.

 5HOHDVLQJ0HVVDJHV

PxError_t PxMsgRelease ( PxMsg_t *msg )

When a task has received and processed a message, it can either reuse or release it
with 3[0VJ5HOHDVH PVJ  When this service is applied, the occupied resources are
returned to the systems disposal once again.

HighTec EDV-Systeme GmbH 33 20. Mai 1996


PXROS V4 Users Guide Version 1.0

([DPSOH

SendTask ()
{
PxMsg_t msg;
....
PxMsgRequest (&msg, 100, PXMcSystemdefault,
PXOpoolSystemdefault);
....
PxMsgSend (&msg, mbx);
....
}

ReceiveTask ( PxTask_t myid,


PxMbx_t mymbx,
PxEvents_t myevents)
{
PxMsg_t msg;
....
PxMsgReceive (&msg, mymbx);
....
PxMsgRelease (&msg);
....
}

3[0VJ5HTXHV 3[0VJ6HQ

Task

Task
3[0VJ5HDOHDV 3[0VJ5HFHLY

When a message is processed, the receiving task often sends a message itself, e.g. to
return requested data. In this case, it would be uneconomical to release the message
with the job request and then create a new message. Instead, the message that is
received should be reused. It is especially conveniant if the space for the requested
data is already provided in the messages data area. After processing, the task need
only enter the requested data in the provided area and return the message to the
original sender.

([DPSOH

HighTec EDV-Systeme GmbH 34 20. Mai 1996


PXROS V4 Users Guide Version 1.0

typedef struct {
PxUInt_t opcode;
PxUInt_t sender;
PxMbx_t answmbx;
PxUInt_t result;
....
PxUChar_t *data;
} Request_T;

SendTask (PxTask_t myid, PxMbx_t mymbx, PxEvents_t myevents)


{
Request_T *data;
PxMsg_t msg;
PxError_t err;
....
....
err = PxMsgRequest (&msg, 100, PXMcSystemdefault,
PXOpoolSystemdefault);
if (err != PXERR_NOERROR
{
return (err);
}

data = (Request_T *) PxMsgGetData (msg);


data->opcode = ...;
data->sender = myid;
data->answmbx = mymbx;
....
PxMsgSend (&msg, mbx);
....
}

ReceiveTask ( PxTask_t myid,


PxMbx_t mymbx,
PxEvents_t myevents)

{
PxMsg_t msg;
Request_T *data;
....
....
PxMsgReceive (&msg, mymbx);
data = (Request_T *) PxMsgGetData (msg);

HighTec EDV-Systeme GmbH 35 20. Mai 1996


PXROS V4 Users Guide Version 1.0
switch(data->opcode)
{
case...:
....
data->result = OK;
PxMsgSend (&msg, data->answmbx);
break;
....
....
}
}

Even if a message must be restructured, it still can be reused. In this case, the data
area must be of sufficient size to accommodate the new data. This can be determined
by with the function 3[*HW%XIIHUVL]H PVJ 

 8VLQJDQ([LVWLQJ'DWD$UHD

PxError_t PxMsgEnvelop ( PxMsg_t *Msg,


void *data,
PxSize_t size,
PxOpool_t opool,
PxUChar_t *Flag )

PxError_t PxMsgEnvelop_NoWait ( PxMsg_t *Msg,


void *data,
PxSize_t size,
PxOpool_t opool,
PxUChar_t *Flag )

PxEvents_t PxMsgEnvelop_EvWait ( PxMsg_t *Msg,


void *data,
PxSize_t size,
PxOpool_t opool,
PxUChar_t *Flag,
PxEvents_t events )

void PxAwaitMsgrel ( PxUChar_t *Flag )

Often the messages program data is "ready to be sent" as the message is requested
with 3[0VJ5HTXHVW. The task cannot simply provide the datas location; it must copy
the data into the messages memory area. Requesting memory and copying the data
increase run time. If the message only receives a data pointer, the process of copying
is avoidable. The two tasks must coordinate the access to the memory area they share.
In this case, requesting messages still requires memory.

HighTec EDV-Systeme GmbH 36 20. Mai 1996


PXROS V4 Users Guide Version 1.0

To avoid these problems, the application can also create messages with
3[0VJ(QYHORS This service requests a message object and allocates it a predefined

memory area; i.e. QR PHPRU\ LV UHTXHVWHG Using the service 3[$ZDLWV0VJUHO, the
sending task can recognize when a message was released, thus allowing it to reaccess
that data area. When a message is released, PXROS only returns the object to the
object pool and the data area remains unchanged.

3[0VJ(QYHORS 0VJ GDWD VL]H RSRRO )ODJ requests a message object from the
object pool RSRRO The message object is allocated a memory area of VL]H bytes at the
address GDWD, and the message 0VJ is created. Memory is QRW requested, it must
already exist. )ODJ is the address of a variable, which PXROS sets to  when a
message is being generated. Once the message is released, Flag is set to . In
addition to the conventional PXROS mechanisms, a service is available that allows a
task to wait for a messages release: 3[$ZDLW0VJUHO IODJ returns as soon as PXROS
sets )ODJ to  (i.e. when the requested message is released). Until then, the task
remains in a ZDLW VWDWH, and other tasks can become active. After a message is
released, the receiver of this message no longer has access to data; otherwise,
inconsistencies might occur. 3[$ZDLW0VJUHO returns, thus indicating that the data
access had been completed.

The services 3[0VJ(QYHORS and 3[$ZDLW0VJUHO can also be used to synchronize


communication between two tasks. This is convenient when for example, Task1 needs
information from Task2 in order to continue operating.

([DPSOH

typedef struct {
PxUInt_t opcode;
PxUInt_t sender;
PxUInt_t result;
....
PxUChar_t *data;
} Request_T;

Task1Func()
{
PxUChar_t flag;
Request_T req;
PxMsg_t msg;
....
req.opcode = ....
req.sender = myid;
....
PxMsgEnvelop (&msg, (void *) &req, sizeof(Request_T),
PXOpoolSystemdefault, &flag);
PxMsgSend (&msg, mbx);
....
PxAwaitMsgrel (&flag)
if (req->result == OK)
{
....
}

HighTec EDV-Systeme GmbH 37 20. Mai 1996


PXROS V4 Users Guide Version 1.0
else
{
....
}
....
}

Task2Func(PxTask_t myid, PxMbx_t mymbx, PxEvents_t myevents)


{
PxMsg_t msg;
Request_T *req;
....
PxMsgReceive (&msg, mymbx);
req = (Request_T *) PxMsgGetData (msg);
...
if (...)
{
req->result = OK;
}
else
{
req->result = FALSE;
}
PxMsgRelease (&msg);
....
}

 0HVVDJH3RROV

When a message is created, PXROS may have to wait for an object to become
available. Also, using 3[0VJ5HTXHVW to create a message requires memory, which is
not always available. Even when the request can be fulfilled, it may require time to
create the message. In some cases, the delays caused are not acceptable. These
problems can be avoided by creating messages in advance. In this way, if a message
is needed, it is immedialtely accessible (i.e. as long as not all of the messages are
being used). These "ready-made" messages are kept in a so called PHVVDJHSRRO:

Using 3[0VJ5HTXHVW, messages are


created during initialization. These messages
are kept in a mailbox is created specifically
for this purpose and referred to as the
PHVVDJH SRRO (creating a mailbox with
3[0E[5HTXHVW is described in detail in PxMsgReceive PxMsgRelease
chapter 9). During initialization, the amount
of time taken to create message is irrelevant.
When a task uses a prepared message, it
takes the message from the message pool PxMsgSend
using the 3[0VJ5HFHLYH service. This is
quicker than creating new message as Ta s k Task
needed. One potential disadvantage with this
method however, is that individual messages
HighTec EDV-Systeme GmbH 38 20. Mai 1996
PXROS V4 Users Guide Version 1.0

can not be distinguished from other messages when taken from a mailbox.

When a message is no longer needed, it is usually released, the object returns to its
object pool, and the memory returns to its memory class. Message that originate from
message pools may not be deleted; they must return to the message pool after being
used. This ensures that the message pool is not emptied after a short time. This
precaution implies that the PXROS application must somehow distinguish between
messages. Within an application, messages can be differentiated as follows:

....
if ( ... ) /* message from message pool */
PxMsgSend (&msg, MsgPool);
else
PxMsgRelease (&msg);
....

This distinction is not really sufficient! For this reason, 3[,QVWDOO5HOPE[ PVJ PE[ is
applied. It defines the mailbox PE[ as the UHOHDVH PDLOER[ responsible for the message
PVJ,. This means that when 3[0VJ5HOHDVH PVJ is called, the message is not

relased; rather, it is sent back to the mailbox PE[. For messages from a message pool,
the pool should always be defined as the release mailbox. Now every message can be
released with 3[0VJ5HOHDVH, while PXROS ensures, when applicable, that the
message can return to the message pool.

If a release mailbox is already defined for a message, 3[,QVWDOO5HO0E[ fails. When the
parameterPE[ has the value  the installation of a release mailbox is cancelled.

([DPSOH

PxMbx_t MsgPool;

Task1Func()
{
PxMsg_t msg;
....
PxMbxRequest (&MsgPool, ...);
....
for (i=1; i<=MSG_NO; i++)
{
PxMsgRequest (&msg, MSG_SIZE, ...);
PxMsgInstallRelmbx (msg, MsgPool);
PxMsgRelease (&msg);
/* PxMsgSend (&msg, MsgPool) is also possible */
}
....
}

Task2Func()

{
PxMsg_t msg;
....

HighTec EDV-Systeme GmbH 39 20. Mai 1996


PXROS V4 Users Guide Version 1.0
PxMsgReceive (&msg, MsgPool);
data = PxMsgGetData(msg);
/* provided with data */

....
PxMsgSend (&msg, PxGetMbx(Task3Id));
....
}

Task3Func(PxTask_t myid, PxMbx_t mymbx, PxEvents_t myevents)

{
PxMsg_t msg;
....
PxMsgReceive (&msg, mymbx);
....
PxMsgRelease(&msg);
....
}

 ([DPSOHV

The source code for the following "data communications" sample programs can be
found in the directory FRPP on the accompanying disk.

 H[F

Task1 and Task2 send each other a message that was originally generated by Task1.
Each task increments the value of a counter which is located within the messages data
area. When the counter reaches the value 100 the task that is momentarily in
possession of this message, releases it and subsequently, both tasks go into a state of
waiting.

Typedef struct {
PxMbx_t AnswerMbx;
PxUInt_t Counter;
} Request_T;

HighTec EDV-Systeme GmbH 40 20. Mai 1996


PXROS V4 Users Guide Version 1.0
7DVN)XQF

PxMsg_t msg;
PxMbx_t mbx;
Request_t *data;

(1) PxMsgRequest (&msg, sizeof(Request_T),


PXMcSystemdefault,
PXOpoolSystemdefault);
(2) data = (Request_T *) PxMsgGetData(msg);
(3) data->AnswerMbx = mymbx;
(4) data->Counter = 0;

(5) PxMsgSend (&msg, PxTaskGetMbx(Task2Id));

for (;;)
{
(6) PxMsgReceive (&msg, mymbx);

(7) data = (Request_T *) PxMsgGetData(msg);

(8) if (data->Counter > 100)


{
(9) PxMsgRelease (&msg);
}
else
{
(10) mbx = data->AnswerMbx;
(11) data->AnswerMbx = mymbx;
(12) data->Counter++;
(13) PxMsgSend (&msg, mbx);
}
}

7DVN)XQF

PxMsg_t msg;
PxMbx_t mbx;
Request_T *data;

for (;;)
{
(14) PxMsgReceive (&msg, mymbx);
(15) data = (Request_T *) PxMsgGetData(msg);
(16) if (data->Counter > 100)
{
(17) PxMsgRelease (&msg);
}

HighTec EDV-Systeme GmbH 41 20. Mai 1996


PXROS V4 Users Guide Version 1.0
else
{
(18) mbx = data->AnswerMbx;
(19) data->AnswerMbx = mymbx;
(20) data->Counter++;
(21) PxMsgSend (&msg, mbx);
}
}

GHWDLOHGSURFHVVGHVFULSWLRQ

Task1 generates a message PVJ with the call to 3[0VJ5HTXHVW:

(1) PxMsgRequest (&msg, sizeof(Request_T),


PXMcSystemdefault,
PXOpoolSystemdefault);

This contains a data area with the size of the message structure 5HTXHVWB7. The
resources for the messages are received from the system pool and the system memory
class.

(2) data = (Request_T *) PxMsgGetData(msg);

GDWD is assigned the address of the messages data area. Now the message can be
provided with its contents:

(3) data->AnswerMbx = mymbx;


(4) data->Counter = 0;

The counter is initialized and Task1s private mailbox is specified in $QVZHU0E[ This
attribute represents the mailbox that is intended to receive the answer to the message.

(5) PxMsgSend (&msg, PxTaskGetMbx(Task2Id));

sends the message to Task2s private mailbox. Task1 then waits to receive a message
at its private mailbox.

(6) PxMsgReceive (&msg, mymbx);

Task2 draws the message previously sent by Task1 from its private mailbox

(14) PxMsgReceive (&msg, mymbx);

The address is written to GDWD to evaluate the message

(15) data = (Request_T *) PxMsgGetData(msg);

and the counter checked.

(16) if (data->Counter > 100){

If the counter exceeds the value  , the message is released.


HighTec EDV-Systeme GmbH 42 20. Mai 1996
PXROS V4 Users Guide Version 1.0

(17) PxMsgRelease (&msg);

Then both Task2 and Task1 wait for a message, and remain in this state.

(6), (14) PxMsgReceive (&msg, mymbx);

If the counter does not exceed the value 100, Task2 uses PE[ (18) to save the mailbox
(i.e. where the answer is to be received). It specifies its private mailbox as the answer
mailbox (19). Also, the counter is incremented (20) and the message is sent to the
answer mailbox.

(21) PxMsgSend (&msg, mbx);

Task1 leaves the wait state and evaluates the message that it receives from Task2.
Task1 proceeds in the same way as Task2 did.

 H[F

Task1 generates a message with PxMsgEnvelop, sends it to Task2 and waits for its
release through PxAwaitMsgrel. Task2 receives the message, changes the data, and
releases the message. In this way Task1 regains access to the data.

7DVN)XQF

PxMsg_t msg;
PxUInt_t result = 0;
PxUChar_t flag;
PxMbx_t mbx;

mbx = PxTaskGetMbx (Task2Id);


for (;;)
{
(1) if (result > 100)
{
(2) flag = 0;
}
else
{
(3) PxMsgEnvelop (&msg, (void *) &result,
sizeof(PxUInt_t),
PXOpoolSystemdefault,
&flag);
(4) PxMsgSend (&msg, mbx);
}
(5) PxAwaitMsgrel (&flag);
}

7DVN)XQF

HighTec EDV-Systeme GmbH 43 20. Mai 1996


PXROS V4 Users Guide Version 1.0

PxMsg_t msg;
PxUInt_t *data;

for(;;)
{
(6) PxMsgReceive (&msg, mymbx);
(7) data = (PxUInt_t *) PxMsgGetData(msg);
(8) (*data)++;
(9) PxMsgRelease (&msg);
}

GHWDLOHGSURFHVVGHVFULSWLRQ

Task1 checks if UHVXOW is bigger than 100. UHVXOW was initialized with , thus the task
creates the message.

(3) PxMsgEnvelop (&msg, (void *) &result,


sizeof(PxUInt_t),
PXOpoolSystemdefault, &flag);

The variable UHVXOW is this messages data area. PXROS acknowledges the messages
release when it sets IODJ to  After sending the message to Task2 (4), Task1 waits for
the message to be released with the call

(5) PxAwaitMsgrel (&flag);

Task2 receives the message with the call

(6) PxMsgReceive (&msg, mymbx);

and has access to the data (7). The data contains the variable UHVXOW for Task1. Task2
increments this variable (8) and releases the message (9).

This enables Task1 to become active again. Once active, Task1 checks the value of
UHVXOW. If it is smaller than 100, Task1 requests another message and sends it to Task2

(4). Task1 then waits for the message to be returned (5). Task2 receives the message
and increments UHVXOW again. If UHVXOW is larger than 100, Task1 sets IODJ to 0 (2). The
following call

(5) PxAwaitMsgrel (&flag);

does not return, because IODJ is no longer changed.

HighTec EDV-Systeme GmbH 44 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 H[F

This example demonstrates the use of a message head to differentiation between


messages. The two message types used have an identical message head, but are
different in the structure of their program data. Task1 sends the two message types
alternately to Task2, which recognizes the message type by its head, and can evaluate
the messages accordingly.

typedef struct {
PxInt_t Opcode;
PxMbx_t AnswMbx;
PxInt_t Result;
} MsgHead_T;

typedef struct {
MsgHead_T Head;
PxUInt_t Data[4];
} MsgType1_T;

typedef struct {
MsgHead_T Head;
PxULong_t Data;
} MsgType2_T;

7DVN)XQF

PxMsg_t msg;
PxMbx_t mbx;
MsgType1_T *data1;
MsgType2_T *data2;
PxInt_t Count = 0;

mbx = PxTaskGetMbx (Task2Id);

for (;;)
{
(1) if (Count & 1)
{
(2) PxMsgRequest ( &msg, sizeof(MsgType1_T),
PXMcSystemdefault,
PXOpoolSystemdefault);
(3) data1=(MsgType1_T *) PxMsgGetData (msg);
(4) data1->Head.Opcode = 1;
(5) data1->Head.AnswerMbx = mymbx;
(6) data1->Data[0] = 0;
(7) data1->Data[3] = 1;
}

HighTec EDV-Systeme GmbH 45 20. Mai 1996


PXROS V4 Users Guide Version 1.0
else
{
(8) PxMsgRequest (&msg, sizeof(MsgType2_T),
PXMcSystemdefault,
PXOpoolSystemdefault);
(9) data2=(MsgType2_T *) PxMsgGetData (msg);
(10) data2->Head.Opcode = 2;
(11) data2->Head.AnswerMbx = mymbx;
(12) data2->Data = 0x11223344;
}
(13) Count++;
(14) PxMsgSend (&msg, mbx);
(15) PxMsgReceive (&msg, mymbx);
(16) PxMsgRelease (&msg);
}

7DVN)XQF

PxMsg_t msg;
MsgHead_T *head;
MsgType1_T *data1;
MsgType2_T *data2;
PxInt_t result;

for (;;)
{
(17) PxMsgReceive (&msg, mymbx);
(18) head = (MsgHead_T *) PxMsgGetData (msg);

(19) switch (head->Opcode)


{
case 1: data1 = (MsgType1_T *) head;
data1->Data[1] = 99;
result = 0;
break;
case 2: data2 = (MsgType2_T *) head;
data2->Data = 0;
result = 0;
break;
default: result = -1;
}
(20) head->Result = result;
(21) PxMsgSend (&msg, head->AnswMbx);
}

HighTec EDV-Systeme GmbH 46 20. Mai 1996


PXROS V4 Users Guide Version 1.0

GHWDLOHGSURFHVVGHVFULSWLRQ

Depending on the value of the counter &RXQW, Task1 generates a message with a data
area of large enough for either 0VJ7\SHB7 or 0VJ7\SHB7

(2) PxMsgRequest (&msg, sizeof(MsgType1_T),


PXMcSystemdefault,
PXOpoolSystemdefault);
or
(8) PxMsgRequest (&msg, sizeof(MsgType2_T),
PXMcSystemdefault,
PXOpoolSystemdefault);

The message head is given an "assignment" code ((4) or (10)), and the tasks private
mailbox is specified as the answer mailbox ((5) or (11)). The program data differs in
structure and content, and therefore must be set for the specific assignment ((6) and
(7) or (12)).

The completed message is sent to Task2s private mailbox:

(14) PxMsgSend (&msg, mbx);

It expects an answer and thus calls:

(15) PxMsgReceive (&msg, mymbx);

The message is received by Task2

(17) PxMsgReceive (&msg, mymbx);

which has to evaluate it. It processes the message based on its message type. In order
to identify the type, only the message head is examined. All messages arriving have an
identically structured message head, and are therefore easily interpreted:

(18) head = (MsgHead_T *) PxMsgGetData (msg);

The information in the message head allows the task to identify the message and
process it accordingly:

(19) switch (head->Opcode){

After processing, the result is entered

(20) head->Result = result;

and the message is returned:

(21) PxMsgSend (&msg, head->AnswMbx);

HighTec EDV-Systeme GmbH 47 20. Mai 1996


PXROS V4 Users Guide Version 1.0

Task1 receives the message

(15) PxMsgReceive (&msg, mymbx);

and can now reevaluate it. Because the task in this example fulfills no specific function,
it releases the message immediately.

(16) PxMsgRelease (&msg);

The use of identically structured message heads helps distinguish between different
message types. If the message head is kept non-specific (i.e. contains no application-
specific entries), the task can easily be used in a variety of different applications. When
a task is reused in a new application, only the application specific changes need to be
added to the new function.

 H[F

This example demonstrates the use of a PHVVDJH SRRO: Task1 sends messages with
data areas of a similar size. It creates a message large enough for all message types,
and puts it in a message pool. When needed, Task1 takes a message from the pool,
writes data to it, and sends it to Task2. Task2 processes the message and releases it.
At this time, the message is returned to the message pool it originated from, and from
which it is again requested by Task1. Normally message pools are filled with several
messages and not only with one; this example was kept deliberately simple to facilltate
understanding of the basic mechanism:

typedef struct {
PxInt_t Opcode;
PxMbx_t AnswMbx;
PxInt_t Result;
} MsgHead_T;

typedef struct {
MsgHead_T Head;
PxUInt_t Data[4];
} MsgType1_T;

typedef struct {
MsgHead_T Head;
PxULong_t Data;
} MsgType2_T;

HighTec EDV-Systeme GmbH 48 20. Mai 1996


PXROS V4 Users Guide Version 1.0
7DVN)XQF

PxMbx_t MsgPool;
PxMsg_t msg;
PxMbx_t mbx;
MsgType1_T *data1;
MsgType2_T *data2;
PxInt_t Count = 0;

(1) PxMbxRequest (&MsgPool, PXOpoolSystemdefault);


(2) PxMsgRequest (&msg, sizeof(MsgType1_T),
PXMcSystemdefault,
PXOpoolSystemdefault);
(3) PxMsgInstallRelmbx (msg, MsgPool);
(4) PxMsgRelease (&msg);

mbx = PxTaskGetMbx (Task2Id);

for (;;)
{
(5) PxMsgReceive (&msg, MsgPool);
if (Count & 1)
{
data1=(MsgType1_T *) PxMsgGetData (msg);
data1->Head.Opcode = 1;
data1->Head.AnswerMbx = mymbx;
data1->Data[0] = Count;
}

else
{
data2 = (MsgType2_T *) PxMsgGetData
(msg);
data2->Head.Opcode = 2;
data2->Head.AnswerMbx = mymbx;
data2->Data = ((PxULong_t) Count) << 8;
}
Count++;
(6) PxMsgSend (&msg, mbx);
}

7DVN)XQF

PxMsg_t msg;
MsgHead_T *head;
MsgType1_T *data1;
MsgType2_T *data2;
PxULong_t value;

for (;;)
{

HighTec EDV-Systeme GmbH 49 20. Mai 1996


PXROS V4 Users Guide Version 1.0
(7) PxMsgReceive (&msg, mymbx);
head = (MsgHead_T *) PxMsgGetData (msg);
switch (head->Opcode)
{
case 1: data1 = (MsgType1_T *)
head;
value = data1->Data[0];
break;
case 2: data2 = (MsgType2_T *) head;
value = data2->Data;
break;
}
(8) PxMsgRelease (&msg);
}

GHWDLOHGSURFHVVGHVFULSWLRQ

To install a message pool, both a mailbox, 0VJ3RRO (see also chapter 9), and a
message must be created:

(1) PxMbxRequest (&MsgPool, PXOpoolSystemdefault);


(2) PxMsgRequest (&msg, sizeof(MsgType1_T),
PXMcSystemdefault,
PXOpoolSystemdefault);

0VJ3RRO is defined as the release mailbox for the message PVJ

(3) PxMsgInstallRelmbx (msg, MsgPool);

The call

(4) PxMsgRelease (&msg);

releases the message generated, which then returns to the message pool. This
concludes the preparations required to use the message pool.

Task1 draws a message from the message pool,

(5) PxMsgReceive (&msg, MsgPool);

writes to the data area and sends the message to Task2s private mailbox (6).
Afterwards, Task1 tries again to draw a message from the pool (5). Since 0VJ3RRO only
contained one message, it is now empty, thus Task1 has to wait. Consequently, Task2
becomes active and draws the message from its own mailbox.

(7) PxMsgReceive (&msg, mymbx);

After processing it, Task2 releases the message, (8) which is then returned to the
message pool. At this point, Task1s request can now be fulfilled. Task1 now sends the
new message to Task2...

HighTec EDV-Systeme GmbH 50 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 (YHQWV

 6XPPDU\

Tasks and handlers signal HYHQWV to transmit information.


This mechanism informs a task that an important event
has occurrence of, e.g. the end of a timeout or the
occurrence of an error. Events cannot be signalled to
handlers

Signalling of events is the standard way handlers


communicate with tasks, since handlers cannot generally
send messages. Tasks are also able to signal events to
other tasks, as well as sending messages. This
mechanism is commonly used when extensive data need not be transmitted, but e.g.
only a change of status is to be communicated. The signalling of events does not
consume resources.

The application is free to assign the "meaning" of events. 32 different events can be
signalled to tasks,

numbered from 0 to 31 consecutively. The event with the number L is
assigned the L bit in a 32 bit mask. Thus, the macro

#define EVENT(x) ((PxEvents_t) 1 << (x))

defines the event [ (0 <= x <= 31). Events can be pooled in HYHQW PDVNV. A single
event can be considered an event mask that contains RQO\ RQH event. The 25operator
"_" unites event masks with a "logical or" operation. Similarly, the $1'operator " "
combines event masks with a "logical and" operation.

([DPSOH

events = (EVENT(1) | EVENT(2) | EVENT(3))

This line assigns HYHQWV the event mask formed by the events , , and . With

events = ev1 & ev2

Here HYHQWV is assigned the events contained in both HY and HY. One can check for
the presence of (9(17  in the event mask HYHQWV as follows:

if ( events & EVENT(1) )

When 3[$ZDLWV(YHQWV HYHQWV is used, the calling task waits for events from the
event mask HYHQWV. As soon as one of these events is signalled to it, the task becomes
ready again, and 3[$ZDLW(YHQWV returns. The return value contains the events from
HYHQWV, which were signalled to the task. The task then evaluates these events.

HighTec EDV-Systeme GmbH 51 20. Mai 1996


PXROS V4 Users Guide Version 1.0

A task signals events with the function 3[7DVN6LJQDO(YHQWV. Handlers must use the
special version of this call: 3[7DVN6LJQDO(YHQWVB+QG. Both functions contain
parameters for the event pool and the other the Id of the task they are signalled to.

Some PXROS services can wait simultaneousely for both PXROS objects and/or for
events to be signalled. One should keep in mind that both possibilities can conceivably
occur at the same time!

 6LJQDOOLQJ(YHQWV

void PxTaskSignalEvents ( PxTask_t task,


PxEvents_t events )

PxTaskSignalEvents (task, events) signals the events HYHQWV to the task WDVN If WDVN
has been waiting for one of these events, it switches to a ready state and becomes
active, provided any higher priority tasks are not active.

Only tasks can call 3[7DVN6LJQDO(YHQWV. Similarly, handlers must use the special
service 3[7DVN6LJQDO(YHQWVB+QG This function has the same parameters as the task
service, but has been specially optimized for use on handler level.

 :DLWLQJIRU(YHQWV

PxEvents_t PxAwaitEvents ( PxEvents_t events )

For a task, events are QRW considered as KDYLQJ RFFXUUHG, as long as they have not
been signalled to the task. Using the call PxAwaitEvents (events) a task waits for
events from the event pool. The function returns as soon as DW OHDVW RQH of these
events is signalled to the task, or DW OHDVW RQH of these events is about to occur at the
time of the call. The task does not wait until DOO events from events have been signalled.

$UULYLQJ(YHQWV

Events: 1, 5, 9

PxTaskSignalEvents ( EVENT(0) | (EVENT(3) )

Events: 0, 1, 3, 5, 9

PxAwaitEvents ( EVENT(0) | EVENT (1) | EVENT (9) )

Events: 3, 5

HighTec EDV-Systeme GmbH 52 20. Mai 1996


PXROS V4 Users Guide Version 1.0

The return value of 3[$ZDLW(YHQWV holds the events signalled to the task contained in
the mask HYHQWV. These are removed from the list of events in the event mask that a
task was waiting for. Afterwards, these are seen as not having occurred. When the
return value is examined, one should remember that several events may have been
registered; therefore, one should check for the occurrence of any possible events.
Evaluating these events is explained in the application examples.

3[$ZDLW(YHQWV never returns a . This would mean that the function returned although

no event was signalled to the task. 3[$ZDLW(YHQW waits until at least one of the events
in HYHQWVhas been signalled.

([DPSOH

ev = PxAwaitEvents ( EVENT(0) | EVENT(1) );

if (ev & (EVENT(0) )


{
...
}
if (ev & (EVENT(1) )
{
...
}

When using 3[$ZDLW(YHQWV, the developer should keep in mind that at least one of
the events from HYHQWV must be signalled to the task during the run of the program;
otherwise, the task is in a dead end (i.e. it will not become active again). This is
especially important when calling 3[$ZDLW(YHQWV  

In addition to those services which wait for both events and PXROS objects,
3[$ZDLW(YHQWV is usually used to wait for events.

 5HVHWWLQJ(YHQWV

PxEvents_t PxResetEvents ( PxEvents_t events )

Like 3[$ZDLW(YHQWV, 3[5HVHW(YHQWV HYHQWV cancels events from the event mask.
In contrast however, 3[5HVHW(YHQWV does not wait for one of the events from HYHQWV to
arrive. In other words, this function does not change the tasks state; rather, it returns
immediately. The return value contains the mask of events from HYHQWV that were
actually present at the time of the function call. Furthermore, the return value of
3[5HVHW(YHQWV can be . One must keep in mind that an event can conceivably be

signalled directly after the function returns. This means that the event is queued once
again, even though it was previously deleted with 3[5HVHW(YHQWV.

HighTec EDV-Systeme GmbH 53 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 2WKHU)XQFWLRQV

 3DUDOOHO:DLWLQJ

Several PXROS services wait simultaneously for an object to become available, and for
specific events to be signalled (e.g. 3[0VJ5HFHLYHB(Y:DLW). These services are
recognized by the extension B(Y:DLW. They either return as soon as the expected
object is available, or once one of the events from the event mask has been signalled.

These services are typically applied for placing a time limit on how long the task waits
for an object to become available. To do this, a WLPHRXW is started, which signals an
event to the task after a certain time has passed. After starting the timeout, the task
waits for either the requested object, or for the event to arrive. Once the set time limit
has expired, if the expected object has not become available, the task stops waiting.
Other events can also be used to interrupt a waiting task (i.e. not only timeouts). When
this type of service returns because it received the requested object, the return value is
; otherwise, the signalled events are contained in the return value.

,PSRUWDQW Keep in mind that both possibilities can occur simultaneously! For example,
if a message arrives after the task has called 3[0VJ5HFHLYHB(Y:DLW, the task is in a
ready state; however, if it is blocked by a higher priority task until after the timeout has
expired, the return value will not be 0 even though the message arrived.

([DPSOH

TIMEOUT_START (EVENT(1));

ev = PxMsgReceive_EvWait (&msg, mbx, EVENT(1));


if (msg)
{ /* message arrived */
TIMEOUT_STOP;
...
}
if (ev)
{ /* Timeout finished */
...
}

 $ERUWLQJ)XQFWLRQVZLWK(YHQWV

With the service 3[([SHFW$ERUW, PXROS application can call any function, such that it
will be aborted when specific events occur. This mechanism is used when e.g. a task
activity must be aborted by an "emergency off switch". In this example, the interrupt
handler that reacts to the off switch signals an abort signal to the relevant task, thereby
aborting it immediately.

The use of 3[([SHFW$ERUW is described in detail in chapter 17

HighTec EDV-Systeme GmbH 54 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 ([DPSOHV

The source code for the following "events" examples can be found in the directory
HYHQWV on the floppy disk.

 H[F

Task1 and Task2 wait for different events. When these events arrive and are
evaluated, the receiving task signals its own events to the other task.

7DVN)XQF

for (;;)
{
(1) ev = PxAwaitEvents (EV_1 | EV_2);
(2) if (ev & EV_1)
{
(3) PxTaskSignalEvents (Task2Id, EV_1);
}
(4) if (ev & EV_2)
{
(5) PxTaskSignalEvents (Task2Id, EV_2);
}
}

7DVN)XQF

(6) PxTaskSignalEvents (Task1Id, EV_1 | EV_3);

for (;;)
{
(7) ev = PxAwaitEvents (EV_1 | EV_3);

(8) if (ev & EV_3)


{
(9) PxTaskSignalEvents (Task1Id, EV_3);
}
(10) if (ev & EV_1)
{
(11) PxTaskSignalEvents (Task1Id, EV_1 |
EV_3);
}
}

HighTec EDV-Systeme GmbH 55 20. Mai 1996


PXROS V4 Users Guide Version 1.0

GHWDLOHGSURFHVVGHVFULSWLRQ

Task1 starts first and waits

(1) PxAwaitEvents (EV_1 | EV_2)

for either EV_1 RU EV_2 to be signalled. At this time, no events have been signalled,
thus Task2 becomes active and sends EV_1 DQG EV_3 to Task1, using

(6) PxTaskSignalEvents (Task1Id, EV_1 | EV_3)

One of these events, EV_1, is contained in Task1s event mask. For this reason, Task1
becomes ready and interrupts Task2. 3[$ZDLWV(YHQWVs return value contains the
events in event mask that were actually signalled to the task. In this case, only EV_1
was sent. This event is UHVHW (i.e. EV_1 is again considered not to have occurred).
EV_3 is still present.

Since Task1 waited for both EV_1 or EV_2 and 3[$ZDLW(YHQWV returned with only RQH
of the signalled events, the return value can only contain RQH or ERWK of the events. To
find out which, the task must evaluate the result as follows:

(2) if (ev & EV_1)


and
(4) if (ev & EV_2)

The first test (2) is positive, therefore Task1 sends EV_1 to Task2:

(3) PxTaskSignalEvents (Task2Id, EV_1)

This event is now waiting at Task2. The second test (4) failed, therefore the conditional
action of the LI statement is ignored. Now Task1 waits again

(1) PxAwaitEvents (EV_1 | EV_2)

for EV_1 and EV_2. EV_3, which Task2 signalled, is still present, but is not contained
in the call parameter and is therefore ignored.

Task2 is reactivated and continues from where it was interrupted. It calls

(7) PxAwaitEvents (EV_1 | EV_3)

and waits for one of the events EV_1 or EV_3. At this time, EV_1 is has arrived and
EV_3 has not. 3[$ZDLW(YHQWV returns with EV_1, and EV_1 is reset in the event
mask.

As the return value is evaluated, the first test (8) fails, while the second test (10) is
successful. As specified in this second conditional statement, Task2 sends EV_1 and
EV_3 to Task1 with

(11) PxTaskSignalEvents (Task1Id, EV_1 | EV_3).

HighTec EDV-Systeme GmbH 56 20. Mai 1996


PXROS V4 Users Guide Version 1.0

The program continues in this manner, repeating the step described above.

 H[F

This example shows the case where an event is signalled to a task again before the
task was able to evaluate it.

7DVN)XQF

for (;;)
{
(1) ev = PxAwaitEvents (EV_1 | EV_2);

(2) if (ev & EV_1)


{
(3) PxTaskSignalEvents (Task2Id, EV_1 |
EV_3);
}
(4) if (ev & EV_2)
{
(5) PxTaskSignalEvents (Task2Id, EV_2 |
EV_3);
}
}

7DVN)XQF

for (;;)
{
(6) PxTaskSignalEvents (Task1Id, EV_1 | EV_2);
(7) ev = PxAwaitEvents (EV_3);
(8) ev = PxResetEvents (EV_1 | EV_2 | EV_3);
}

GHWDLOHGSURFHVVGHVFULSWLRQ

Task1 starts first and waits

(1) PxAwaitEvents (EV_1 | EV_2)

for EV_1 or EV_2 to be signalled. At this moment, no events have been signalled to
Task1. Task2 becomes active and sends EV_1 and EV_2 to Task1.

(6) PxTaskSignalEvents (Task1Id, EV_1 | EV_2)

HighTec EDV-Systeme GmbH 57 20. Mai 1996


PXROS V4 Users Guide Version 1.0

Task1 again becomes active, EV_1 and EV_2 are reset, and 3[$ZDLW(YHQWV returns.
The return value is evaluated using the conditional statements

(2) if (ev & EV_1)


or
(4) if (ev & EV_2)

HYhas the value EV_1 | EV_2. Both conditionals test positive, therefore, Task1 signals
EV_1, EV_2 and EV_3 to Task2:

(3) PxTaskSignalEvents (Task2Id, EV_1 | EV_3)


and
(5) PxTaskSignalEvents (Task2Id, EV_2 | EV_3)

In this case, EV_3 is signalled WZLFH. These events are present at Task2. Having
signalled these events to Task2, Task1 again waits

(1) PxAwaitEvents (EV_1 | EV_2)

for EV_1 and EV_2.

Task2 becomes active and continues from where it was interrupted. It calls

(7) ev = PxAwaitEvents (EV_3)

and waits for EV_3. Because Task1 already signalled these events, EV_1, EV_2 and
EV_3 are already present. 3[$ZDLW(YHQWV returns immediately. Since Task2 only
waited for EV_3, the return value HY can only contain EV_3. EV_3 is reset in Task2.

The call

(8) ev = PxResetEvents (EV_1 | EV_2 | EV_3)

indicates which of the three events EV_1, EV_2 or EV_3 is still queued at Task2. The
return value is EV_1 | EV_2. Because it was reset, EV_3 is QRW included in the return
value even though it was signalled WZLFH and "picked up" only RQFH.

The program now continues in the same manner as described above.

This example shows that a task must process signalled events in a timly manner if it is
to react to HYHU\ signal. If an event is signalled again before it is processed by a task,
the task can not determine whether the event was already signalled.

HighTec EDV-Systeme GmbH 58 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 0HPRU\0DQDJHPHQW

 6XPPDU\

PXROS manages the applications dynamically allocateable


memory. To do so, PXROS can divide memory into different
PHPRU\ FODVVHV . This is useful for e.g. protecting critical

application components, or for shortening the time required to


request and release memory blocks. For example, all memory
requests for the application can be taken from another
memory class as system function requests.

When 3[0F7DNH%ON PF EON VL]H is called, PXROS takes a memory block of the
size VL]H byte from the memory class PF and makes it available to the application. EON
contains the memory blocks starting address. After being used, the memory block is
returnedto the memory class PFwith the call 3[0F5HWXUQ%ON PFEON 

 0HPRU\5HTXHVWV

PxError_t PxMcTakeBlk ( PxMc_t mc,


PxAligned_t **Blk,
PxSize_t size )

void PxMcReturnBlk ( PxMc_t mc,


PxAligned_t **Blk )

Using 3[0F7DNH%ON, a PXROS task can dynamically request memory from the
memory class PF. If it contains a block of sufficient size, PXROS delivers the memory
areas starting address; otherwise the function reports an error through the return value
PXERR_MC_NOMEM. When memory is no longer required, it can be returned with a
call to 3[0F5HWXUQ%ON. The parameter PF used in both PXROS services indicates the
memory class from which memory is taken, or to which it is returned. The memory
classes used to return a memory block PXVW be the same as that used for requesting
the memory block.

%ON is the address of a data pointer, where PXROS enters the address of the memory
block provided by 3[0F7DNH%ON If there is not enough memory available, %ON is 
When memory is released, %ON must contain the address given by 3[0F7DNH%ON. It is
not possible to only partially release a requested block. PXROS sets the pointer to 
when a block is released.

The size of the memory area is only needed when a request is made. VL]H contains the
size of the desired memory in %\WH. Certain size restrictions may apply to the requested
memory block.

HighTec EDV-Systeme GmbH 59 20. Mai 1996


PXROS V4 Users Guide Version 1.0

([DPSOH

fun()
{
PxUChar_t *buffer;
PxError_t err;
....
err = PxMcTakeBlk (PXMcSystemdefault,(PxAligned_t**)
&buffer,100);

if (err != PXERR_NOERROR)
{
....
}
....
PxMcReturnBlk (PXMcSystemdefault, (PxAligned_t **)
&buffer);
....
}

 0HPRU\&ODVVHV

 &UHDWLQJ0HPRU\&ODVVHV

PxError_t PxMcRequest ( PxMc_t *Mc,


PxMcType_t mctype,
PxSize_t size,
PxOpool_t opool )

PxError_t PxMcRequest_NoWait ( PxMc_t *Mc,


PxMcType_t mctype,
PxSize_t size,
PxOpool_t opool )

PxEvents_t PxMcRequest_EvWait ( PxMc_t *Mc,


PxMcType_t mctype,
PxSize_t size,
PxOpool_t opool,
PxEvents_t events )

PxError_t PxMcRelease ( PxMc_t *Mc )

At the beginning of the program, the V\VWHP PHPRU\ FODVV 3;0F6\VWHPGHIDXOW


contains the maximum amount of memory available for allocation by PXROS. This
memory can be split up into different memory classes as the program runs.

A new memory class is generated with the service 3[0F5HTXHVW: PXROS takes a
memory class object from the object pool RSRRO and enters its Id in 0F. When RSRRO is
empty, the task waits until an object becomes available.
HighTec EDV-Systeme GmbH 60 20. Mai 1996
PXROS V4 Users Guide Version 1.0

PFW\SH defines the type of the new memory class: i.e. either YDULDEOH or IL[HG block

memory classes. The different memory class types are described in detail in the
sections 7.3.2 and 7.3.3 respectively.

For fixed block memory classes, VL]H indicates the size of the memory blocks in %\WH .
For memory classes with a variable block size, VL]H is basically ignored.

Once generated, the new memory class is not automatically assigned memory. This
must be allocated to the memory class with the appropriate PXROS service.

In addition to the standard 3[0F5HTXHVW, two other services are available for
requesting a memory class: (1) 3[0F5HTXHVWB1R:DLW does not wait if the object pool
is empty; rather it returns immediately with the message PXERR_OBJ_NOOBJ. (2)
3[0F5HTXHVWB(Y:DLW waits until either an object is available in RSRRO, or one of the

events specified in HYHQWV has been signalled to the task. In both services, 0F has the
value  if no object has been made available.

Memory classes are released with the call 3[0F5HOHDVH. Once released, memory
classes return to the object pools they were taken from and 0F is set to .
3[0F5HOHDVH fails if the memory class is not empty. In other words, all memory

assigned to the memory class must be taken from the memory class before calling
3[0F5HOHDVH .

 0HPRU\&ODVVHVZLWKD9DULDEOH%ORFN6L]H

In a memory class of variable block size, available memory is


cataloged in a list of free blocks. When memory is requested,
PXROS searches the list for a block of sufficient size. If the block
chosen contains more memory than requested, it is split up and
residual memory remains on the list. Once a memory block is
released, it is placed on the list of free blocks and PXROS checks
whether it can be joined with the next block and the preceeding
block to make one bigger memory block.

Variable sized memory classes incur higher request and release run time than fixed
size memory classes. This is due to the time required to search for blocks sufficient to
fulfill a memory request, and the time needed to connect consecutive memory blocks.
They also do not allow one to estimate the processing time; however, variable sized
memory classes provide more flexibility than their fixed size counterparts.

If memory is requested from a variable size memory class for both long and short term
requirements, one runs a risk of memory fragmentation. This occurs when the entire
free memory is split up into many smaller blocks that cannot be connected together.
Under certain circumstances, memory requests can not be "honored", even though the
entire free memory is sufficient (i.e. there are no single blocks of sufficient size
available). For this reason, memory requested for different lengths of time should be
fulfilled by different memory classes.
To generate variable sized memory classes, 3[0F5HTXHVWs parameter PFW\SH is

HighTec EDV-Systeme GmbH 61 20. Mai 1996


PXROS V4 Users Guide Version 1.0

assigned the value 3;0F9DUVL]HG. There are also special types of variable size
memory classes. The Users Guide does not deal with these as they are only used in
special applications. These types do use 3[0F5HTXHVWs parameterVL]H.

 0HPRU\&ODVVHVZLWKD)L[HG%ORFN6L]H

Fixed size memory classes also catalog memory in a list of free


blocks. In this case, PXROS need not search for a block of
sufficient size to fulfill a memory request; rather, the first free block
can be used. Also, consecutive memory blocks are not joined to
form bigger blocks. For this reason, requesting and releasing
memory from fixed size memory classes can be processed within an
estimable period of time.

To create a memory class of IL[HG EORFN VL]H 3[0F5HTXHVWs parameter PFW\SH is


assigned 3;0F)L[VL]HG. Requests for more memory than the block size fail. PXROS
does not provide the means to join several blocks. If a smaller sized block is requested,
an entire fixed size memory block is taken from the memory class.

 $OORFDWLQJDQG5HOHDVLQJ0HPRU\

Void PxMcInsertBlk ( PxMc_t mc,


PxAligned_t *Blk,
PxSize_t size )

PxError_t PxMcRemoveBlk ( PxMc_t mc,


PxSize_t minsize,
PxSize_t optsize,
PxSize_t maxsize,
PxUInt_t sizefactor,
PxAligned_t **Blk,
PxSize_t *Size )

When a memory class is generated, it is not immediately assigned its memory. This is
done with a specific PXROS service: 3[0F,QVHUW%ON inserts a memory block into a
memory class. At this time, the memory block may not be allocated to another memory
class; however, it is likely that the block has either not been in a memory class before,
or that it previously belonged to a different memory class. PF is the Id of the memory
class into which the memory block will be inserted. %ON contains the memory blocks
starting address and VL]H its size in byte.

HighTec EDV-Systeme GmbH 62 20. Mai 1996


PXROS V4 Users Guide Version 1.0

([DPSOH

PxError_t fun (PxSize_t size, PxMc_t *mc)


{
PxAligned_t *Blk;
PxError_t err;

err = PxMcTakeBlk (PXMcSystemdefault, &Blk, size);


if (err != PXERR_NOERROR)
return err;
PxMcRequest (mc, PXMcVarsized, 0, PXOpoolSystemdefault);
PxMcInsertBlk (*mc, Blk, size);

return PXERR_NOERROR;
}

When memory is removed with the call 3[0F7DNH%ON, the block always contains the
required administrative information for returning the block with the call 3[0F5HWXUQ%ON.
This becomes useless if a block is removed from the memory for any length of time,
e.g. if it is assigned to a different memory class. In this case, it is advisable to remove
the block with 3[0F5HPRYH%ON

The 3[0F5HPRYH%ON parameters PF (the memory class) and %ON (the pointer)
correspond in meaning to their 3[0F7DNH%ON counterparts; however, the two services
differ in the size of the memory blocks they use. Specifically, 3[0F5HPRYH%ON does
not have to request memory of a FHUWDLQ size; rather, RSWVL]H describes the desired size
of the memory block. PLQVL]H and PD[VL]H indicate the minimum and maximum values
within which the memory blocks size must lie. A value can be indicated by VL]HIDFWRU.
The size of the assigned block must be divisible by this value. This is important when,
e.g. memory for a fixed size memory class must be provided. If possible, PXROS takes
a block that is sufficient for the requirements from the memory class PF, and registers
its size in 6L]H

Memory blocks that are removed from a memory class with 3[0F5HPRYH%ON cannot
be returned with the call 3[0F5HWXUQ%ON; instead, they are assigned to a memory
class with 3[0F,QVHUW%ON.

 8VHRI'LIIHUHQW0HPRU\&ODVVHVLQWKH6\VWHP

Essentially, there are two reasons to use several memory classes: security and run
time. If single parts of the application only use memory from specific memory classes,
problems that are caused by a lack of memory are limited locally. This means critical
components continue to run, even if there is no memory available for other functions.
Simple systems generally only use the system memory class.

Memory requests from fixed size memory classes can be processed much faster than
requests from variable size memory classes. If similar memory block sizes are
frequently needed, it is advisable to generate a fixed block memory class to service the
requests quickly.

HighTec EDV-Systeme GmbH 63 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 7LSVIRU'HYHORSHUV

Requesting and releasing memory from variable size memory classes is time-
consuming. If small memory blocks are only used for a short time, HighTec
recommends defining corresponding local variables. Requesting large memory areas
via local variables could increase the respective tasks stack requirements
disproportionately.

Run time is unnecessarily increased when memory is often needed on a short-term


bases and is requested and released after use. It is better to request a memory block
of maximum size and reuse it when possible.

 ([DPSOHV

The source code to the following memory administration examples can be found on the
accompanying disk in the directory PHP.

 H[F

Task1 requests memory from the system memory class and then releases. The size of
the requested block is increased until the request can no longer be fulfilled. The size is
then set back to the starting value.

7DVN)XQF

PxError_t err;
PxAligned_t *buffer;
PxUInt_t i = 100;

for (;;)
{
(1) err = PxMcTakeBlk (PXMcSystemdefault,&buffer,i);
(2) if (err == PXERR_NOERROR)
{
(3) PxMcReturnBlk (PXMcSystemdefault,
&buffer);
(4) i += 100;
}
else
(5) i = 100;
}

GHWDLOHGSURFHVVGHVFULSWLRQ

Task1 requests a memory block from the system memory class:

(1) err = PxMcTakeBlk (PXMcSystemdefault,&buffer,i);

HighTec EDV-Systeme GmbH 64 20. Mai 1996


PXROS V4 Users Guide Version 1.0

The size of the memory block is contained in the variable L and amounts to  %\WHV
when the first call is placed. The starting address of the memory block should be
entered into EXIIHU. The return value, HUU, indicates whether the request was successful
or not. If the memory was allocated, HUU has the value PXERR_NOERROR,

(2) if (err == PXERR_NOERROR)

and the memory is returned as follows:

(3) PxMcReturnBlk (PXMcSystemdefault, &buffer);

After the call, buffer is 0. L is raised by 100 (4) and memory is again requested, only this
time a bigger block (1) is requested. If the memory request cannot be fulfilled, L is
initialized again (5) and the requests starts over.

 H[F

Task1 removes a memory block of 2000 bytes from the system memory class. If this
request is successful, a new memory class is generated with a fixed block size of 1000
bytes. The requested memory is placed in this memory class. Then a 500 byte block
from the new memory class is requested and released.

7DVN)XQF

PxMc_t mc;
PxError_t err;
PxAligned_t *adr;
PxSize_t size;

(1) err = PxMcRemoveBlk ( PXMcSystemdefault, 2000, 2000,


2000, 100, &adr, &size);
if (err == PXERR_NOERROR)
{
(2) PxMcRequest (&mc, PXMcFixsized, 1000,
PXOpoolSystemdefault);
(3) PxMcInsertBlk (mc, adr, 1000);
(4) adr += 1000 / sizeof(PxAligned_t);
(5) PxMcInsertBlk (mc, adr, 1000);
}
else
{
mc = PXMcSystemdefault;
}

for (;;)
{
(6) err = PxMcTakeBlk (mc, &adr, 500);
if (err == PXERR_NOERROR)
{
(7) PxMcReturnBlk (mc, &adr);
}
}

HighTec EDV-Systeme GmbH 65 20. Mai 1996


PXROS V4 Users Guide Version 1.0

GHWDLOHGSURFHVVGHVFULSWLRQ

Task1 removes 2000 bytes from the system memory class (1) and, if successful, uses

(2) PxMcRequest (&mc, PXMcFixsized, 1000,


PXOpoolSystemdefault);

to generate the memory class PF with a fixed block size of 1000 bytes.

(3) PxMcInsertBlk (mc, adr, 1000);

The new memory class, PF, is assigned 1000 bytes (1) of memory. This block begins
at the address DGU DGUis then set to the address directly after these 1000 bytes:

(4) adr += 1000 / sizeof(PxAligned_t);

and the remaining 1000 bytes are assigned to the memory class.

(5) PxMcInsertBlk (mc, adr, 1000);

The blocks are inserted individually since a block is only tested for sufficient size. It is
not split up, even if it is big enough for several blocks. With

(6) err = PxMcTakeBlk (mc, &adr, 500);

a 500 byte block is requested from the new memory class. The requested blocks size
is VPDOOHU than the memory class fixed block size. The request can be fulfilled. In
contrast, a request of  bytes could not be fulfilled, even though the memory class
still has this amount of memory available (2000 bytes is PRUH than the memory class
block size). Finally, the memory is then released (7).

HighTec EDV-Systeme GmbH 66 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 3;5267LPH

 6XPPDU\

PXROS has a system clock for time-based routines. This clock is incremented by the
applications periodic call to 3[7LFN'HILQHB+QG. The time span between two calls is
referred to as 3;526WLFN PXROS services specify time with the tick unit.

Time-based jobs usually signal the expiration of a predefined time span to a task. For
this reason, the application is provided with specific services:

3[7R,QLW WR WLFNV HYHQWV initializes a timeout structure at the address WR. After WLFNV
PXROS ticks, the events in the event mask HYHQWV are signalled to the calling task. The
timeout is started with the call 3[7R6WDUW WR and can be stopped with 3[7R6WRS WR .
When events are signalled SHULRGLFDOO\, similar services can be used: 3[3H,QLW
3[3H6WDUW and 3[3H6WRS

Sometimes these services are not sufficient to perform specific jobs. PXROS also
provides a so-called GHOD\ MRE to activate (after a given time span) predefined functions
on the handler level. A GHOD\ REMHFW is required for the definition of a delay job. The
application requests a delay object with the call 3['HOD\5HTXHVW. 3['HOD\6FKHG
GHOD\ WLFNV KDQGOHU DUJ gives the delay object, GHOD\, the assignment to call the

function KDQGOHU with the argument DUJ after WLFNV PXROS ticks. If the job is not
executed on the task level, but on handler level, the service 3['HOD\6FKHGB+QG is
used. This handler specific service has an identical list of parameters.

 3;5267LPH%DVH

Void PxTickDefine_Hnd ( void )


PxTicks_t PxTickGetCount ( void )

Every time-based application must call 3[7LFN'HILQHB+QG in order to increment the


system clock. When this is called, PXROS checks if any jobs must be processed, and if
so, PXROS starts them. This is done with a predefined, processor and version
dependent time base. For this reason, the largest possible PXROS tick should be
chosen to minimize the system load. e.g. if an application only uses time intervals that
are a multiples of 10 ms, a PXROS tick should be given the size 10 ms.

Normally, the systems time base is made available by a hardware timer that generates
an interrupt after the desired time frame expires. 3[7LFN'HILQHB+QG is called in the
ensuing interrupt handler, and the timer is started once again. Any other periodic
interrupt source could be utilized as an alternative to a timer. Assigning interrupt
routines to an interrupt source is explained in chapter 11. The current state of the
PXROS clock can be "read" with 3[7LFN*HW&RXQW. This service can be used to e.g.
take time measurements within the system.

HighTec EDV-Systeme GmbH 67 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 6WDQGDUG6HUYLFHV

 7LPHRXWV

PxError_t PxToInit ( PxTo_T *to_ptr,


PxTicks_t ticks,
PxEvents_t events )

PxError_t PxToStart ( PxTo_T *to_ptr )


PxError_t PxToStop ( PxTo_T *to_ptr )
PxError_t PxToClear ( PxTo_T *to_ptr )

PxError_t PxToChange ( PxTo_T *to_ptr,


PxTicks_t ticks,
PxEvents_t events )

With these functions, the end of a time span is signalled to a task. A timeout structure
of the type 3[7RB7 is required. This structure can either be global, requested
dynamically, or located on the tasks stack.

3[7R,QLW initializes the structure such that the events of the event mask HYHQWV are
signalled to the calling task after WLFNV PXROS ticks. This call does not start the timeout
immediately; rather, it provides and initializes internal resources required.

A timeout is started with a call to 3[7R6WDUW. A timeout can be


stopped with 3[7R6WRS. If the timeout is finished, 3[7R6WRS has no
effect. With 3[7R&KDQJH, the values of WLFNV and HYHQWV can be
changed. This stops any running timeout.

3[7R&OHDU FOHDUV the timeout. In other words, the timeout is stopped (if active) and the
internal resources, requested by 3[7R,QLW are released. After 3[7R&OHDU has been
called, the application must reinitialize the cleared timeout structure with 3[7R,QLW
before again using the structure with 3[7R6WDUW, 3[7R6WRS, or 3[7R&KDQJH.

([DPSOH

#define EV_TIMEOUT ....

TaskFunc()
{
PxTo_T to;
....
PxToInit (&to, 100, EV_TIMEOUT);
....
PxToStart (&to);
....
PxAwaitEvents (EV_TIMEOUT);
PxToClear(&to);
....
}

HighTec EDV-Systeme GmbH 68 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 3HULRGLF(YHQWV

PxError_t PxPeInit ( PxPe_T *pe_ptr,


PxTicks_t ticks,
PxEvents_t events )

PxError_t PxPeStart ( PxPe_T *pe_ptr )

PxError_t PxPeStop ( PxPe_T *pe_ptr )

PxError_t PxPeClear ( PxPe_T *pe_ptr )

PxError_t PxPeChange ( PxPe_T *pe_ptr,


PxTicks_t ticks,
PxEvents_t events )

These functions periodically signal events to a task. The services are related to the
3[7R services described above. 3[3H services require a structure of the type

3[3HB7. This structure can be global, requested dynamically, or located on a tasks

stack.

3[3H,QLW initializes the structure so that the events in the event PDVN HYHQWV can be
signalled to the calling task after WLFNV PXROS ticks. The periodic event is started with
3[3H6WDUW and stopped with 3[3H6WRS . 3[3H&KDQJH changes the WLFNV and HYHQWV

values, after which the signalling of events must be reinitialized with 3[3H6WDUW.

3[3H&OHDU interrupts any active periodic events and releases the internal resources
requested with 3[3H,QLW. After 3[3H&OHDU has been called, the application must
reinitialize the cleared periodic event with PxPeInit before again using the structure with
3[3H6WDUW , 3[3H6WRS or 3[3H&KDQJH .

([DPSOH

#define EV_PE ....

TaskFunc()
{
PxPe_T pe;
....
PxPeInit (&pe, 100, EV_PE);
....
....
PxPeStart (&pe);
....
for (;;)
{
PxAwaitEvents (EV_PE);
....
}
}

HighTec EDV-Systeme GmbH 69 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 'HOD\-REV

The application can give PXROS a GHOD\ MRE. This activates and executes the indicated
function on the handler level after a given time span expires.

 'HOD\-RE5HVRXUFHV

PxError_t PxDelayRequest ( PxDelay_t *Delay,


PxOpool_t Opool )

PxError_t PxDelayRequest_NoWait ( PxDelay_t *Delay,


PxOpool_t Opool )

PxEvents_t PxDelayRequest_EvWait ( PxDelay_t *Delay,


PxOpool_t Opool,
PxEvents_t events )

PxError_t PxDelayRelease ( PxDelay_t *Delay )

Every delay job requires a delay object, which the


application requests with a call to 3['HOD\5HTXHVW. For
example, PXROS takes a delay object from the object
pool 2SRRO and enters its Id in 'HOD\. If 2SRRO is empty,
the task waits until an object becomes available.

In addition to the standard service 3['HOD\5HTXHVW, two


other specialized services are available:
3['HOD\5HTXHVWB1R:DLW , which does not wait for an

object to become available if the object pool is empty;


rather, it immediately returns the error
PXERR_OBJ_NOOBJ. The second service
3['HOD\5HTXHVWB(Y:DLW waits until either an object
becomes available in 2SRRO, or until an event from HYHQWV
is signalled to the task. With both services, 'HOD\ has the
value  if no delay object was made available.

3['HOD\5HTXHVW does not immediately assign a job to the requested delay object. This
is accomplished in an individual step (see section 8.4.2).

A delay object is released with 3['HOD\5HOHDVH and returns to the object pool it was
taken from. 'HOD\ is thereby set to . If the delay job given 'HOD\ was not executed, it
is deleted.

HighTec EDV-Systeme GmbH 70 20. Mai 1996


PXROS V4 Users Guide Version 1.0

([DPSOH

TaskFunc()
{
PxDelay_t delay;
....
/* request */
PxDelayRequest (&delay, PXOpoolSystemdefault);
/* use */
.....
/* release */
PxDelayRelease (&delay);
....
}

 6WDUWLQJD'HOD\-RE

Void PxDelaySched ( PxDelay_t delay,


PxTicks_t ticks,
void handler (PxArg_t),
PxArg_t arg )

With 3['HOD\6FKHG, the delay object, GHOD\, is given an assignment and allocated to
PXROS. After WLFNV PXROS ticks have expired, PXROS activates the function KDQGOHU
with the argument DUJ. If KDQGOHU requires several arguments, these can be entered in
an individual structure. This structures address is given inDGU

3['HOD\6FKHG can only be called by tasks. Handlers must use the handler specific
service 3['HOD\6FKHGB+QG, which uses an identical parameter list.

([DPSOH

typedef struct {
....
....
} ArgStruct_T;

void handler (PxArg_t arg)


{
ArgStruct_T *str;

str = (ArgStruct_T *) arg;


....
}

HighTec EDV-Systeme GmbH 71 20. Mai 1996


PXROS V4 Users Guide Version 1.0
TaskFunc()
{
PxDelay_t delay;
ArgStruct_T str;
....

/* request */
PxDelayRequest (&delay, PXOpoolSystemdefault);

/* use */
str ... =
str ... =
tr ... =
PxDelaySched (delay, 100, handler, (PxArg_t) &str);

/* release */
PxDelayRelease (&delay);
....
}

The function KDQGOHU is executed on the


handler level. Keep in mind that only Delay Handler
PXROS services that can be executed by
handlers may be used within the function.

When KDQGOHU is activated, it interrupts the PxDelaySched


task that is active at that time. If multiple
delay jobs are activated at the same time,
they are performed sequentially, i.e. they do PXROS ticks
not interrupt one another. Delay jobs can be
interrupted by any hardware interrupt handler.

As soon as KDQGOHU is activated, no job is associated with the relevant delay object. If a
function is to be called SHULRGLFDOO\, 3['HOD\6FKHGB+QG must be repeatedly replace
the job associated with the calling function. To do so, it must "know" the the relevant
delay objects Id, thus the Id must be provided globally or via the argument.

([DPSOH

typedef struct {
PxDelay_t delay;
....
} ArgStruct_T;

HighTec EDV-Systeme GmbH 72 20. Mai 1996


PXROS V4 Users Guide Version 1.0
void handler (PxArg_t arg)
{
ArgStruct_T *str;

str = (ArgStruct_T *) arg;


....

/* start delay job again */


PxDelaySched_Hnd (str->delay, 100, handler, arg);
}

TaskFunc()
{
PxDelay_t delay;
ArgStruct_T str;

....

/* request */
PxDelayRequest (&delay, PXOpoolSystemdefault);

str.delay = delay;
str.... =
str.... =
/* start delay job */
PxDelaySched (delay, 100, handler, (PxArg_t) &str);
....
}

 &DQFHOOLQJD'HOD\-RE

By calling 3['HOD\6FKHG with the value  for WLFNV, a delay job associated with the
specified delay object can be cancelled In this situation, the arguments KDQGOHU and
DUJare of no consequence. If the job has already been executed, the call has no effect.

If 3['HOD\6FKHG is called for a delay object with WLFNV not equal to , the old job will be
cancelled and the new job is installed. It is therefore not necessary to cancel the old job
explicitely before using 3['HOD\6FKHG in this way. If the old job is to be kept, a second
delay object must be requested and the new job linked to it.

([DPSOH

TaskFunc()
{
PxDelay_t delay;

....

/* request */
PxDelayRequest (&delay, PXOpoolSystemdefault);

HighTec EDV-Systeme GmbH 73 20. Mai 1996


PXROS V4 Users Guide Version 1.0
/* use */
PxDelaySched (delay, 100, handler, (PxArg_t) &str);
....
/* cancel job */
PxDelaySched (delay, 0, 0, 0);
....
/* use again */
PxDelaySched (delay, 50, handler, (PxArg_t) &str);
....
/* use and cancel old job if necessary*/
PxDelaySched (delay, 200, handler, (PxArg_t) &str);

/* release */
PxDelayRelease (&delay);
....
}

 ([DPSOHV

The source code for the delay job examples can be found in the directory GHOD\ on the
accompanying disk.

All examples use signals and wait for events, the use of which is described in detail in
chapter 6. This requires knowledge about how events are signalled and received, as
well as the effect this has on the scheduling of tasks.

 H[F

Task1 generates a delay job that activates 'HOD\)XQF after 100 ticks. This function
signals EV_DELAY to Task2. Task2 then becomes active and signals EV_SIG to
Task1, which restarts the delay job.

'HOD\)XQF

PxTask_t task = (PxTask_t) arg;

(1) PxTaskSignalEvents_Hnd (task, EV_DELAY);

7DVN)XQF

PxDelay_t delay;
(2) PxDelayRequest (&delay, PXOpoolSystemdefault);

HighTec EDV-Systeme GmbH 74 20. Mai 1996


PXROS V4 Users Guide Version 1.0
for (;;)
{
(3) PxDelaySched (delay,100,DelayFunc, (PxArg_t)
Task2Id);

(4) PxAwaitEvents (EV_SIG);


}

7DVN)XQF

for (;;)
{
(5) PxAwaitEvents (EV_DELAY);
(6) PxTaskSignalEvents (Task1Id, EV_SIG);
}

GHWDLOHGSURFHVVGHVFULSWLRQ

With

(2) PxDelayRequest (&delay, PXOpoolSystemdefault);

Task1 requests the delay object GHOD\ from the system pool. The call

(3) PxDelaySched (delay, 100, DelayFunc, (PxArg_t)


Task2Id);

gives GHOD\ the following delay job: after 100 PXROS ticks, the delay function
'HOD\)XQF is called with the argument 7DVN,G

Now Task1 awaits EV_SIG with

(4) PxAwaitEvents (EV_SIG)

Task2 then becomes active and awaits EV_DELAY with

(5) PxAwaitEvents (EV_DELAY)

Now both tasks are in a state of ZDLWLQJ After the lapse of 100 PXROS ticks, PXROS
activates 'HOD\)XQF. With

(1) PxTaskSignalEvents_Hnd (task, EV_DELAY);

EV_DELAY is sent to Task2, the Id of which is given to the function as argument. Upon
receiving this signal, Task2 no longer waits. Using

(6) PxTaskSignalEvents (Task1Id, EV_SIG)

Task2 sends EV_SIG to Task1. Its wait is ended and it restarts the delay job.

HighTec EDV-Systeme GmbH 75 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 H[F

Both tasks start an individual delay job that in both cases calls 'HOD\)XQF after a
certain time. Both tasks wait for an event to be signalled. 'HOD\)XQF signals an event to
a task and restarts itself. The delay objects event, task and Id take the function from a
parameter structure, the address of which is given as argument.

typdef struct {
PxDelay_t delay;
PxTask_t task;
PxEvents_t events;
PxTicks_t ticks;
} ArgStr_T;

'HOD\)XQF

(1) ArgStr_T *str = (ArgStr_T *) arg;

(2) PxTaskSignalEvents_Hnd (str->task, str->events);


(3) PxDelaySched_Hnd (str->delay, str->ticks, DelayFunc,
arg);

7DVN)XQF

PxDelay_t delay;
(4) PxDelayRequest (&delay, PXOpoolSystemdefault);

(5) str.delay = delay;


(6) str.task = myid;
(7) str.ticks = 20;
(8) str.events = EV_DEL1;

(9) PxDelaySched (str.delay, str.ticks, DelayFunc, (PxArg_t)


&str);

for (;;)
{
(10) PxAwaitEvents (EV_DEL1);
}

GHWDLOHG3URFHVVGHVFULSWLRQ

Task1 and Task2 have almost identical code. For this reason, only Task1s code is
described here.

The task requests a delay object:

(4) PxDelayRequest (&delay, PXOpoolSystemdefault);

HighTec EDV-Systeme GmbH 76 20. Mai 1996


PXROS V4 Users Guide Version 1.0

Afterwards, some values are assigned to a parameter structure ((5) - (8)). These
include the Id of a delay object, the Id of a task, a value for PXROS ticks, and an event
mask. The task gives PXROS the delay job:

(9) PxDelaySched (str.delay, str.ticks, DelayFunc,


(PxArg_t) &str);

After a given period of time, PXROS calls 'HOD\)XQF gives the address of the
parameter structure as argument. With

(2) PxTaskSignalEvents_Hnd (str->task, str->events);

the event is signalled to the task and the delay job is restarted:

(3) PxDelaySched_Hnd ( str->delay, str->ticks,


DelayFunc, arg);

If, at this time, the delay jobs of both tasks are waiting, these are executed
successively. They do not interrupt each other.

 H[F

This example demonstrates how a delay job is stopped and its delay object is released.
Task1 initializes a delay job and waits for the signals EV_DELAY and EV_INTR. If
EV_DELAY is signalled, the task restarts the job. Using EV_INTR, the delay job is
stopped and the object released.

'HOD\)XQF

(1) PxTaskSignalEvents_Hnd (Task1, (PxEvents_t) arg);

7DVN)XQF

Pxdelay_t delay;
PxEvents_t ev;
(2) PxDelayRequest (&delay, PXOpoolTaskdefault);
(3) PxDelaySched (delay, 1000, DelayFunc,
(PxArg_t) EV_DELAY);

(4) for (;;)


{
(5) ev = PxAwaitEvents (EV_INTR | EV_DELAY);
(6) if (ev & EV_DELAY)
{
(7) PxDelaySched (delay, 1000, DelayFunc,
(PxArg_t) EV_DELAY);
}

HighTec EDV-Systeme GmbH 77 20. Mai 1996


PXROS V4 Users Guide Version 1.0
(8) if (ev & EV_INTR)
{
(9) PxDelaySched (delay, 0, 0, 0);
(10) PxDelayRelease (&delay);
}
}

7DVN)XQF

(11) PxTaskSignalEvents (Task1Id, EV_INTR);

(12) for (;;);

GHWDLOHGSURFHVVGHVFULSWLRQ

Task1 requests a delay object

(2) PxDelayRequest (&delay, PXOpoolTaskdefault);

and it is assigned the following delay job:

(3) PxDelaySched (delay,1000,DelayFunc, (PxArg_t)


EV_DELAY);

The task then waits for the signals EV_DELAY and EV_INTR.

(5) ev = PxAwaitEvents (EV_INTR | EV_DELAY);

While Task1 is waiting, the lower priority Task2 becomes active and signals EV_INTR
to Task1.

(11) PxTaskSignalEvents (Task1Id, EV_INTR);

Once Task1 is reactivated, it evaluates the events it received: if the delay job has
already been executed, then EV_DELAY was sent and Task1 restarts the job (7);
however, this case is not important at the moment. The requirement

(8) if (ev & EV_INTR){

is fulfilled by the event signalled by Task2. The task stops the delay job by calling:

(9) PxDelaySched (delay, 0, 0, 0);

WLFNVis assigned the value  The other two parameters for this function are irrelevant
and thus assigned  as well. The delay object, GHOD\, is now released:

(10) PxDelayRelease (&delay);

Since the release of the delay object automatically stops a job in process (see section
8.4.1), the explicit interruption (9) is in this case superfluous. The task now waits for the
events EV_DELAY and EV_INTR, which never arrive.

HighTec EDV-Systeme GmbH 78 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 H[F

This example implements the same functions as H[DPSOH 


. This time however,
3[7R services are used.

This example demonstrates how a timeout is aborted, and how resources are released
when using 3[7R services. Task1 initializes a timeout. Once the timeout expires,
EV_DELAY is signalled. The task then waits for the events EV_INTR and EV_DELAY.
If EV_DELAY is signalled, the task restarts the timeout. If EV_INTR is signalled, the
timeout is cleared.

7DVN)XQF

PxTo_T to;
PxEvents_t ev;

(1) PxToInit (&to, 100, EV_DELAY);


(2) PxToStart (&to);

(3) for (;;)


{
(4) ev = PxAwaitEvents (EV_INTR | EV_DELAY);
(5) if (ev & EV_DELAY)
(6) PxToStart (&to);

(7) if (ev & EV_INTR)


(8) PxToClear (&to);
}

7DVN)XQF

(9) PxTaskSignalEvents (Task1Id, EV_INTR);


(10) for (;;);

GHWDLOHGSURFHVVGHVFULSWLRQ

Task1 has a timeout structure, WR, on its stack. Using 3[7R,QLW, Task1 initializes it to
wait 100 PXROS ticks and then signal EV_DELAY to the task.

(1) PxToInit (&to, 100, EV_DELAY);

Afterwards, the task starts the timeout

(2) PxToStart (&to);

and waits for EV_DELAY and EV_INTR (4). With Task1 in a wait state, Task2 becomes
active and sends Task1 the signal EV_INTR

(9) PxTaskSignalEvents (Task1, EV_INTR);

HighTec EDV-Systeme GmbH 79 20. Mai 1996


PXROS V4 Users Guide Version 1.0

Task2 remains in endless loop for the rest of the program. Task1 now evaluates the
events signalled: if the timeout has already expired, EV_DELAY was signalled and
Task1 restarts the timeout (6). This is currently not the case. The requirement

(7) if (ev & EV_INTR){

is fulfilled. The task clears the timeout using

(8) PxToClear (&to);

This stops the timeout. Subsequently the task awaits the events EV_DELAY and
EV_INTR, which can no longer be signalled.

 H[F

An event is periodically signalled to Task1. Every time the event is signalled, Task1
increments a counter. After 10 times, the periodic event is cleared.

7DVN)XQF

PxPe_T pe;
PxInt_t count;

(1) PxPeInit (&pe, 100, EV_PE);


(2) PxPeStart (&pe);
(3) count = 0;
for (;;)
{
(4) PxAwaitEvents (EV_PE);
(5) count++;
(6) if (count == 10)
{
(7) PxPeClear (&pe);
}
}
GHWDLOHGSURFHVVGHVFULSWLRQ

Task1 has a structure, SH, on its stack. Using PxPeInit, Task1 initializes it such that the
task is signalled EV_PE after 100 ticks.

(1) PxPeInit (&pe, 100, EV_PE);

The periodic event is started

(2) PxPeStart (&pe);

and the counter is initialized at 0 (3). Task1 awaits the signal EV_PE

(4) PxAwaitEvents (EV_PE);

HighTec EDV-Systeme GmbH 80 20. Mai 1996


PXROS V4 Users Guide Version 1.0

and increments the counter as soon as it receives the signal for the event (5). After 10
times, the structure for the periodic event is cleaed:

(7) PxPeClear (&pe);

Afterwards, Task1 remains in PxAwaitEvents (EV_PE) for eternity (or at least until you
stop the program :^).

HighTec EDV-Systeme GmbH 81 20. Mai 1996


PXROS V4 Users Guide Version 1.0

HighTec EDV-Systeme GmbH 82 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 0DLOER[HV

 6XPPDU\

In general, messages allow communication between


tasks. A message is never sent to a WDVN; rather,
always to a PDLOER[. Mailboxes store messages on a
FIFO (first in- first out) based linked lists: these are
kept in the order they arrive in. When a task requests
a message, it is usually given the message that has
been stored in the mailbox longest. The tasks private
mailbox is usually sufficient for most communication.
3[0E[5HTXHVW allows one to create additional
mailboxes for e.g. message pools.

 &UHDWLQJ0DLOER[HV

PxError_t PxMbxRequest ( PxMbx_t *Mbx,


PxOpool_t opool )

PxError_t PxMbxRequest_NoWait ( PxMbx_t *Mbx,


PxOpool_t opool )

PxEvents_t PxMbxRequest_EvWait ( PxMbx_t *Mbx,


PxOpool_t opool,
PxEvents_t events )

PxError_t PxMbxRelease ( PxMbx_t *Mbx )

When a task is created, its SULYDWH PDLOER[ is created simultaneously. This private
mailbox is where the task normally awaits messages.

Usually the private mailboxes are sufficient for an application intertask communcation.
Sometimes however, it is useful to create additional mailboxes to e.g. be used as
message pools to store messages that were generated in advance (see chapter 5.7).
This saves time since requesting a message from a mailbox is a lot quicker than to
creating a new message each time one is needed. Message pools can also be quite
useful for implementing semaphores.

A mailbox is created with the call 3[0E[5HTXHVW: PXROS takes a mailbox object from
the object pool RSRRO and enters its Id in 0E[. If RSRRO is empty, the task waits until an
object becomes available.

HighTec EDV-Systeme GmbH 83 20. Mai 1996


PXROS V4 Users Guide Version 1.0

In addition to the standard service 3[0E[5HTXHVW, two specialized services are


available: 3[0E[5HTXHVWB1R:DLW, which does not wait for an object to become
available when the object pool is empty; rather, it but returns immedialtely with the error
PXERR_OBJ_NOOBJ. The second special service, 3[0E[5HTXHVWB(Y:DLW, waits
until either an object is available in RSRRO, or until one of the events in the event mask
HYHQWV is signalled to the task. With both services, 0E[ contains a  if no mailbox was

been made available.

If the mailbox is no longer needed, it can be released by with the call 3[0E[5HOHDVH.
When released, the object used returns to the object pool from which it was taken. As a
result, 0E[ is set to  The service 3[0E[5HOHDVH fails if there are still messages in
the mailbox, or if tasks are waiting for messages at the specified mailbox. A tasks
private mailbox can not be released.

 0DLOER[+DQGOHUV

PxError_t PxMbxInstallHnd (PxMbx_t mbx,


PxError_t (*hnd)
(PxMsg_t *,PxMsgType_t,PxArg_t),
PxMsgType_t msgspec,
PxArg_t arg )

Mailbox
Handler

Using the service 3[0E[,QVWDOO+QG, the routine KQG is installed at the mailbox PE[ as
a PDLOER[ KDQGOHU. KQG can be activated by PXROS whenever a message is sent to
PE[. The mailbox handler need not be activated with the arrival of HYHU\ message;

instead, specific messages can be chosen. The choice is not based on the messages
FRQWHQW; rather, it is based on the given priority. The message type is defined by the

parameter PVJVSHF. The parameter can receive one of the following values:

3;0VJ3ULR0VJ indicates messages with a SULRULW\. These messages are


sent with the service 3[0VJ6HQGB3ULR. If PVJVSHF has this value, KQG is
only activated when messages have a priority.

3;0VJ1RUPDO0VJ indicates a "normal" message (i.e. without priority).

These messages are sent with the service 3[0VJ6HQG. If PVJVSHF has this
HighTec EDV-Systeme GmbH 84 20. Mai 1996
PXROS V4 Users Guide Version 1.0

value, KQG is only activated by normal messages.

3;0VJ$Q\0VJ does not distinguish between messages with or without

priority. If PVJVSHF has this value, all messages activate KQG.


When a mailbox handler is activated, KQG is called with 3 parameters: the first
parameter has a message pointer, the second specifies the message type, and the
third parameter is any argument indicated in 3[0E[,QVWDOO+QG in DUJ.

If a mailbox handler is installed at the specified mailbox, the call fails. A mailbox
handler can be removed by calling 3[0E[,QVWDOO+QG and specifing the parameter KQG
to be .

Further processing of the message is determined by the mailbox handlers return value
as follows:

If KQG returns the value other than , PXROS assumes that the handler has
refused to accept the message. In this case, the message is QRW passed on
to the mailbox, and the 3[0VJ6HQG call fails. The return value of KQG is
taken on by 3[0VJ6HQG.

If KQGreturns the value  and the message is set to , PXROS assumes that
KQG has processed the message and either released it or sent it on its way.
In this case, the message does QRW reach the mailbox.

If KQG returns the value 0 and has QRW set the message to , the message
reaches the mailbox.

The standard version of PXROS does not provide a service to send and release
messages on the handler level. An installed mailbox handler can only read and
evaluate messages. The use of mailbox handlers enables tasks to wait at GLIIHUHQW
mailboxes simultaneousely: a mailbox handler is installed at every mailbox the task
wishes to monitor. Once a message arrives, the mailbox handler signals an event to the
task. This mechanism can also be used for flow control. In this case, the mailbox
handler registers any messages that arrive.

,PSRUWDQW a mailbox handler must be defined such that all parameters within the
routine are transfered over the stack. Register can not be allocated for this purpose.

 ([DPSOHV

The source code for the following examples can be found in the directory PE[ on the
accompanying disk.

HighTec EDV-Systeme GmbH 85 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 H[F

This example demonstrates how a mailbox handler enables a task to wait for
messages at several mailboxes simutaneously: Task1 creates a mailbox, PE[ with a
mailbox handler that signals an event whenever a message arrives. The task waits at
its private mailbox for messages and, simultaneously, for the mailbox handlers events.
Task2 sends a message, alternating between PE[ and Task1s private mailbox. If the
message arrives in PE[, Task1 stops waiting and takes the message from PE[.

typedef struct {
PxMbx_t Mbx;
} Request_T;

0E[+QG

(1) events = (PxEvents_t) arg;


(2) PxTaskSignalEvents_Hnd (Task1Id, events);
(3) return (0);

7DVN)XQF

Task2Mbx = PxTaskGetMbx (Task2Id);

(1) PxMbxRequest (&mbx, PXOpoolSystemdefault);


(2) PxMbxInstallHnd (mbx,MbxHnd,PXMsgAnyMsg,
(PxArg_t)EV_MBX1);

(3) PxMsgRequest (&msg, sizeof (Request_T),


PXMcSystemdefault, PXOpoolSystemdefault);

req = (Request_T *) PxMsgGetData(msg);


req->Mbx = mymbx;

(4) PxMsgSend(&msg, Task2Mbx);

for (;;)
{
(5) ev = PxMsgReceive_EvWait (&msg, mymbx, EV_MBX1);
(6) if (msg)
{
req = (Request_T *) PxMsgGetData(msg);
(7) req->Mbx = mbx;
PxMsgSend(&msg, Task2Mbx);
}
(8) if (ev & EV_MBX1)
{
(9) PxMsgReceive (&msg, mbx);
req = (Request_T *) PxMsgGetData(msg);
(10) req->Mbx = mymbx;
(11) PxMsgSend(&msg, Task2Mbx);
}
}

HighTec EDV-Systeme GmbH 86 20. Mai 1996


PXROS V4 Users Guide Version 1.0

HighTec EDV-Systeme GmbH 87 20. Mai 1996


PXROS V4 Users Guide Version 1.0
7DVN)XQF

for (;;)
{
(12) PxMsgReceive (&msg, mymbx);
req = (Request_T *) PxMsgGetData(msg);
(13) PxMsgSend (&msg, req->Mbx);
}

GHWDLOHGSURFHVVGHVFULSWLRQ

Task1 creates the mailbox PE[ (1), and installs the funtion 0E[+QG as the mailbox
handler for the new mailbox.

(2) PxMbxInstallHnd (mbx, MbxHnd, PXMsgAnyMsg,


(PxArg_t)EV_MBX1);

The function 0E[+QG is called with the argument (9B0%; for every message that is
sent to PE[.

Task1 then creates a message (3). The messages data area notes the mailbox to
which the message is to be sent back to. Task1 specifies its private mailbox as the
receiving mailbox, and sends the message to Task2 (4). Task1 then waits at its private
mailbox for either a message or the event (9B0%; (5).

Task2 accepts Task1s message from its private mailbox (12) and sends it to the
mailbox specified in the messages data area, in this case Task1s private mailbox (13).

Task1 becomes active again, and 3[0VJ5HFHLYHB(Y:DLWs parameters, HY and PVJ,


are  and "unequal to " respectively. This time, Task1 specifies PE[ in the messages
data area (7), sends the message to Task2, and waits again (5). After receiving this
message, Task2 forwards it to PE[. This causes the mailbox handler 0E[+QG to
become active.

The mailbox handler signals the event EV_MBX1 to Task1, which was specified during
its installation (2). The mailbox handler now returns  Afterwards, PXROS places the
message into the mailbox PE[. Task1 is activated by the signalled event and takes the
message from PE[:

(9) PxMsgReceive (&msg, mbx);

Once again, Task1 specifies its private mailbox in the messages data area, and the
message is sent to Task2. This process is continuously repeated. If a task is to wait at
a third or fourth mailbox, the mailbox handler 0E[+QG would be installed with a
different event for each case. This enables the calling task to directly identify the
mailbox that contains the new message.

HighTec EDV-Systeme GmbH 88 20. Mai 1996


PXROS V4 Users Guide Version 1.0

HighTec EDV-Systeme GmbH 89 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 2EMHFWVDQG2EMHFW3RROV

 6XPPDU\

Most PXROS services somehow utilize PXROS objects. These include


memory classes, message objects, mailboxes, object pools and delay
objects. Internally, these different objects are made up of a common
structure. By emphasizing various features of this structures, different
objects can be created. The precise composition of the objects is
generally of no consequence to their use in an application.

The object type dictate which PXROS services are available for the various objects. For
example, a service for a PDLOER[ REMHFW cannot be used on a GHOD\ REMHFW. Some
services are provided for all objects, regardless of their object type, such as those that
request or release objects. Services dealing with individual PXROS objects are
described in the corresponding chapters.

When PXROS is initialized, it automatically creates a


certain amount of objects. These are still of an
unspecified nature. The objects created are then
placed into an object pool (the V\VWHP SRRO) until they
are required. Specific objects can then be requested
by calling services that of the basic form
3[5HTXHVW . When these services are called,
Objekt-Pool
PXROS takes an unspecified object from the object
pool and gives it the desired features. An application
may also request an unspecified object and then
define the desired features itself. This is only necessary in exceptional circumstances
and is thus not dealt with in the Users Guide.

When an application begins, all objects reside in the V\VWHP SRRO -


3;2SRRO6\VWHPGHIDXOW, which is generated during initialization and filled with objects

New object pools can be created to distribute objects at any time while the program is
running. There are two types of object pools: YLUWXDO and UHDO object pools. While UHDO
object pools actually distribute objects, YLUWXDO object pools merely serve to limit access
to objects. The reason for, and the use of these differences is dealt with in section 10.4.
The system pool is generally sufficient for use with simple applications.

HighTec EDV-Systeme GmbH 90 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 *HQHUDWLQJ2EMHFW3RROV

PxError_t PxOpoolRequest ( PxOpool_t *Opool,


PxOpoolType_t type,
PxUInt_t capacity,
PxOpool_t src,
PxOpool_t pool )

PxError_t PxOpoolRequest_NoWait ( PxOpool_t *Opool,


PxOpoolType_t type,
PxUInt_t capacity,
PxOpool_t src,
PxOpool_t pool )

PxEvents_t PxOpoolRequest_EvWait ( PxOpool_t *Opool,


PxOpoolType_t type,
PxUInt_t capacity,
PxOpool_t src,
PxOpool_t pool,
PxEvents_t events )

PxError_t PxOpoolRelease ( PxOpool_t *Opool )

3[2SRRO5HTXHVW creates an object pool. Section 10.4 describes how additional object
pools can be useful. With the call 3[2SRRO5HTXHVW, PXROS takes an object from the
object pool SRRO, and converts it into an object pool, the Id of which is written in 2SRRO
If SRROis empty, then the task waits until an object becomes available.

FDSDFLW\ specifies how many objects the object pool should contain. These objects are
taken from the source pool VUF. W\SH defines whether a UHDOor YLUWXDO pool is created. To
create a UHDO object pool, W\SH receives the value 3;2SRRO5HDO, while to create a
YLUWXDO pool, W\SH is given the value 3;2SRRO9LUWXDO . Essentially, the difference lies in

the immediacy with which the object is extracted from a source pool. For a real object
pool, an object is extracted immediately from VUF. In contrast, an object is only taken
from a virtual pool when required. These differences are dealt with in detail in sections
10.2.1. and 10.2.2.

In addition to the standard service, 3[2SRRO5HTXHVW, there are two specialized


services available for requesting object pools: 3[2SRRO5HTXHVWB1R:DLW does not wait
for an object to become available at the specified object pool; rather, it returns
immediately with the error code PXERR_OBJ_NOOBJ. The second service,
3[2SRRO5HTXHVWB(Y:DLW , waits until either an object becomes available, or until the

task is signalled one of the events in the event mask HYHQWV. In both services, 2SRRO
has a value of  if no object pool was made available.

3[2SRRO5HOHDVH releases an object pool and returns the underlying object to the
object pool from which it came. The objects contained within the released object pool
are also returned to their source pool. If however, objects from the object pool are still
being used, the object pool cannot be released; otherwise, the object pool into which
they must return, would no longer exist! Also, if tasks are waiting for objects at the
object pool to be released, a call to 3;2SRRO5HOHDVH is unsuccessful.

HighTec EDV-Systeme GmbH 91 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 9LUWXDO2EMHFW3RROV

A virtual object pool serves to limit the use of objects in certain modules, without
actually allocating objects specifically to those modules. In this way, available objects
are not used up in one area alone. For example, if a task requests an object from the
object pool 3RRO, and 3RRO is empty, the request would not be "granted". If however,
3RRO is a virtual object pool with a small capacity, other tasks can make requests on the

source pool and (assuming the source pool is not empty as well) still receive the
objects theve requested.

Objects are actually allocated when a


request to a virtual object pool is
successful. If the virtual object pool is not Source Pool 32
empty, then an attempt is made to fulfill
the request by calling an object from the
source pool. If this is successful, the
number of available objects in the virtual
pool, as well as the source pool, is 4
10
reduced. If the virtual pool RU the source
pool is empty, the request fails. 20 11
5
A virtual object pool can be allotted more
objects than the source pool actually Virtual Pools
contains at the time of creation. Furthermore, an object pool can be the source pool of
several virtual object pools. It is possible, and in fact not uncommon, to allot PRUH
virtual object pools objects than are actually contained in the entire shared source pool.

 5HDO2EMHFW3RROV

A real object pool is issued resources


immediately. The resources are taken Real Object Pools
from the source pool. When the object 40
pool is created, these resources must be
available. As long as the capacity of the Source Pool
object pool is not , objects are always
available and may be allocated
immediately. 52
PxOppolRequest
Creating real object pools causes an
Source Pool
actual, physical allocation of objects to
various object pools. Critical application
12
components use real object pools to
ensure the availability of resources in
critical situations. Real Pool

HighTec EDV-Systeme GmbH 92 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 *HQHUDWLQJ$GGLWLRQDO2EMHFWV

PxError_t PxOpoolInsertNewObj ( PxOpool_t opool,


PxAligned_t **Blk,
PxSize_t *size )

PxSize_t PxGetObjsize ( void )

When PXROS is initialized, a number of objects are generated. These are kept in the
system object pool. New objects can be inserted with the call 3[2SRRO,QVHUW1HZ2EM.
Free memory is then converted into additional objects. %ON must indicate a free area
with the size of VL]H bytes. This service changes memory into an unspecified object
and places it in the object pool RSRRO. This object pool PXVW be a UHDO object pool (see
section 10.2.2). Also, VL]H must be large enough to hold an object whose size that can
be determined with 3[*HW2EMVL]H. The size of an object is dependent on both the
processor used, and on the maximum length of the object name.

If the service is successful,  is returned, %ON is increased by the size of one object,
and VL]H is reduced accordingly. If unsuccessful, an error code is returned and both
parameters remain unchanged.

Normally, all objects that are likely to be needed are generated during the initialization
of PXROS. 3[2SRRO,QVHUW1HZ2EM is used during the initialization of PXROS e.g. if
there is not enough memory in the system memory class available for all requested
objects. This service might also during run time if additional memory (e.g memory card)
becomes available which is also to be used for objects.

 8VLQJ'LIIHUHQW2EMHFW3RROVLQWKH6\VWHP

The use of several different real object pools serves essentially to protect critical
system functions. By dividing different parts of the system into cells, problems caused
by resource difficiency can be contained within certain parts of the application. Other
areas are then left unaffected. To avoid delays in receiving objects (waiting for
availability), resources for critical jobs should be taken from the system pool or from a
special real object pool.

Virtual object pools can also help protect critical functions from resource deficiency. For
example, a task must wait for an object because a virtual pool is empty but the source
is not. In this case, only object requests that can accept such delays should be sent to
such a pool. In most simple systems, only the system pool is normally used.

HighTec EDV-Systeme GmbH 93 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 2WKHU6HUYLFHV

PxUInt_t PxOpoolGetCurrentCapacity ( PxOpool_t opool )

PxOpoolType_t PxOpoolGetType ( PxOpool_t opool )

PxError_t PxObjGetName ( PxObj_t obj,


char *buffer,
PxSize_t bufsize )

PxError_t PxObjSetName ( PxObj_t obj,


char *name )

3[2SRRO*HW&XUUHQW&DSDFLW\ shows how many objects are resident in the object pool
RSRRO . 3[2SRRO*HW7\SH reports whether RSRRO is virtual or real.

Like tasks, objects can have names. These names serve to make identification easier
while debugging the application. These names can not be used to identify objects
within the application itself. The maximum length of the name is fixed during the
initialization of PXROS. The sizes of objects increase accordingly.

3[2EM6HW1DPH assigns the object REM the name QDPH. This name is saved within the
fixed length specified during initialization. In other words, QDPH is truncated if it is too
long. The name is not saved with a terminating zero if it exceeds the maximum length.
PXROS gives the system memory class and the system pool their names.

3[2EM*HW1DPH copies the name of a given object into the buffer EXIIHU. The size of

the buffer is reported in EXIVL]H If the name is longer then only EXIVL]H symbols are
copied.

3[*HW2EM1DPH and 3[6HW2EM1DPH both return PXERR_NOERROR if succesful. If


the name is too long, then the return value is PXERR_NAME_BUFOVERFLOW.

 ([DPSOHV

The source code for the following examples can be found in the directory RSRRO, on the
accompanying disk.

 H[F

7DVN first creates a real object pool. This serves as the source pool for a virtual object
pool that is generated by one of its objects. Delay objects are then requested from the
virtual object pool. The last request fails because the virtual object pool is empty, even
though the source pool itself is not empty.

HighTec EDV-Systeme GmbH 94 20. Mai 1996


PXROS V4 Users Guide Version 1.0
7DVN)XQF

PxOpool_t RealPool, VirtPool;


PxDelay_t Obj1, Obj2, Obj3;
PxError_t err;

(1) PxOpoolRequest (&RealPool, PXOpoolReal, 5,


PXOpoolSystemdefault,
PXOpoolSystemdefault);

(2) PxOpoolRequest (&VirtPool, PXOpoolVirtual, 2, RealPool,


RealPool);

for (;;)
{
(3) err = PxDelayRequest_NoWait (&Obj1, VirtPool);
(4) err = PxDelayRequest_NoWait (&Obj2, VirtPool);
(5) err = PxDelayRequest_NoWait (&Obj3, VirtPool);
(6) PxDelayRelease (&Obj1);
(7) PxDelayRelease (&Obj2);
}

GHWDLOHGSURFHVVGHVFULSWLRQ

7DVN generates a new real object pool.

(1) PxOpoolRequest (&RealPool, PXOpoolReal, 5,


PXOpoolTaskdefault,
PXOpoolTaskdefault);

5HDO3RRO contains 5 objects taken from the system pool. After creating the object pool,

the system pool contains IHZHUREMHFWV (i.e. five objects + one object pool). 9LUW3RRO, a
new virtual object pool containing two objects, is then requested from 5HDO3RRO.

(2) PxOpoolRequest (&VirtPool, PXOpoolVirtual, 2,


RealPool, RealPool);

5HDO3RRO now contains 4 objects (only 1 object taken for the object pool). In the
endless loop that follows, a delay object is requested three times from 9LUW3RRO ((3), (4)
and (5)). The first two requests are successful and the return value is
PXERR_NOERROR. Due to these requests, 5HDO3RROs capacity has dropped to two,
and 9LUW3RRO now has 0 objects available. Therefore

(5) err = PxDelayRequest_NoWait (&Obj3, VirtPool);

returns the error PXERR_OBJ_NOOBJ, and the two other requested delay objects are
released (6) and (7).

HighTec EDV-Systeme GmbH 95 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 H[F

This example attempts to create as many objects as possible from the memory field
PHP, and to place these in an object pool.

PxAligned_t mem[100];

7DVN)XQF

PxAligned_t *adr;
PxOpool_t Pool;
PxSize_t size;
PxError_t err;
PxUInt_t capacity;

(1) PxOpoolRequest (&Pool, PXOpoolReal, 1,


PXOpoolSystemdefault,
PXOpoolSystemdefault);
(2) adr = &mem[0];
(3) size = 100 * sizeof(PxAligned_t);
do {
(4) err = PxOpoolInsertNewObj (Pool, &adr, &size);
(5) } while(err == PXERR_NOERROR);

(6) capacity = PxOpoolGetCurrentCapacity (Pool);


for (;;);

GHWDLOHGSURFHVVGHVFULSWLRQ

Using

(1) PxOpoolRequest(&Pool, PXOpoolReal, 1,


PXOpoolSystemdefault,
PXOpoolSystemdefault);

7DVN generates a new real object pool, 3RRO


, which contains RQH object. DGU holds the
starting point of the memory block PHP

(2) adr = &mem[0];

and VL]Hcontains its size in bytes.

(3) size = 100 * sizeof(PxAligned_t);

Afterwards, a loop is used to convert memory into an object, which is then placed in the
object pool 3RRO.

(4) err = PxOpoolInsertNewObj(Pool, &adr, &size);

HighTec EDV-Systeme GmbH 96 20. Mai 1996


PXROS V4 Users Guide Version 1.0

With this function, DGU increases in size by one object, while VL]H is reduced by the size
of one object. Once the memory has been used up, 3[2SRRO,QVHUW1HZ2EM returns an
error and the loop is terminated (5). Afterwards, the object pools new capacity is finally
determined and saved in FDSDFLW\

(6) capacity = PxOpoolGetCurrentCapacity(Pool);

HighTec EDV-Systeme GmbH 97 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 ,QWHUUXSW,QWHUIDFH

void TrapInit ( void )

void TrapInstallChandler ( PxInt_t no,


void (*hnd) (PxArg_t),
PxArg_t arg )

void *TrapInstallChainedChandler ( PxInt_t no,


void (*hnd) (PxArg_t),
PxArg_t arg )

void TrapRemoveChainedChandler ( PxInt_t no,


void *achain )

The interrupt interface depends on the hardware used. PXROS provides services for
defining interrupt handlers. These services offer the application an interface
independent of hardware.

7UDS,QVWDOO&KDQGOHU defines the C-function KQG as an interrupt handler for the


interrupt with the number QR. When an interrupt occurs KQG is activated with the
parameter DUJ. The interrupt handler can be allocated to the interrupt source occurs
dynamically during run time, and can be later overwritten with the call
7UDS,QVWDOO&KDQGOHU.

7UDS,QVWDOO&KDLQHG&KDQGOHU allows one to chain a number of handlers together. In


other words, chained handlers are executed in succession once the specified interrupt
occurs. The parameters correspond to the parameters in 7UDS,QVWDOO&KDQGOHU. The
chained C handler function returns an Id for identifying the entry.
7UDS5HPRYH&KDLQHG&KDQGOHU removes an interrupt handler from the chain of
interrupt handlers. QR specifies its interrupt number. DFKDLQ is the Id returned if
7UDS,QVWDOO&KDLQHG&KDQG was successful.

Before using TrapInstallChandler or TrapInstallChainedChandler the interrupt interface


must be preinitialized. This is usually accomplished by calling 7UDS,QLW. These
preparations are dependent on the target processor (see chapter 18).

When this interrupt interface is used, functions can be chosen and used as interrupt
service routines. With this in mind, when the interrupt occurs, preparations must be
made before the execution of the routine. One must take care not to increase the
interrupt latency time unnecessarily. For example, not every interrupt handler requires a
register bank or a stack. Also, at times it is possible to start an interrupt handler as the
application is created. TrapInstallChandler is not always the optimum method,
especially when high frequency interrupts are used and should only be allowed to run
for a short time period. In such cases, the interrupt interface should be created
statically. This is done by using certain macros as the function is defined.

HighTec EDV-Systeme GmbH 98 20. Mai 1996


PXROS V4 Users Guide Version 1.0

The modules containing the functions for the trap interface are not distributed in the
PXROS library. These modules are delivered separately (as source code) since it is
usually necessary to modify the trap interface to the target hardware. Specifically, they
must be configured, translated, and linked to the target hardware. Descriptions of these
modules are found in the individual modules, as well as in their header files, which also
contain a description for the static definition of the interrupt routine.

If certain routines are specified as interrupt handlers without using the function
described above (i.e. assembly routines), they must ensure that the function saves the
processor context before using the processor, and restores it when exiting. If function
calls are used, the function must also make sure there is room on the stack.

HighTec EDV-Systeme GmbH 99 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 (UURU+DQGOLQJ

 6XPPDU\

PXROS provides two different error handling services. Errors are seperated into two
classes, and PXROS handles each class differently:

5XQWLPH HUURUV are one type of error common to many PXROS applications. A lack of
resources is an example a runtime error. This is usually noted in the services return
value.

The second of errors, DSSOLFDWLRQ HUURUV, can generally be traced to the improper use of
the services. For example, attempting to use a service with the wrong object type will
cause an application error. These errors can be caught through the additional tests
performed in the PXROS debug library. PXROS does not warn of these errors with a
return value; instead, PXROS calls 3[0HVVDJH. This service activates an error
function that reacts in accordance with the severity of the error.
3[0HVVDJH)XQ'HIDXOW is the standard PXROS error function; however, PXROS

allows one to install a customized error function. When debugging a PXROS


application, the developer is advised to define a breakpoint at the error function. In this
way, every error that PXROS registers with the debug library causes the program to
stop once it reaches the breakpoint. The error can then be examined and corrected.

 5XQWLPH(UURUV

PxError_t PxGetError ( void )

void PxSetError ( PxError_t err )

Run time errors occur during normal usage. Most runtime problems are related to
resource requests, and are reported in the calling services return value. Ignoring a
reported error can lead to even more severe problems. For example: if a request for an
object fails and is not noticed, an illegal object Id may be sent to a PXROS service.

In addition to reporting an error in the return value, PXROS saves the last error that
occurred in each task. 3[*HW(UURU shows the calling tasks last saved error. The
application is allowed to change the saved error value. Once an error is removed,
PXERROR_NOERROR is usually written to this value to avoid confusion from reports
of an old error. The call 3[6HW(UURU HUU sets the error value to HUU

All errors of this type are registered by both the PXROS production library and the
debug library. This allows the application to react dynamically to runtime errors.

HighTec EDV-Systeme GmbH 100 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 $SSOLFDWLRQ(UURUV

void PxMessage ( PxMessageClass_t class,


PxError_t err, ... )

void PxMessageFunDefault ( PxMessageClass_t class,


PxError_t err, ... )

void PxPanic ( void )

void PxCtrl ( PXCtrlSetMessageFun,


void(*fun) (PxMessageClass_t,
PxError_t,...) )

Application errors occur when services are used incorrectly. These errors are only
detected by additional tests performed in the PXROS debug library. For example, the
debug library notices when a tasks stack overflows, or e.g. if an object Id of the wrong
type is passed to a service.

These errors are sometimes the result of unnoticed or ignored run time errors. If, for
example a message request is unsuccesful, the variable for the message Id is  If a
service with this Id is called, this causes an application error because the Id does not
represent a message.

When such an error occurs, PXROS calls 3[0HVVDJH FODVV HUU  . This service
reports the error with the systems error message function. The error message function
is sent the type of error in FODVV, and the error code HUU. It can also receive additional,
user-specified parameters. FODVV is assigned one of the values: 3;:DUQLQJ, 3;(UURU or
3;)DWDO.

3[0HVVDJH)XQ'HIDXOW is the default PXROS error message function. This function


calls 3[3DQLF whenever a 3;)DWDO FODVV HUURU RFFXUV 3[3DQLF XVXDOO\ JHQHUDWHV
HLWKHU D EUHDNSRLQW LQVWUXFWLRQ RU DQ LOOHJDO LQVWUXFWLRQ 7KLV FDXVHV D PRQLWRU WR EH

DFWLYDWHG 7KH DSSOLFDWLRQ LWVHOI FDQ DOVR DWWHPSW WR UHDFW 3[0HVVDJH)XQ'HIDXOW

DOZD\V LJQRUHV HUURUV RI WKH FODVV 3;:DUQLQJ 3;(UURU FODVV HUURUV DUH LJQRUHG ZKHQ

IRXQG LQ WKH SURGXFWLRQ OLEUDU\ KRZHYHU LQ WKH GHEXJ OLEUDU\ WKLV FODVV RI HUURU FDXVHV

DFDOOWR3[3DQLF

By calling 3[&WUO, the application can define a customized error message function. The
first parameter PXVW have the value 3;&WUO6HW0HVVDJH)XQ . The application can also
activate this function by calling 3[0HVVDJH.

 ([DPSOH

The source code for this example can be found in the directory HUURU on the
accompanying disk.

HighTec EDV-Systeme GmbH 101 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 H[F

Task 1 defines a custom error message function, 0\(UURU0HVVDJH)XQF and initially


calls it with a warning. A run time error is then introduced, followed by an application
error. This causes a fatal error, at which point PXROS activates the error message
function.

0\(UURU0HVVDJH)XQF 3[0HVVDJH&ODVVFODVV3[(UURUBWHUU

static PxULong_t warning, error;

if (class == PXWarning)
(1) warning++;
else
if (class == PXError)
(2) error++;
else
(3) PxPanic ();

7DVN)XQF

(4) PxCtrl (PXCtrlSetMessageFun, MyErrorMessageFunc);


(5) PxMessage (PXWarning, -1);

(6) PxMcRequest (&mc, PXMcVarsized, 0,


PXOpoolSystemdefault);
(7) err = PxGetError

(8) PxMsgRequest (&msg, 100, mc, PXOpoolSystemdefault);


(9) err = PxGetError ();

(10) PxMsgSend (&msg, PxTaskGetMbx (Task2Id));

for (;;);

GHWDLOHGSURFHVVGHVFULSWLRQ

(4) PxCtrl (PXCtrlSetMessage Fun,


MyErrorMessageFunc);

7DVN defines the custom error message function: 0\(UURU0HVVDJH)XQF. This counts
all warnings and errors ((1) and (2)), and stops the system with a call to 3[3DQLF (3)
whenever a fatal error occurs. The message function is activated by calling:

(5) PxMessage(PXWarning, -1);

This contains a warning and the error code -1. Afterwards, the application requests a
new memory class PF (6). The error variable is not assigned the requests return value;
rather, it is given the last error saved for the task:

(7) err = PxGetError();


HighTec EDV-Systeme GmbH 102 20. Mai 1996
PXROS V4 Users Guide Version 1.0

The new memory class is not allocated any memory. The application attempts to create
the following message:

(8) PxMsgRequest(&msg,100,mc,PXOpoolSystemdefault);

This call fails, and again the error is assigned the last error reported by 3[*HW(UURU (9).
The task ignores the error and

(10) PxMsgSend (&msg, PxTaskGetMbx (Task2Id));

tries to send a message; however, since no message could be created (8), PVJ is an
illegal message Id. PXROS treats this as fatal application error and activates the error
message function with the error class 3;)DWDO. 0\(UURU0HVVDJH)XQF then stops the
system by calling 3[3DQLF (3).

HighTec EDV-Systeme GmbH 103 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 6FKHGXOLQJ

 6XPPDU\

PXROS is a PXOWLWDVNLQJ operating system. In other words, using several tasks allows
PXROS to run several operations simultaneously. These make up the lions share of
the functions implemented with PXROS. In addition to tasks (and PXROS itself),
KDUGZDUH LQWHUUXSW KDQGOHUV allow an application to react to external processor

interrupts. PXROS also provides services for activating the so-called VRIWZDUH LQWHUUXSW
KDQGOHU.

The operating system decides which code is executed. PXROS uses SUHHPSWLYH
SULRULW\EDVHGVFKHGXOLQJ to determine exactly when the various jobs are processed.

The principle behind this


mechanism is that system Priorities
components with a higher priority
can always run by interrupting
components with a lower priority. Hardware Interrupt Handler
(Mutually interrupting based on their respective interrupt priorities)
Modules with a lower priority
FDQQRW interrupt those with a higher

priority, which execute their code Software Interrupt Handler


(do not interrupt one another)
and then relinquish control of the
processor. The highest priority is Tasks
given to the hardware interrupt (mutually interrupting based on their respective task priorities)
handlers, followed by PXROS itself
and software interrupt handlers.
Tasks have the lowest priority in a
PXROS system. Each task is assigned a priority relative to the other tasks.

 +DUGZDUH,QWHUUXSW+DQGOHUV

An application specifies KDQGOHU URXWLQHV to respond to individual hardware interrupts


(see chapter 11). When an interrupt occurs, it immediately interrupts any other
procedure to call the assigned handler routine. Once the handler has been processed,
the previous procedure can resume executing its code at the point it left off at.

On some processors, hardware interrupts can also be given priorities relative to one
another. PXROS uses this hierarchy, thus allowing high priority handlers to interrupt
handlers with a lower priority.

PXROS never disables the interrupt system. Also, the operating system does not affect
how the processor handles its interrupts. Basically the processors interrupt latancy is
dependent on how the interrupt handlers are installed (see chapter 11).

HighTec EDV-Systeme GmbH 104 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 6RIWZDUH,QWHUUXSW+DQGOHUV

Basically, software interrupt handlers are either GHOD\ KDQGOHUV (see chapter 8.4) or
PDLOER[ KDQGOHUV. They can interrupt any task, but they may also be interrupted by any

hardware interrupts that occur while they are running. Software interrupt handlers are
not assigned priorities, and therfore do not interrupt one another. When two or more
software interrupt handlers are called simultaneously, they are processed sequentially.

 7DVN6FKHGXOLQJ

Tasks are scheduled according to their respective WDVN SULRULWLHV. Each task is given a
priority when it is created. This can be changed dynamically with a special PXROS
service. The tasks priority only controls its scheduling in relation to other tasks. If a
handler is activated, any active task is interrupted immediately.

Zero (0) is the highest possible priority a task can have. The lowest possible task
priority depends on the processor used, as well as the version of PXROS used.
Normally the lowest priority is 15 or 31. PXROS does not schedule a task based on the
absolute value of its priority; rather, scheduling is based on the relative priorities
between tasks.

In addition to its priority, the tasks status plays a role in scheduling. Tasks are
generally considered to be in one of two possible states: ZDLWLQJ or UHDG\. All ready
tasks compete to become active, whereas tasks in the wait state remain dormant until
something occurs to make them active. Tasks in the ready state execute their code in
the order of their respective priorities (i.e. highest to lowest).

Under the following conditions, a task will relinquish processor control to another task:

The task calls a PXROS service that places it in a wait state.

A task or a handler calls a PXROS service that places a task with a higher
priority into a ready state (i.e. the task was in a wait state) .

Using the relevant PXROS service, the active task sets its own priority lower
than that of another ready task. Alternatively, the active task could set
another ready tasks priority higher than it own.

HighTec EDV-Systeme GmbH 105 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 7DVNVRI(TXDO3ULRULW\

If a number of tasks with equal priorities are ready at the same time, the task that has
been ready for the longest time is activated first. The remaining tasks are processed on
a "first come, first served basis". When a ready tasks priority is dynamically changed,
the task is treated as if it were temporarily in a wait state and then became ready. In
other words, the task does not become activate until all other ready tasks at the new
priority level have been processed (i.e. those that have been waiting longest). Of
course the new priority level can always be interrupted by ready tasks with a higher
priority.

 6SHFLDO7\SHV

Processing time plays no role in deciding which task becomes active. In addition to the
tasks priorities, the PXROS-Plus-version allows to schedule tasks with a WLPH VOLFLQJ
process. This process is explained in chapter 19.3.

 ([DPSOH

All examples in the Users Guide describe which tasks and handlers are active. For this
reason, no example was provided to demonstrate the scheduling mechanism
idividually.

HighTec EDV-Systeme GmbH 106 20. Mai 1996


PXROS V4 Users Guide Version 1.0

HighTec EDV-Systeme GmbH 107 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 &UHDWLQJ7DVNV

PxError_t PxTaskCreate ( PxTask_t *TaskId,


PxTaskSpec_t ts )

Chapter 3.1 demonstrated how tasks can be created with the function &UHDWH6WGWDVN.
This function offers applications a comfortable interface for creating tasks. When tasks
are created with this service, some parameters are set to default values, which is not
always acceptable. This chapter explains the actual process of creating a task creation.

Task-Create
Tasks are created with the service 3[7DVN&UHDWH. The parameter WV contains the
address of a structure of the type 3[7DVN6SHFB7. This structure is used to configure
the new task. The remainder of this chapter describes the individual attributes of this
configuration structure. It also explains how to chose suitable values for the various
attributes.

typdef struct
{
PxUChar_t *ts_name;
void (*ts_fun) (PxTask_t, PxMbx_t, PxEvents_t);
PxMc_t ts_mc;
PxOpool_t ts_opool;
PxStackSpec_T ts_taskstack;
PxSize_t ts_tblimit;
PxUChar_t ts_prio;
PxEvents_t ts_actevents;
PxTicks_t ts_timeslices;
PxAbortFrame_t ts_abortstack;
PxSize_t ts_abortstacksize;
PxTaskSchedExt_t ts_sched_extension;
PxArg_t ts_sched_initarg;
PxArg_t ts_privileges;
PxUInt_t ts_int_dummies[ ];
PxTaskContext_T *ts_context;
PxDataAddr_t *ts_addr_dummies[ ];
} PxTaskSpec_T, *PxTaskSpec_t;
If 3[7DVN&UHDWH is successful, 7DVN,G contains the new tasks task Id. If the service

HighTec EDV-Systeme GmbH 108 20. Mai 1996


PXROS V4 Users Guide Version 1.0

fails, 7DVN,G is set to 0, and the return value provides information as to why the task
was not created.

 WVBQDPH

WVBQDPH is the name given to the task. It is used to help debug the application and can

not be used for identifying tasks within the program.

 WVBIXQ

The function, WVBIXQ, contains the new tasks code. This does have certain restrictions,
e.g. the function must have a defined prototype. Details are given in chapter 3.2.

 WVBPF

When memory is requested for any purpose, one must always specify the memory
class from which the memory is taken. Selecting the memory class often depends on
how important the request is within the application as a whole. If an application
provides several different memory classes, important requests should be directed to
their own exclusive memory class, or to the system memory class. This increases the
probability that the memory pool will have enough memory to satisfy the request.
Requests that are not as important tend to be directed to a memory class that is
provided for general use. At times, this may be unable to meet all requests.

Determining which memory requests are important generally depends on the


importance of the requesting task within the application as a whole. To make this
determination, each task can be allocated a GHIDXOW PHPRU\ FODVV based on its
importance. This memory class is entered into WVBPF when the task is created. The
task default can either be the system memory class or a new memory class that is
created at run time.

HighTec recommends that tasks direct their normal memory requirements to this task
default by specifying 3;0F7DVNGHIDXOW. If the task changes its meaning, the memory
class need only be adjusted when it is created. Regardless of the tasks importance,
only truly important requests should specify the memory class (or the Id of a special
memory class) directly.

The call &UHDWH6WGWDVN (chapter 3.1) automatically sets WVBPF as 3;0F7DVNGHIDXOW.


This means that the calling task inherits this memory class. The advantages to using
different memory classes is described in chapter 7.4.

HighTec EDV-Systeme GmbH 109 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 WVBRSRRO

The application must always specify the object pool from which a requested object
should be taken. This often depends on the importance of the request within the
application as a whole. If a number of object pools are available, important requests are
usually directed to a real object pool set up specifically for such requests, or to the
system pool. This increases the probability that an object will be provided in a timely
manner. Less important requests are usually directed to virtual object pools that are
provided for general use.

For the most part, the importance of an object request is related to the importance of
the requesting task. To make this work, a task is allocated a GHIDXOW REMHFW SRRO that
correspond to its importance. This object pool is set in the attribute WVBRSRRO when the
task is created. The task default can either be the system pool or an object pool
generated at run time.

HighTec recommends that all tasks direct their object requests to this default pool by
specifying 3;2SRRO7DVNGHIDXOW. If the meaning of a task changes, its object pool need
only be changed at the time of the tasks creation. Regardless of the tasks importance,
only truly important requests should take objects from the system pool or a specific real
object pool.

&UHDWH6WGWDVN (chapter 3.1) sets ts_opool to the value 3;2SRRO7DVNGHIDXOW. This

means that the calling tasks object pool is inherited by the request. The advantages of
using different object pools is described in chapter 10.1.

 WVBWDVNVWDFN

Every task has its own stack, the configuration of which is defined by the structure
3[6WDFN6SHFB7 :

typedef struct
{
PxStackSpecType_t stk_type;
PxSize_t stk_size;
void *stk_src;
} PxStackSpec_T, *PxStackSpec_t;

There are two methods with which a task can be assigned a stack. While the task is
being created, memory is automatically requested for the stack. Alternatively, a task
may be given its task stack explicitely (i.e. an available memory area). These options
are explained in the following paragraphs. The init tasks stack is an exception. This is
explained in section 14.16.

HighTec EDV-Systeme GmbH 110 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 $XWRPDWLF6WDFN5HTXHVW

This is the normal way to give a stack to the task. The stacks structure is set as
follows: VWNBW\SH receives the value 3;6WDFN$OORF. The stack size is given as the
number of LQWHJHUV in the parameter VWNBVL]H. VWNBVUF specifies the memory class that
allots memory to the stack.

The task creation function, &UHDWH6WGWDVN (chapter 3.1), creates the stack in this way,
using memory from the system memory class.

 ([SOLFLW6WDFN$OORFDWLRQ

If a free area of memory is specified for stack, the structures attributes should be set
as follows: VWNBVL]H contains the size of the available memory (this is the amount of
LQWHJHUV). VWNBVUF is given either the start or end address of the memory area. If the

start address is given, then VWNBW\SH must have the value 3;6WDFN*URZ. Conversely, if
the end address is given, VWNBW\SH must be given the value 3;6WDFN)DOO.

PXROS checks for stack overflow regardless of how the stack was created. For
backwards compatibility with earlier PXROS versions, one can forgo these tests if the
memory for the stack is already available. To do this, the stack should be configured as
follows:

VWNBVL]H is given the value 3;6WDFN'RQW&KHFN The memory address in VWNBVUF


depends on the processor used, i.e. whether the address of the stack becomes smaller
or bigger as the stack grows. When the address increases in value, VWNBW\SH is
specified as 3;6WDFN*URZ. If the address decreases, VWNBW\SH must is given the value
3;6WDFN)DOO In both cases, VWNBVUF contains the address at which the stack should

begin, i.e. the memory areas lowest address for growing tasks, or the memory areas
highest address for falling stacks. Whichever the case, the prossesors alignment
should be taken into account.

The option to not check the stack should only be used in exceptional circumstances.

 &KRRVLQJD6WDFN6L]H

Determining the stack size dependends on the tasks code: e.g. every function within a
nested call increases the demands on the tasks stack. In this scenario, not only the
functions prologue, but all local variables and (in some cases) parameters are placed
on the stack. This can make it quite difficult to estimate the stacks needs when starting
a new application.

HighTec EDV-Systeme GmbH 111 20. Mai 1996


PXROS V4 Users Guide Version 1.0

If the chosen stack is too small, difficult to locate run time errors may occur as unknown
memory areas are written to. Although PXROS debug library tests every call to PXROS
services for stack overflow, it cannot guarantee every such instance will be registered.
HighTec recommends generosity when choosing the stacks size (assuming there is
enough memory available to the system). At the end of the development phase, the
system can always be optimized. With the realtime monitor, PXmon, a tasks maximum
requirements can be determined, and the stack size can be adjusted accordingly.

 WVBWEOLPLW

WVBWEOLPLWspecifies the maximum amount of memory that a task can use for messages.
This can be seen as a sort of memory account that a task uses to control its use of
memory. When 3[0VJ5HTXHVW (see chapter 5.2) is called to request a message, the
size of the messages data area is subtracted from the tasks memory account. When
the message is released, this amount is deposited back in the account.

If the "memory account" does not contain enough "credits", 3[0VJ5HTXHVW is


unsuccessful. In effect, the account can not be overdrawn. The return value
PXERR_MSG_TBLIMIT reports this error.

This limit cannot be turned off. If WVBWEOLPLW is 0, the task cannot request a message with
PxMsgRequest. If WVBWEOLPLW is -1 (= 0xfff..), the limit would have practically no influence,
because this is a relatively high value.

The memory limit helps ensure that a task does not use up all available memory for
messages. This can happen if messages are repeatedly sent and received, but are not
in turn released by the receiver. This can occur e.g. at the beginning of the
development phase when the application still contains errors. Applications can also be
protected from "memory gluttons" by using multiple memory classes (see chapter 7.4).
Excessive memory use can be easily located with the help of the realtime monitor
PXmon.

The task creation function, &UHDWH6WGWDVN (chapter 3.1), sets WVBWEOLPLW to -1.

 WVBSULR

WVBSULR defines the tasks priority. The highest possible priority is always , and the
lowest depends on the processor and the PXROS variant used. On most processors,
this value is usually  or . PXROS only uses relative values of the task priorities to
schedule tasks; their absolute values are not really important. No firm rules apply to
assigning task priorities, although the following guidelines should help: Tasks with a
small buffer, time critical tasks, tasks close to the hardware, and tasks that service
other tasks generally receive a high priority. Tasks that perform duties unrelated to the
hardware usually receive lower priorities. These include data evaluation tasks, tasks
that run displays and ROM checks.

HighTec EDV-Systeme GmbH 112 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 WVBDFWHYHQWV

Normally a task starts UHDG\ to execute its code. Once a task is created, it can be given
an activating event, which causes it to ZDLW until the activating event is signalled.
WVBDFWHYHQWV holds the tasks activating events mask.

The task creation function, &UHDWH6WGWDVN (chapter 3.1) sets WVBDFWHYHQWV to 0. This
means that the task is ready immediately after creation.

 WVBWLPHVOLFHV

PXROS normally allocates control over the processor based on a tasks priority and
status. Some versions of PXROS provide timeslicing as an additional scheduling
mechanism. It is described in chapter 19.3. WVBWLPHVOLFHV sets the numer of 3;526
WLFNV that make up a time slice. If WVBWLPHVOLFH is , the default is applied to the task, i.e

the task does not participate in the time-slicing procedure.

The task creation function, &UHDWH6WGWDVN (chapter 3.1) sets WVBWLPHVOLFHV to 0.

 WVBDERUWVWDFNWVBDERUWVWDFNVL]H

These two attributes are only needed if the task uses the abort mechanism (see
3[([SHFW$ERUW as described in chapter 17). If this service is not used, WVBDERUWVWDFN

and WVBDERUWVWDFNVL]H can be set to 0. Tasks created with &UHDWH6WGWDVN can not use
the the abort mechanism since the standard task creation function sets both values to
0.

3[([SHFW$ERUW calls a function that is interrupted if certain events occur. PXROS


saves the context on the DERUW VWDFN before the function is called. When the calling task
resumes execution, its context must be restored. Each time the context is saved, a
definite amount of memory is required (i.e. an abort frame). Every nested call to
3[([SHFW$ERUW increases this amount by one abort frame. The size of an abort frame

is processor dependent. It can be determined with 3[*HW$ERUW)UDPH6L]H.

The abort stack must be provided when a task is created. WVBDERUWVWDFNVL]H sets the
size of the abort stack and contains the number of abort frames available on the abort
stack. The maximum number of nested calls to 3[([SHFW$ERUW is equal to the number
of abort frames.

The abort stack "falls" and is decremented before a value is saved on the stack.
WVBDERUWVWDFN holds the first address after the provided memory area. The processor

dependent alignment must be taken into account.

HighTec EDV-Systeme GmbH 113 20. Mai 1996


PXROS V4 Users Guide Version 1.0

([DPSOH

fun1()
{
...
PxExpectAbort (EV_ABORT2, fun2);
...
}

fun2()
{
/* no PxExpectAbort */
}

TaskFunc()
{
...
PxExpectabort (EV_ABORT1, fun1);
...
}

main()
{
PxTaskSpec_T ts;
PxUChar_t *adr;
PxSize_t size;
....
/* Task initialization */
...
size = 2*PxGetAbortFrameSize();
PxMcTakeBlk(PXMcSystemdefault, (PxAligned_t **) &adr,
size);
ts.ts_abortstacksize = 2;
ts.ts_abortstack = (PxAbortFrame_t) &adr[size];
...
}

The task 7DVN)XQF contains two nested calls to 3[([SHFW$ERUW. This means two abort
frames are required, thus WVBDERUWVWDFNVL]H must have a minimum value of 2. The abort
stack is requested from the system memory class dynamically, thus

size = 2*PxGetAbortFrameSize()

bytes are required, beginning at the address DGU. The first address after the memory
area is DGU>VL]H@. Therefore, WVBDERUWVWDFN must be set to DGU>VL]H@.

HighTec EDV-Systeme GmbH 114 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 WVBVFKHGBH[WHQVLRQWVBVFKHGBLQLWDUJ

Special versions of PXROS allow user-defined, task-specific functions to be executed


whenever a task is activated and/or deactivated. These functions must be entered in a
structure of the type 3[7DVN6FKHG([WB7. WVBVFKHGBH[WHQVLRQ contains the address of
this structure, and WVBVFKHGBLQLWDUJ holds a parameter for the scheduling extensions
initialization function. Details about this structure and its configuration are given in
chapter 19. This service is not used with the function &UHDWH6WGWDVN.

 WVBSULYLOHJHV

This attribute is not described here and should be set to .

 WVBLQWBGXPPLHV

These attributes are reserved for future extensions and should be set to .

 WVBFRQWH[W

This attribute is extremely processor dependent and is described in detail in chapter 18.

 WVBDGGUBGXPPLHV

These attributes are reserved for future extensions and should be set to .

 )HDWXUHVRIWKH,QLWLDOL]DWLRQ7DVN

When setting the attributes of initialization tasks configuration structure, consider the
following features: the attribute WVBIXQ is not interpreted; instead, this function is
assigned the task code from which 3[,QLW is called. WVBPF must specify the system
memory class, and WVBRSRRO must refer to the system pool. WVBDFWHYHQWV has no
meaning for the init task.

The initialization of the task stack is also quite different compared to "normal". The
initialization task uses the programs user stack. The application configures this either
with the linker while the program is generated, or during the startup phase.

If the linker is used to configure the user stack, the following macros (defined in
S[GHIK) are recommended for setting the attribute WVBWDVNVWDFN:

HighTec EDV-Systeme GmbH 115 20. Mai 1996


PXROS V4 Users Guide Version 1.0

ts_taskstack.stk_type =3;3URF*HW,QLWVWDFN6SHFW\SH
ts_taskstack.stk_size = 3;3URF*HW,QLWVWDFN6L]H
ts_taskstack.stk_src = 3;3URF*HW,QLWVWDFN6WDUW

This setup allows PXROS to uses processor specific information to recognize stack
overflow (if possible). These macros may require the declaration of certain external
variables, which can be accomplished with the macro 3;3URF,PSRUW,QLWVWDFN (also
defined in S[GHIK).

If the user stack is configured by an application specific startup, these entries should be
provided as described for creating "normal" task (see section 14.5.2).

([DPSOH

#include "pxdef.h"

...
PXProcImportInitstack;
...

main()
{
PxInitSpec_T is;
PxTaskSpec_T ts;

/* occupation of the initialization


tasks configuration structure */
PxBzero((PxUChar_t *) &ts, sizeof(PxTaskSpec_T));
....
ts.ts_mc = PXMcSystemdefault;
ts.ts_opool = PXOpoolSystemdefault;
ts.ts_taskstack.stk_type = PXProcGetInitstackSpectype;
ts.ts_taskstack.stk_size = PXProcGetInitstackSize;
ts.ts_taskstack.stk_src = PXProcGetInitstackStart;
....
is.is_inittask = &ts;
....
/* PXROS initialization */
PxInit(&is)
...
}

 ([DPSOH

The function %VS,QLW serves as a good example for the information described this
chapter. %VS,QLW is used to initialize PXROS, and it creates the tasks used in all of the
example programs contained in the Users Guide.

HighTec EDV-Systeme GmbH 116 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 3;526,QLWLDOL]DWLRQ

 $6WDQGDUG,QLWLDOL]DWLRQ

At the beginning of every application, PXROS must initialized with a number of


parameters. For most applications, only a few of these parameters are important. For
this reason, PXROS offers the function VWG,QLW. VWG,QLW assumes all processes required
to initialize PXROS. It only requires a few specific parameters, otherwise default values
are used. The service VWG,QLW is not distributed with the PXROS standard package, and
can be obtained in source form.

PxTask_t stdInit ( PxUInt_t objno,


PxAligned_t *firstblk_start,
PxSize_t firstblk_size,
char *name,
PxUChar_t prio )

During initialization, PXROS creates a stock of objects and one task. The memory
required to create these object must be reserved on the target system. The parameter
ILUVWEONB VWDUW specifies the starting address of this memory block, and ILUVWEONBVL]H

indicates its size. During initialization, the V\VWHP PHPRU\ FODVV is generated, and the
allocated memory is assigned to this memory class. At run time, the application can
dynamically use the remaining memory (i.e. that not used to create the task and objects
during initialization) for memory requests, or to create objects and tasks. If PXROS is
given too little memory, resource requests made at run time could fail.

The easiest way to allocate memory is to define a global array of the type 3[$OLJQHGBW.
The size of this array should correspond to the entire amount of memory that PXROS
will manage. ILUVWEONBVWDUW must contain the arrays starting address. This method can
not always be used (e.g. c16x large model); however, one should chose the data type
PxAligned_t, which recognizes potential processor dependent alignments when
memory is requested. At run time, additional physical memory can be added to the
system memory class with 3[0F,QVHUW%ON.

([DPSOH

#define SYSMEMSIZE
(9000 + sizeof (PxAligned) - 1) / sizeof (PxAligned)
/* size in PxAligned units */
PxAligned_t Sysmem[SYSMEMSIZE];

During initialization, a stock of objects is created. REMQR defines the number of objects
that are created and added into the system pool. The memory required to create the
object pool, as well as the objects it contains, is taken from the system memory class.

HighTec EDV-Systeme GmbH 117 20. Mai 1996


PXROS V4 Users Guide Version 1.0

The amount of objects required is equivalent to the maximum number of objects that
must exist DW WKH VDPH WLPH during the course of the application. This amount is always
selected on extremely application-dependent creiteria. Until more is known, REMQR
should be set generously, provided enough memory is available for the system memory
class. In this way one avoids run time problems caused by insufficient objects. At the
end of the development phase, the object requirements can be monitored at run time
with the realtime monitor PXmon. REMQR can then be optimized using this information.
Two more objects are created during PXROS initialization: the system memory class
and the system pool.

Afterwards, the LQLWLDOL]DWLRQ WDVN is created. Its task code is the program code through
which the PXROS initialization was called. Like every other task, the initialization task is
assigned a specific priority. This is set by in the value SULR.

Every task may receive an individual name. The initialization tasks name is defined in
QDPH. This value is only used to help debug an application, i.e. when using PXmon, it

can not be used to identify the task within the application.

Once PXROS has been successfully initilized, VWG,QLW returns initialization tasks task Id;
otherwise, it returns a . In addition to initializing PXROS, other important components
are initialized within VWG,QLW, e.g. the system clock is started. This service is not dealt
with in this chapter.

 ,QLWLDOL]DWLRQ'HWDLOV

PxTask_t PxInit ( PxInitSpec_t is )

PXROS is initialized with the service 3[,QLW. The parameter LV contains the address of a
structure of the type 3[,QLW6SHFB7, with which PXROS is configured. The following
sections describe this structures individual attributes. For example, these sections
explain how to select appropriate values for the various attributes. A standard, project-
specific initialization can be implemented with the function VWG,QLW, and used during the
development of the application. If errors occur, 3[,QLW returns a ; otherwise it returns
the initialization tasks task Id.

typedef struct
{
PxMcType_t is_sysmc_type;
PxSize_t is_sysmc_size;
PxAligned_t *is_sysmc_blk;
PxSize_t is_sysmc_blksize;
PxUInt_t is_obj_number;
PxUInt_t is_obj_namelength;
PxTaskSpec_t is_inittask;
PxInt_t is_monitoring;
PxInt_t is_int_dummies[ ];
PxGlobalSchedExt_T *is_schedext;
PxDataAddr_t *is_addr_dummies[ ];
} PxInitSpec_T, *PxInitSpec_t;

HighTec EDV-Systeme GmbH 118 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 LVBV\VPFBW\SHLVBV\VPFBVL]H

Memory reserved for PXROS on the target system, is allocated to the system memory
class, wich is usually a memory class of YDULDEOH block size. For this reason,
LVBV\VPFBW\SH usually holds the value 3;0F9DUVL]HG, and LVBV\VPFBVL]H is
meaningless. This value is only used in exceptional cases in wich the system memory
class may have different type. These exceptions are not dealt with the Users Guide.

 LVBV\VPFBEONLVBV\VPFBEONVL]H

The attributes LVBV\VPFBEON and LVBV\VPFBEONVL]H correspond to the parameters


ILUVWEONBVWDUW and ILUVWEONBVL]H as described for the standard VWG,QLW.

 LVBREMBQXPEHULVBREMBQDPHOHQJWK

The attributes LVBREMBQXPEHU corresponds to the parameter REMQR in the service


VWG,QLW.

Objects, like tasks, can receive names. Object names are also only used to help debug
an application, and cannot be used for identification. LVBREMBQDPHOHQJWK specifies the
maximum name length, and the size of each object increases accordingly. For this
reason, only the debug library allows one to name objects. LVBREMBQDPHOHQJWK is
therefore meaningless to the production library.

6WG,QLW sets LVBREMBQDPHOHQJWK to .

 LVBLQLWWDVN

When PXROS is started, the initialization task is created automatically. Like every other
task, it must be configured. This is done via a structure of type 3[7DVN6SHFB7.
LVBLQLWWDVN holds the address of this structure. This structures attributes, and the

specifics of an init task are described in chapter 14.16.

HighTec EDV-Systeme GmbH 119 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 LVBPRQLWRULQJ

LVBPRQLWRULQJ regulates which additional monitoring job PXROS supports. Currently, the

following options are available:

3;0RQLWRU0HPRU\

During the development of an application, run time problems can be caused


by a lack of memory. If the memory blocks used by the tasks are known,
searching for errors can be made easier. For example, one can recognize
when requested memory blocks are lost because they were not correctly
released after being used.

When PXMonitorMemory is specified, PXROS notes the variable sized


memory classes used to request memory blocks, as well as the requesting
task. In this way, Pxmon can monitor the applications use of memory.

This service increases the memory management overhead by three pointers


and one integer for each block. The additional time required to monitor the
memory usage is negligeable.

3;0RQLWRU1HZV7DVNV

This service reports the creation of a task to the debugger. The realtime
monitor, Pxmon-RT require this information for debugging in realtime.

These values can be bitwise ored into LVBPRQLWRULQJ. Not all services are available in
every version of PXROS. Because monitoring is an application specific service, VWG,QLW
sets LVBPRQLWRULQJ to .

 LVBLQWBGXPPLHV

These attributes are reserved for future extensions and should be set to .

 LVBVFKHGH[W

With every task change, PXROS can execute user-defined functions.These functions
are provided in a structure of the type 3[*OREDO6FKHG([WB7. LVBVFKHGH[W contains the
structures address. This attribute is described in detail in chapter 19.1. Usually this
service is only available in the PXROS debug library. VWG,QLW does not use this attribute.

HighTec EDV-Systeme GmbH 120 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 LVBDGGUBGXPPLHV

These attributes are reserved for future extensions and should be set to .

 ([DPSOH

The function %VS,QLW serves as a good example for the information described this
chapter. %VS,QLW is used to initialize PXROS, and it creates the tasks used in all of the
example programs contained in the Users Guide.

HighTec EDV-Systeme GmbH 121 20. Mai 1996


PXROS V4 Users Guide Version 1.0

HighTec EDV-Systeme GmbH 122 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 &RPPRQ7DVN'DWD

PxArg_t PxGetAppinfo ( void )

void PxSetAppinfo ( PxArg_t info )

With PXROS, an application can store task-specific data and retrieve it globally. The
call 3[6HW$SSLQIR LQIR writes this task-specific data to LQIR. 3[*HW$SSLQIR is used to
read the stored information later.

For example, this feature can be used to provide a task with a special identifier that
must be given when connecting to a server. This identifier can be passed as a
parameter from deeply nested functions. It could also be saved task-globally, thus
giving every service function access to the identifier as needed.

([DPSOH ZLWKRXWXVLQJWDVNVSHFLILFGDWD

TaskFun()
{
PxInt_t Id;
....
ServerOpen (&Id, ...);
....
Service1 (Id, ...);
....
Service2 (Id, ...);
....
Service3 (Id, ...);
....
Service4 (Id, ...);
....
}

void Service? (PxInt_t Id, ...)


{
.....
}

HighTec EDV-Systeme GmbH 123 20. Mai 1996


PXROS V4 Users Guide Version 1.0

([DPSOH 8VLQJWDVNVSHFLILFGDWD

TaskFun()
{
....
ServerOpen (&Id, ...);
PxSetAppinfo (Id);
....
Service1 (....);
....
Service2 (....);
....
Service3 (....);
....
Service4 (....);
....
}

void Service? ()
{
PxInt_t Id;

Id = PxGetAppinfo();
.....
}

In this way, the identifier remains unnoticed by the service function user. Also, changes
can be introduced at individual points. Changing the data type only effects the datas
actual user functions.

If a number of different modules use task-specific data, access must be controlled such
that data is not overwritten, as well as to ensure that the desired data is accessed. With
this in mind, data should not be stored with 3[6HW$SSLQIR directly; instead, an
extendible data structure should be created, to which the different data from the
individual modules can be written. Chapter 23.1 describes a module which regulates
secure access to services.

 ([DPSOH

The following source code can be found in the directory DSSLQIR on the accompanying
disk.

 ([F

Both tasks use a function called IXQF. The task-specific data saved in the two tasks
contains the respective other tasks Id. Each task is signalled an event.

HighTec EDV-Systeme GmbH 124 20. Mai 1996


PXROS V4 Users Guide Version 1.0
IXQF

PxArg_t info;
PxTask_t task;
(1) info = PxGetAppinfo ();
(2) task = (PxTask_t) info;
(3) PxTaskSignalEvents (task, EV_1);

7DVN)XQF

(4) info = (PxArg_t) Task2Id;


(5) PxSetAppinfo (info);
for (;;)
{
(6) PxAwaitEvents (EV_1);
(7) func();
}

7DVN)XQF

(8) info = (PxArg_t) Task1Id;


(9) PxSetAppinfo (info);
for (;;)
{
(10) func();
(11) PxAwaitEvents (EV_1);
}

GHWDLOOHGSURFHVVGHVFULSWLRQ

With

(4) info = (PxArg_t) Task2Id;


(5) PxSetAppinfo (info);

7DVN saves WDVNs Id in its task-specific data. It then waits for the signal EV_1 (6).

While 7DVN is waiting, 7DVN becomes active and stores WDVNs Id in ist task-specific
data ((8) and (9)). 7DVN calls IXQF (10), where the tasks data is evaluated:

(1) info = PxGetAppinfo();


(2) task = (PxTask_t) info;

The task whose Id is saved in the task-specific data, is signalled the event EV_1 (3). In
this case, 7DVN becomes active and also calls IXQF (7). After evaluating the task-
specific data, EV_1 is signalled to WDVN (3). 7DVN again waits for EV_1, and 7DVN
continues executing its code where it was interrupted.

(11) PxAwaitEvents (EV_1);

7DVN returns immediately from the function IXQF, as the event has already been

signalled. )XQF is then called again (10), and the programm continues in this way ad
infinitum.

HighTec EDV-Systeme GmbH 125 20. Mai 1996


PXROS V4 Users Guide Version 1.0

HighTec EDV-Systeme GmbH 126 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 $ERUW0HFKDQLVP

 6XPPDU\

PXROS has the ability to abort functions when certain user-defined events occur. The
abort mechanism is realized with the service 3[([SHFW$ERUW.

This service is given a number of events to trigger the abort. If one of these events is
signalled to the calling task, PXROS stops the function call immediately.
3[([SHFW$ERUW returns the events actually that triggered the abort. If the function ends

"naturally", the abort function returns a 0. Only properly configured tasks can use this
function. If resources are requested, the calling task must ensure that they are not lost
when the task is aborted.

 8VLQJWKH$ERUW0HFKDQLVP

PxEvents_t PxExpectAbort ( PxEvents_t events,


void fun(), ... )

The function IXQ is called, but is aborted if an event contained in the event mask,
HYHQWV, is signalled to the calling task. 3[([SHFW$ERUW returns the event(s) that

triggered the abort. If IXQ terminates normally, 3[([SHFW$ERUW returns a . IXQ always
loses its pontential return value. When 3[([SHFW$ERUW is called, the function IXQ must
be declared such that its parameters are transferred over the stack (i.e. not over the
register), and they must be specified after the actual function name (e.g. IXQ).

The abort mechanism can be used e.g. when a task activity is to be stopped by an
emergency off switch. In this example, the interrupt handler that reacts to the switch
signals an abort event to the relevant task.

A task must be configured to use the abort mechanism. This task requires an DERUW
VWDFN, the size of which corresponds to the deepest level of nested calls to
3[([SHFW$ERUW (see chapter 14.10).

([DPSOH

InterruptCode()
{
/* Interrupt for emergency-off */
PxTaskSignalEvents_Hnd (TaskId, EV_INTR);
}

HighTec EDV-Systeme GmbH 127 20. Mai 1996


PXROS V4 Users Guide Version 1.0
void act(void)
{
PxUInt_t i;
....
for (i=0; i<MAX; i++)
{
StartMotor(i);
}
}

TaskCode()
{
PxEvents_t ev;
....
ev = PxExpectabort (EV_INTR, act);
if (ev)
{
/* "act" aborted */
}
else
{
/* "act" run through to end */
}
....
}

The function called by 3[([SHFW$ERUW can call 3[([SHFW$ERUW as well; however, this
deactivates the RXWHU DERUW IUDPH (i.e. the first call to the abort mechanism). The outer
abort frame must be reactivated manually after returning from the iQQHU DERUW IUDPH
(see sections 17.3 and 17.4).

 $FWLYDWLRQDQG'HDFWLYDWLRQRIWKH$ERUW0HFKDQLVP

PxTmode_t PxSetModebits ( PxTmode_t modebits )


PxTmode_t PxClearModebits ( PxTmode_t modebits )

A task can activate or deactivate the abort mechansim by changing its PRGH with the
appropriate services. The task mode is of type 3[7PRGHBW. This data type contains a
bit mask that specifies which of the following PXROS mechanisms are temporarily
GHDFWLYDWHG:

Aborts
Remote Procedures
Remote Handler
Timeslicing

HighTec EDV-Systeme GmbH 128 20. Mai 1996


PXROS V4 Users Guide Version 1.0

The task mode is set by bitwise oring of the desired, corresponding values:

PXTmodeDisableAborts
PXTmodeDisableRemprocs
PXTmodeDisableRemhnds
PXTmodeDisableTimeslicings

The set bits specify which mechanism deactivated. Only 3;7PRGH'LVDEOH$ERUWV is


used to activate and deactivate the abort mechanism.

3[6HW0RGHELWV PRGHELWV and 3[&OHDU0RGHELWV PRGHELWV are services used to


change the task mode. 3[6HW0RGHELWV GHDFWLYDWHV the mechanisms specified in
PRGHELWV. Similarly, 3[&OHDU0RGHELWV DFWLYDWHV the the desired mechanisms by
specifying the corresponding bits in PRGHELWV Both functions return the task mode
specified before the mode was changed. The status of the mechanisms not set in
PRGHELWV remains unchanged. The current task mode can be read with
3[6HW0RGHELWV  . This does not change the task mode.

([DPSOH

void fun()
{
PxTmode_t mode;
....
/* determine task mode and deactivate the abort
mechanism */
mode = PxSetModebits (PXTmodeDisableAborts);
/* protected run before abort */
....

/* Restore original mode */


if ((mode & PXTmodeDisableAborts) == 0)
{
/* Abort mechanism not deactivated => reactivate
*/
PxClearModebits (PXTmodeDisableAborts);
}
}

 ,PSOLFLWGHDFWLYDWLRQZLWK3;5266HUYLFHV

PxEvents_t PxGetAbortingEvents ( void )

Certain PXROS services can remove events from a tasks event mask. These includes
the services, 3[$ZDLW(YHQWV, 3[B(Y:DLW services, and 3[([SHFW$ERUW itself.
These services automatically deactivate the abort mechanism, but they do not
reactivate it.

HighTec EDV-Systeme GmbH 129 20. Mai 1996


PXROS V4 Users Guide Version 1.0

([DPSOH

fun1()
{
....
ev = PxExpectAbort (EV_INTR1, fun2);
....
}

void fun2()
{
....
ev = PxExpectabort (EV_INTR2, fun3);
....
}
In this example, IXQ can only be aborted by the signal EV_INTR2 (i.e. EV_INTR1 does
not abort IXQ). If IXQ ends normally, IXQ will not be aborted by the signal EV_INTR1,
because the call to 3[([SHFW$ERUW (in fun2) deactivates the abort mechanism.
Remember, when using these services, the abort mechanism must be reactivated
manually after the function terminates.

([DPSOH

fun1()
{
....
ev = PxExpectAbort (EV_INTR1, fun2);
....
}

void fun2()
{
....
ev = PxExpectabort (EV_INTR2, fun3);
PxClearModebits (PXTmodeDisableAborts);
....
}

Now the abort mechanism is reactivated after IXQ is terminated (i.e. either naturally or
via an abort); however, EV_INTR1 does not cause an abort as long as IXQ is running.

Normally, the abort mechanism should remain effective, regardless of the level of
execution. This is achieved with services that deactivate the abort mechanism, but still
react to possible abort events. If an abort event is signalled to the task, the task can
trigger the abort mechanism by reactivating it, and resignalling the received event to
itself.

HighTec EDV-Systeme GmbH 130 20. Mai 1996


PXROS V4 Users Guide Version 1.0

([DPSOH

fun1()
{
....
ev = PxExpectAbort (EV_INTR1, fun2);
....
}

void fun2()
{
PxEvents_t ev, abort_ev;
PxTmode_t mode;
....
....
mode = PxSetModebits (PXTmodeDisableAborts);
if ((mode & PXTmodeDisableAborts) == 0)
abort_ev = PxGetAbortingEvents();
else
abort_ev = 0;

ev = PxExpectAbort (EV_INTR2 | abort_ev, fun3);


if (ev & abort_ev)
PxTaskSignalEvents (PxGetId(), ev & abort_ev);
if ((mode & PXTmodeDisableAborts) == 0)
PxClearModebits (PXTmodeDisableAborts);

....
}

3[*HW$ERUWLQJ(YHQWV returns the events that aborted the current activity, provided the

abort mechanism is activated. In this example, 3[*HW$ERUWLQJ(YHQWV returns


EV_INTR1. IXQ can now be aborted with EV_INTR1 and EV_INTR2. If IXQ has been
aborted with EV_INTR1, the task can abort IXQ by reactivating the abort mechanism
and resignalling the event to itself.

 3URWHFWLQJUHVRXUFHV

When using the abort mechanism, remember that resource requests require special
protection. For example, if memory is requested for a function that uses
3[([SHFW$ERUW, memory can be lost if the function is aborted.

HighTec EDV-Systeme GmbH 131 20. Mai 1996


PXROS V4 Users Guide Version 1.0

([DPSOH

void act (void)


{
PxUChar_t *mem;

....
alloc (&mem);
....
....
free (&mem);
....
}

TaskCode()
{
....
ev = PxExpectabort (EV_INTR, act);
....
}

If the task is aborted (as specified in DFW) between the calls to ALLOC and FREE, the
memory is lost. In this case, the memory is accessed via the local variable PHP, which
is no longer available after the abort.

To prevent the loss of resources when using 3[([SHFW$ERUW, the abort mechanism
can be turned off between the request for resources and their release (see section
17.3). A second method of dealing with this problem by referencing the resources
outside of the abort frame.

In the previous example, the requested memory was lost because the reference to the
memory was no longer available outside of the function. The reference was saved in a
local function variable. This problem is avoided by saving the reference in a transfer
parameter.
([DPSOH

void act (PxUChar_t **mem)


{
....
alloc (mem);
/* => *mem != 0 */
....
....
free (mem);
/* *mem == 0 */
...
}

HighTec EDV-Systeme GmbH 132 20. Mai 1996


PXROS V4 Users Guide Version 1.0
fun()
{
PxUChar_t *mem;
....
mem = 0;
ev = PxExpectabort (EV_INTR, act, &mem);
if (ev)
{
....
if (mem != 0)
FREE (&mem);
....
}
....
}

Before the call, PHP is set to 0 and sent as a parameter to DFW. Once released, PHP
receives the value 0 again. If DFW is aborted, the memory can still be accessed and
released from the function IXQF via the parameter PHP. The PXROS services for
requesting and releasing memory are protected against the abort mechanism, so an
abort occurring while such a service is active will not cause problems.

This method has the disadvantage that all resource requests in 3[([SHFW$ERUW must
be known in advance. This can be problematic when using and implementing standard
modules or library functions. For this reason, such functions usually protect their
resource usage against the abort mechanism by periodically deactivating it (see section
17.3); otherwise the functions are not used in 3[([SHFW$ERUW.

The most flexible means to deal with this potential problem is to have the called
function automatically recognize what sort of cleanup work is necessary after the abort
mechanism is used. Chapter 23.3 describes a module that supports this service.

 ([DPSOH

The source code for the following example can be found on the accompanying disk in
the directory DERUW.

 ([F

Task1 starts a timeout, followed by the call of the function &RXQW)XQF in


3[([SHFW$ERUW. If the timeout finishes before &RXQW)XQF is completed, the function is

aborted.

HighTec EDV-Systeme GmbH 133 20. Mai 1996


PXROS V4 Users Guide Version 1.0
&RXQW)XQF

while (*count < 20000)


{
(*count)++;
}

7DVN)XQF

(1) PxToInit (&to, 10, EV_INTR);

for (;;)
{
(2) PxToStart (&to);
(3) ev = PxExpectAbort (EV_INTR, CountFunc, &count)
(4) if (ev)
{
(5) start += 100;
}
else
{
(6) start = 0;
}
(7) count = start;
}

GHWDLOOHGSURFHVVGHFULSWLRQ

Task1 starts a timeout set for 10 PXROS ticks ((1) and (2)). Afterwards,

(3) ev = PxExpectAbort ( EV_INTR, CountFunc, &count)

&RXQW)XQF is called in 3[([SHFW$ERUW. The call includes the address of the variable
FRXQW as ist parameter. The function is aborted when the timeout signals EV_INTR to

Task1. If this is the case, the return value HY will not equal 0 (4) and VWDUW is larger;
otherwise, VWDUW is reinitialized with 0 (6).

FRXQW is set to the value of VWDUW (7), and the process begins again. &RXQW)XQF is not
aborted by the timeout, if VWDUW is so large, that FRXQW in &RXQW)XQF is incremented to
20000 before the timeout expires.

HighTec EDV-Systeme GmbH 134 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 3URFHVVRU'HSHQGHQW6HUYLFHV

PXROS provides the application with a common interface underneath which processor
dependent differences are hidden. This includes the interrupt interface. There are even
services available for specific processors. Except for the interrupt interface, the
services described in the following pages are required only rarely in a PXROS
application.

The following sections describe only a few of these processor-dependent services.


They do not mention all of processors PXROS supports. For additional information
about hardware specific services, please contact HighTec.

 3;526IRU6LHPHQV&[3URFHVVRUV

 ,QWHUUXSW,QWHUIDFH

The module for the interrupt interface are distributed in source from along with PXROS.
Using special compiler options, the interrupt interface can be adapted to the best use of
the target hardware.

'HILQLJ+DQGOHUV'\QDPLFDOO\

Calling 7UDS,QVWDOO&KDQGOHU (at run Time) installs an interrupt handler for the hardware
interrupt specified. This allows one to install arbitrary functions that react to certain
interrupts as they occur; however, certain preparations are usually necessary to use
interrupt handlers. These preparations can potentially increase the interrupt latency
time.

Before an interrupt handler is installed, the interrupt vector table must be initialized. If
the vector table is located in RAM, it can usually be initialized with the function 7UDS,QLW.
For all other interrupts for which a handler is dynamically defined, the call to
7UDS'LVSDWFK should be used.

'HILQLQJ+DQGOHUV6WDWLFDOO\

Usually the handler is defined before the programm is created, and it stays in place for
the duration of the application. With the appropriate macros, a handler can be installed
statically in the source code when the function is declared. The declaration macros are
described in the header S[VWUDSK. The interrupt latency time is noticeably less than
with a static definition. During run time, the application must call 3[6WUDS,QLW before the
first interrupt takes place. This function is only available in the GNU C16x C/C++
compiler version 3.1 and beyond.

HighTec EDV-Systeme GmbH 135 20. Mai 1996


PXROS V4 Users Guide Version 1.0

7UDS9HFWRU7DEOHLQ(3520

The C16x-processors trap vector table is located in the 512 bytes beyond the address
0. If there is no RAM there, the vector table can not be dynamically changed. Under
these circumstances, the vector table must be completely configured while the
programm is created. In some applications (e.g. Pxmon), the trap vector table must be
modifiable during run time.

In such cases, a copy of the table can be maintained in RAM. Jumps are entered in the
corresponding points of the "RAM Vectab" as with the trap table. The service functions
must be modified such that they operate on the "RAM Vectab" instead of the trap
modules. When the modules are translated, the macro 75$39HFWDE is set to the
starting address of the RAM vector table. The compiler is then called as follows:

gcc166 DTRAPVectab=XXXX ....,

The starting address of the RAM Vectab is indicated above as ;;;;. If 7UDS9HFWDE is
set to -1, no vector table exists in the RAM. If 75$39HFWDE is not defined, the vector
table is located at the address 0.

A firmware monitor used for debugging must be generated to operate on the RAM
Vectab, as it must modify the table during run time.

 7DVN&RQWH[W

The WDVN FRQWH[W for C16x Processors is used in PXROS versions that support mixed
memory models. The task context is meaningless in other versions, and all structures
or functions pertaining to it are empty.

PxError_t PxGetTaskContext ( PxTaskContext_t context )


PxError_t PxInstallTaskContext ( PxTaskContext_t context )

When a task is activated or deactivated, its context is always restored or saved


respectively. This includes e.g. the tasks registers and the code address where the
task was interrupted. This context can be built around the individual task. For C16x
processors, the task context is defined in the folowing structure:

typedef struct {
PxInt_t c166_dpp0;
PxInt_t c166_dpp1;
PxInt_t c166_dpp2;
} PxTaskContext_T, *PxTaskContext_t;

In this way, the relevant processor registers for each task can be saved independent of
all other tasks or initializations.

HighTec EDV-Systeme GmbH 136 20. Mai 1996


PXROS V4 Users Guide Version 1.0

Using the function 3[7DVN,QVWDOO&RQWH[W , FRQWH[W is defined as the new task context.
3[*HW7DVN&RQWH[W copies the calling tasks context into the address specified in
FRQWH[W .

At the beginning of an application, a newly created task always receives the task
context indicated in the structure PxTaskSpec_T; specifically, that described in
WVBFRQWH[W. If the value is , the task context is inherited from the creating task.

 3;526IRU,QWHO[3URFHVVRUV

 ,QWHUUXSW,QWHUIDFH

During run time, an interrupt handler can be assigned to a hardware interrupt


dynamically. This is done with the service 7UDS,QVWDOO&KDQGOHU, and enables arbitrary
functions to be specified as interrupt handlers. Before the installation of an interrupt
handler, the interrupt interface must be initialized. This entails calling the function
7UDS,QLW.

 7DVN&RQWH[W

PxError_t PxGetTaskContext ( PxTaskContext_t context )


PxError_t PxInstallTaskContext ( PxTaskContext_t context )

When a task is activated or deactivated, ist context is always restored or saved


respectively. This includes the tasks registers and the code address where the task
was interrupted. This context can be built around the task. For processors of the type
80x86 the task context can be defined with the following structure:

typedef struct {
unsigned long t_esp1;
unsigned long t_ss1;
unsigned long t_esp2;
unsigned long t_ss2;
unsigned long t_cr3;
unsigned long t_ldt;
char Bitmap [ (MAXTSSIOADDR+1) /NBPB ] ;
} PxTaskContext_T, *PxTaskContext_t;

In this way, the relevant processor registers for each task can be saved independent of
all other tasks or initializations.

HighTec EDV-Systeme GmbH 137 20. Mai 1996


PXROS V4 Users Guide Version 1.0

With 3[7DVN,QVWDOO&RQWH[W, FRQWH[W is defined as the new task context. If one of the
attributes (except %LWPDS) is set to [IIIIIIII in *context, the corresponding value in the
task context is not changed. 3[*HW7DVN&RQWH[W copies the calling tasks context into
the address specified in FRQWH[W. The values of 0$;766,2$''5 and 1%3% are
defined in pxdef.h.

At the beginning of an application, a newly created tasks always receive the task
context indicated in the structure PxTaskSpec_t; Specifically, that described in
WVBFRQWH[W. If the value is , the task context is inherited from the creating task.

HighTec EDV-Systeme GmbH 138 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 6HUYLFHVRIWKH3;5263OXV9HUVLRQ

Some PXROS services are only available in the PXROS-Plus version. These services
are not included in the standard distribution since they often either increase run time or
memory requirements. They are rarely needed, but some can be quite useful at times.

This chapter touches on such services. For more information, please contact HighTec.

 6FKHGXOLQJ([WHQVLRQV

During a task change, PXROS can execute certain user-defined functions. This service
is usually available in the debug library of the standard PXROS distribution. The
PXROS-Plus version also allows to assign tasks specific scheduling extensions; in
other words, PXROS executes specific, user-defined functions whenever a task is
activated or deactivated.

Scheduling extensions greatly increase the time required for each scheduling function.
Furthermore, more space is required for the task control structure. The task control
block of every task is enlarged whenever a scheduling extension is used. This is done
to create space to save data for future processing.

typedef enum {
PXSchedExtForeignHnd_Bgn,
PXSchedExtForeignHnd_End,
PXSchedExtOwnHnd_Bgn,
PXSchedExtOwnHnd_End,
PXSchedExtSched,
PXSchedExtRemproc_Bgn,
PXSchedExtRemproc_End,
PXSchedExt_LastCode
} PxSchedExtCause_t;

With a variable of type 3[6FKHG([W&DXVHBW, PXROS reports what triggered the tasks
activation or deactivation. Possible triggers include: task changes (3;6FKHG([W6FKHG),
a software interrupt handler that was installed by a task (3;6FKHG([W2ZQ+QGB%JQ or
-B(QG) begins or end, the starting or ending of a software interrupt handler that was
installed by a different task (3;6FKHG([W)RUHLJQ+QGB%JQ or -B(QG) and the starting or
ending of a remote procedure ( 3;6FKHG([W5HPSURFB%JQ or B(QG).

 *OREDO6FKHGXOLQJ([WHQVLRQV

Global scheduling extension can produce scheduling statistics, which can be evaluated
with PXmon. This can provide far-reaching information about the systems behaviour.
This extension uses a data structure to record when a task is activated or deactivation,
the tasks run time, and the scheduling took place. Several functions are available for
this extension.

HighTec EDV-Systeme GmbH 139 20. Mai 1996


PXROS V4 Users Guide Version 1.0

The global scheduling extension is described by a 3[*OREDO6FKHG([WB7 structure:

typedef struct {
PxUInt_t gse_size;
void (*gse_init) (void *);
void (*gse_save) (void *, PxSchedExtCause_t);
void (*gse_restore) (void *, PxSchedExtCause_t);
} PxGlobalSchedExt_T, *PxGlobalSchedExt_t;

JVHBVL]H contains the size of the data to be processed. PXROS adds space to every
task control block and sets it to 0. When the task is activated for the first time, its data
is initialized with JVHBLQLW. JVHBUHVWRUH is called when the task is activated and
JVHBVDYHis called when the task is deactivated 

These functions must pass their parameters via the stack. They are executed on the
handler level and thus may only use handler services. All functions use the first
parameter to store the starting address of the data area provided in the task control
block. In an additional parameter, both JVHBVDYH and JVHBUHVWRUH receive information
about what triggered the scheduling.

 7DVN6FKHGXOLQJ([WHQVLRQV

The task-specific scheduling extension is normally used to multiplex specific data for
several tasks. For example, a normally global variable HUURU, can be multiplexed for
multiple tasks. When a task is activated, it writes a value to HUURU. The task can access
HUURU directly, and HUURUs current value is saved when the task is deactivated. The task-

specific scheduling extension is described in the following structure:

typedef struct {
PxUnit_t tse_size;
void (*tse_init) (void *, PxArg_t);
void (*tse_save) (void *, PxSchedExtCause_t);
void (*tse_restore) (void *, PxSchedExtCause_t);
} PxTaskSchedExt_T, *PxTaskSchedExt_t;

WVHBVL]H contains the size of the data that is to be processed by the functions. PXROS

adds space to every task control block and sets it to 0. When a task is activated for the
first time, its data is initialized with WVHBLQLW. The initialization value is passed to the
second argument and stored in the structure when the task is created (see chapter
14.11). WVHBVDYH is called, when the task is deactivated, and WVHBUHVWRUH is called when
it is activated.

These functions must pass their parameters via the stack. They are executed on the
handler level and thus may only use handler services. All functions use the first
parameter to store the starting address of the data area provided in the control block. In
an additional parameter, both WVHBVDYH and WVHBUHVWRUH receive information about what
triggered the scheduling.

HighTec EDV-Systeme GmbH 140 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 +DQGOHU6HQG

In the standard version of PXROS, a handler cannot send or release messages. This
service is rarely necessary; however, the services 3[0VJ6HQGB+QG,
3[0VJ6HQGB3ULR+QG and 3[0VJ5HOHDVHB+QG are provided in PXROS-Plus to offer

this feature. The parameters correspond to the equivalent task services (see chapter
5). To enable handlers to release messages, a specific task functions as a PHVVDJH
UHOHDVHVHUYHU. This server is created with the function 3[0VJUHOVUY,QLW .

In this version, handlers can not create messages or wait for them to arrive. Handlers
access messages either through a mailbox handler, or with a global variable serviced
by a task that enters the Id any messages created or received on the handlers behalf.

 7LPH6OLFLQJ

PxTicks_t PxGetTimeslices ( void )


void PxSetTimeslices ( PxTicks_t ticks )

PXROS priority based scheduling always gives control of the processor to the ready
task with the highest priority. This task cannot be interrupted by a task at the same
priority level. It stays active until it is either interrupted by a task with higher priority, or
until it enters a wait state.

In addition to task priorities, PXROS-Plus provide timeslicing scheduling mechanism:

Every task is allocated a specific time credit in a timeslicing account. The active tasks
time credit is decremented with every PXROS tick. Once these credits are expended,
PXROS activates the next ready task at the same priority level. PXROS then restocks
the first tasks account. If no other tasks are ready, the active continues processing.

The reload value of a tasks time account is set when the task is created. This value
can be called up and changed at run time. 3[*HW7LPHVOLFHV returns the calling tasks
current reload value. 3[6HW7LPHVOLFHV sets the reload value in WLFNV PXROS ticks. If
ticks is 0, the task does not participate in the time slicing process.

This service increases the programs execution time by a processor-dependent amount


for every PXROS tick. It also increases the size of the control structure that PXROS
creates for every task.

HighTec EDV-Systeme GmbH 141 20. Mai 1996


PXROS V4 Users Guide Version 1.0

HighTec EDV-Systeme GmbH 142 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 8VLQJ3;526ZLWK(3520V

PXROS applications can usually run in EPROMs without restrictions; however, one
should consider potential restriction intoduced by the development environment and the
hardware used. These have little to do with PXROS itself, but are generally related to
the interrupt interface. The remainder of this chapter concerns almost all basic EPROM
applications.

The developer is advised to develop the application in RAM before placing it on an


EPROM. In this way, mistakes can be recognized and removed much earlier and with
fewer difficulties.

The following sections mention some things to look for when creating an application for
specific target processors and development environments.

 6LHPHQV&[)DPLO\ZLWKWKH*18'HYHORSPHQWWRROV

 ,QWHUUXSW,QWHUIDFH

The interrupt interface is established via the vector table, which is located at address 0.
configuring the vector table depends on whether the related interrupt handler is defined
dynamically, i.e. at run time with 7UDS,QVWDOO&KDQGOHU, or if it is defined statically at the
beginning of an application. In the first case, a jump to the function B7UDS'LVSDWFK
must be entered in the interrupt vector table for each interrupt:

calls seg:__TrapDispatch, sof:__TrapDispatch

The interrupt hadler can be defined statically (as the function is declared) using the
macros inS[VWUDSK. In this way when the application is compiled, the linker specifies a
direct jump to the interrupt handler in the vector table.

 &RPSLOHU2SWLRQV

To create an application that can run on an EPROM, the option PURPDEOHFRGH must
be specified when translating each module. Other options are not required.

The file FUWV, which is distributed with the GNU development tools, contains the code
for the startup phase. It initialize the hardware and perform other jobs, such as setting
the BBS (i.e. Block Storage Section) to 0, or initializing application data. FUWV may
need to be adapted to the specific hardware used.

HighTec EDV-Systeme GmbH 143 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 /LQNHU0DS)LOH

C16x executables consist of data, text and BBS areas. The codes complete WH[W area
must be saved in map file for the EPROM. The GDWD area contains constant data and
must be saved to the same address area. The BBS area contains non-initialized data
and must be saved to an area that also contains RAM. In certain memory models
(specmed, small, compact) the data page pointers must be initialized such that they
cover both the BBS DQG data areas.

 3RWHQWLDO3UREOHPV

The application is usually developed on a target system that contains RAM throughout
the address areas used. In testing phase, the application is loaded onto the processor
with a firmware monitor and a debugger. If no bugs are found, then the application
should run on the EPROM. Sometimes bugs appear in the transition, that were not
discovered during the testing phase.

This can often be traced to the startup file FUWV, which may need to be adapted to the
hardware used. Such bugs are not found during the Ram test since the firmware
monitor configurations certain hardware features automatically, and the debugger
automatically sets the applications RAM area (BBS) to 0.

For example, the monitor may activate the interrupts and deactivate the watchdog, in
which case the startup file does not need to perform these activities. In the EPROM
version however, a monitor is not normally used, so these jobs must be correctly
executed in the startup file. If this is not done, the problems drescibed above may
occur.

HighTec EDV-Systeme GmbH 144 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 8VLQJ3[PRQ3[PRQ57

A debugger is usually used to test running programs for errors. It communicates e.g.
over a serial interface with a firmware monitor on the target system. The program can
be loaded and started, breakpoints can be set, assembler code evaluated, and
variables can be read and modified.

To do this, the program must first be stopped. This can cause problems for applications
that communicate with other equipment. When the program is stopped, timeouts may
run out on the other end, and in some cases connections are dismantled. Furthermore,
it is difficult to receive PXROS-specific information from a standard debugger, e.g. the
condition of tasks, resource usage or the contents of mailboxes.

3;PRQ is a special task provides PXROS-specific data while the V\VWHP LV UXQQLQJ. It
can also acces numerous firmware monitor services, for example to alter variables. It
can not be used to set breakpoints, single step the application, etc. Since PXmon is
part of the actual application, it FDQQRW be used to load the program into the target
system.

PXmons most important function is providing PXROS-specific data. This can be used
to determine a tasks stack requirements, or to report the amount of memory or objects
in use. PXmon can also display the scheduling behaviour over a certain time period, or
the sum of the tasks running time. The realtime monitor can temporarily suspend the
tasks execution, which can be used to provoke problem situations and thereby test the
applications reaction. Furthermore, PXmon can influence the running system with user-
defined commands.

The extended version of PXmon, Pxmon-RT, supports debugging in realtime. This


allows one to set task-specific breakpoints and single-step through individual tasks, i.e.
without stopping the rest of the system.

HighTec EDV-Systeme GmbH 145 20. Mai 1996


PXROS V4 Users Guide Version 1.0

HighTec EDV-Systeme GmbH 146 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 3;526DQG&

In GNU-CC, the operator "new" is typically mapped to the library function "malloc()",
operator "delete" to the library function "free()". These functions must be reentrant
coded to be usable in a PXROS multitasking environment. For this reason one must
use special versions that come with a PXROS release.
Object oriented languages, such as C++, use so-called FRQVWUXFWRUV to statically
instanciate (object) classes. Constructors are performed before the program flow
reaches "main()".
A serious synchronization problem arises if a constructor in a PXROS system makes
use of the operator "new", since the memory management of PXROS isnt initialized at
that time.
The GNU & compiler handles constructors within a helper function called
"BBPDLQ ", that is automatically called when "main()" is compiled.
To ship around the above mentioned synchronization problem, one has to compile the
"main()" function with the & compiler (that doesnt call __main() ). After the initialization
of PXROS, one has to call __main() explicitly. No access or reference to the static
object classes are allowed between main() and PxInit()!

void
main(void) {

InitHardware();
...
PxInit (...);
__main(); // handle global constructors
...
}

HighTec EDV-Systeme GmbH 147 20. Mai 1996


PXROS V4 Users Guide Version 1.0

HighTec EDV-Systeme GmbH 148 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 &UHDWLQJD3;526$SSOLFDWLRQ

This chapter describes how a PXROS application is created with the GNU development
tools. It does not go into great detail, and not all applications are mentioned. The
purpose of this chapter is to enable the user to create a simple PXROS application as
quickly as possible. Processor-specific features are dealt with in chapter 18.

To create a PXROS application, one theoretically need only link the interrupt interface
modules and the desired PXROS libraries to the compiled modules.

 6LHPHQV&[3URFHVVRUV

 0DNHILOH

This section describes a simple makefile that creates a PXROS application for this
processor. The makefile is provided in ASCII form in the directory JHQHUDWHF[. It
was saved as PDNHILOH[. It was designed for use on an UNIX system. Certain
modifications are required for MS-DOS systems, especially the definition of 93$7+.
With UNIX, directories are separated with a colon (":"). In contrast, MSDOS uses the
semicolon (";") since the path name often contains a colon (":"). Details are provided in
the GNU handbook in the chapter JPDNH.

In the following description, compiler calls and options are not explained as they are
beyond the scope of the Users Guide. If certain points are unclear, please refer to the
relevant parts of the development tools handbook. Before continuing, a few comments:

A makefile contains the general rules to control certain processes. In this case, these
rules are used to create a program and the objects that belong to it. The rules specified
in the makefile have the following form:

target object: dependencies


<TAB> Rules for creation

e.g.:
module.o: module.c
gcc166 -g -0 -c -mregparm -mspecmed module.c

or

prg: module1.o module2.o module3.o


gcc166 -mspecmed -g -o prg module1.o module2.o
module3.o

HighTec EDV-Systeme GmbH 149 20. Mai 1996


PXROS V4 Users Guide Version 1.0

When creating a makefile, macros can be quite useful. These allow one to globally
change the values associated with path and another variable names. They also serve
to provide the makefile with the clearer structure. Macros are defined in makefile as
follows:

PXROS = /home/pxros
CC = gcc166
COPTS = -g -o

and are accessed by a dollar sign ("$") followed by the macros name in parens:

$(MACRONAME)

They can be used within the definition of another macro. For example:

PXROSLIB = $(PXROS) /lib/pxdbg_x.a

This make the makefile very flexible.

The pound sign ("#") indicates a comment line.

#
# Makefile of a PXROS application for C16x processor
#
#

# Macro definitions:

# Memory model
MODEL = specmed
EXT = _x

# PXROS paths
PXROS = /home/pxros/pxros$(EXT)
PXINC = $(PXROS)/include
PXSRC = $(PXROS)/src
PXLIB = $(PXROS)/lib/pxutils$(EXT) .a $(PXROS)/lib/pxdbg$(EXT)
.a

# Compiler configuration
CINCS = -I$(PXINC) -I../include
COPTS = -c -g -0 -Wall -m7
CDEFS = -DTEST
CFLAGS = $(CINCS) $(CDEFS) $(COPTS)
CC = gcc166 -m$(MODEL) -mromable-code -mregparm

# Linker Configuration
LD = $(CC)
LDFLAGS = -map prg16x.map -loc prg16x.loc

# Modules:
TRAPOBJS = addr.o pxtrap.o pxtrp$(EXT).o
OBJECTS = $(TRAPOBJS) mod1.o mod2.o
HighTec EDV-Systeme GmbH 150 20. Mai 1996
PXROS V4 Users Guide Version 1.0
# Directory paths. The source files contain
VPATH = $(PXSRC):../src

# Rule for the program:


prg: $(OBJECTS)
$(LD) $(LDFLSGS) -m$(MODEL) -o prg $(OBJECTS)
$(PXLIB)

# Rule for an object


pxtrp$(EXT).o : $(PXSRC)/pxtrp$(EXT).ss
$(CC) $(CFLAGS) $(PXSRC)/pxstrp$(EXT).ss -o
pxstrp$(EXT).o

'HVFULSWLRQ

At the beginning of the makefile, various macros are defined. These correspond to the
memory model used to create the application:

MODEL = specmed
EXT = _x

Afterwards, macros are defined for accessing various PXROS modules:

PXROS = /home/pxros/pxros$(EXT)
PXINC = $(PXROS)/include
PXSRC = $(PXROS)/src
PXLIB = $(PXROS)/lib/pxutils$(EXT) .a
$(PXROS)/lib/pxdbg$(EXT) .a

The following lines in the makefile are used to configure the compiler, e.g. compiler
options for the paths that contains the headers to be included.

CINCS = -I$(PXINC) -I../include


COPTS = -c -g -0 -Wall -m7
CDEFS = -DTEST
CFLAGS = $(CINCS) $(CDEFS) $(COPTS)
CC = gcc166 -m$(MODEL) -mromable-code -mregparm

Similary the linker is configured as follows:

LD = $(CC)
LDFLAGS = -map prg16x.map -loc prg16x.loc

Now a macro is defined for hte objects that make up an application. This is used to
facilitate access to these objects.

TRAPOBJS = addr.o pxtrap.o pxtrp$(EXT).o


OBJECTS = $(TRAPOBJS) mod1.o mod2.o

93$7+ specifies the directories in which source files are located. These files are used
to create objects. As mentioned above, the individual directories must be separated
with a colon (":") under UNIX, and by a semicolon (";") on MS-DOS systems.

HighTec EDV-Systeme GmbH 151 20. Mai 1996


PXROS V4 Users Guide Version 1.0
VPATH = $(PXSRC):../src

After the macro definitions, the rules for creating the program follow. The macros
defined earlier are used extensively in this section:

prg: $(OBJECTS)
$(LD) $(LDFLSGS) -m$(MODEL) -o prg $(OBJECTS) $(PXLIB)

This sample makefile only contains rules for creating one object. Other objects are
made with gmakes LPSOLFLW UXOH. This means a standard process is used to create every
object that does not have exclusive rules. To create the object ;;;R, the directories
specified by the macro 93$7+ are searched for the file ;;;F. If ;;;F is found, the
object ;;;R is created as follows:

$(CC) -c $(LDFLAGS) XXX.c

Notice why the macros for configuring the compiler were given earlier. The implicit rule
is advantageous for applications with many individual objects.

 6SHFLDO1RWHV

Applications for C16x processors can be created in various memory models. Single
objects must be created with the appropriate options. For this reason, PXROS is
provided in different versions for the individual memory models. These models can be
recognized by their extensions BV, B[, BO, etc.

The map file informs the linker where text, data, or BBS are located on the target
hardware (i.e. the address area). Keep in mind that for different memory models
(compact and specmed), the data page pointer of the processor should be defined in
the map file such that data and BBS areas are covered by the DPPs. It is also
important that '33 receives the value ; otherwise PXROS will not function properly.

A firmware monitor is usually used during the development phase, and in some cases it
must be loaded onto the target hardware. It requires memory for data, and these areas
may not be released for the application.

With the locater file, one can specify the address of where certain application
components are placed. In principle, the linker places application components
anywhere within the address area that is specified in the mapfile. Fixed definitions can
be made for the loc file. This is important for the interrupt vector table because it should
normally be located at the address .

If the makefile does not specify where to place the startup code, the interrupt vector
table, the map file, or the loc file, the standard files distributed with GNU are used.
These are nott necessarily compatible with the target hardware used. This can lead to
problems when trying to load the application onto the target system.

HighTec EDV-Systeme GmbH 152 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 8WLOLW\/LEUDU\

This chapter serves as an introduction to the utility library. It contains a number of


useful modules to perform specific jobs, each with a comfortable interface to the
standard PXROS services. The utility library is QRW included in the standard PXROS
distribution; rather, it can be obtained from HighTec in source form, including all related
headers, and can be used for individual applications.

 0DQDJHPHQWRI*OREDO7DVN'DWD

PXROS allows the application to save task specific data, and thus implements a means
to access task-global data. If different modules use task-global data, the access to the
data must be strictly controlled, so that no data is overwritten or the wrong data is
inadvertently accessed. With this in mind, the data should not be saved to one location
with 3[6HW$SSLQIR; rather, the data should be placed in an expandable data structure
associated with each task. The module S[XDSSLQFcontains various services that allow
safe access to the application data.

 3[X$SSLQIR6HW&RPS3[X$SSLQIR8SGDWH&RPS

PxError_t PxuAppinfoSetComp ( PxUInt_t index,


void *components,
void (*cleanup) (void * ))

PxError_t PxuAppinfoUpdateComp ( PxUInt_t index,


void *components )

The application uses the function 3[X$SSLQIR6HW&RPS to store new task-specific


data. The parameter LQGH[ is an identifier that differentiates between different data
used for different purposes. If LQGH[ already contains data,
PXERR_REQUEST_ILLEGAL is returned. ,QGH[ values should be numbered, beginnig
with , to save memory space.

&RPSRQHQW is the initial address of a memory area that contains the data to be saved.
&OHDQXS specifies the address of a function with e.g. releases resources when the task-
specific data is no longer needed. &OHDQXSs parameter contains the datas initial
address. If the FOHDQXS function is not required,  is specified for this attribute.

3[X$SSLQQIR8SGDWH&RPS stores new data at LQGH[ using FRPSRQHQWV to specify the


datas initial address. This function can not be used to place new data in index. Dta
must already be stored at LQGH[ (i.e. from a previous call to 3[X$SSLQIR6HW&RPS).

HighTec EDV-Systeme GmbH 153 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 3[X$SSLQIR*HW&RPS

Void *PxuAppinfoGetComp ( PxUInt_t index )

3[X$SSLQIR*HW&RPS provides the initial address of the data saved at LQGH[. If no data
is present,  is returned.

 3[X$SSLQIR&OHDQXS&RPS

void_t PxuAppinfoCleanupComp ( PxuInt_t index )

void PxuAppinfoCleanup ( void )

The data area specified in LQGH[ can be released with 3[X$SSLQIR&OHDQXS&RPS. This
service calls the cleanup function specified in the 3[X$SSLQIR6HW&RPS call. When
3[X$SSLQIR&OHDQXS is called, all task-specific data is erased, not just the data stored

at a specific index.

 1HZ0HPRU\&ODVVHV

PXROS can manage the entire range of dynamically allocateable memory available to
the application. To improve data security and reduce processing time, this memory is
often split up into a number of PHPRU\ FODVVHV (see chapter 7). The services provided
in the modules S[XEONBIF and S[XEONBYF can be used to create new memory classes
and allocate the memory they hold.

 3[X&UHDWH)L[EON3RRO

PxErrror_t PxuCreateFixblkPool ( PxMc_t *Poolmc,


PxUInt_t no,
PxSize_t size,
PxMc_t srcmc )

3[X&UHDWH)L[EON3RRO create a IL[HG block memory class of VL]H bytes. This memory

class contains QR memory blocks. Using the service 3[0F5HPRYH%ON, the memory is
taken from the memory class specified in VUFPF. SRROPF contains the new memory
class Id. Once created, up to QR blocks are available from the new memory class. No
overhead is incurred for the memory management realized with this mechanism.

HighTec EDV-Systeme GmbH 154 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 3[X&UHDWH9DUEON3RRO

PxErrror_t PxuCreateVarblkPool ( PxMc_t *Poolmc,


PxSize_t size,
PxMc_t srcmc )

3[X&UHDWH9DUEON3RRO creates a new YDULDEOH block memory class. This memory class
receives VL]H bytes of memory from its source memory class VUFPF 3RROPF contains
the new memory class Id. The new memory class can not distribute the entire VL]H
bytes of memory, since every request for a memory blockt requires additional bytes of
overhead for memory management.

 &OHDQLQJ8S$IWHUDQ$ERUW

PXROS provides the means to abort an active function if certain predefined events
occur. The a ERUWPHFKDQLVP is implemented with the service 3[([SHFW$ERUW.

When a function is aborted, certain cleanup processes must be performed. For


example, the function may have requested memory which it had not yet released at the
time of the abort (see chapter 17). With this in mind, the cleanup must take place
outside of the function.

There are various methods of cleaning up after an abort. It is best if the function
recognizes what sort of cleanup is required. For this reason, special cleanup structures
have been developed. These structures are linked to FOHDQXS VWDFNV, which note what
sort of cleaning work is required after nested calls have occurred. In order to perform
the necessary work, the cleanup stack reside outside of the call to 3[([SHFW$ERUW.

S[XFOHDQF contains functions to make the required cleaning work as comfortable as

possible. The structure type 3[X&OHDQXSB7 is defined in S[XFOHDQXSK.

typedef struct PxuCleanup_T {


void (*cleanup_fun) (PxArg_t);
PxArg_t cleanup_arg;
struct PxuCleanup_T *cleanup_ next;
PxMc_t cleanup_mc;
} PxuCleanup_T, *PxuCleanup_t;

These structures are associated with a cleanup stack, which holds the information
related to the cleanup functions. When an abort occurs, the corresponding cleanup
functions are activated. FOHDQXSBIXQ is the cleanup function itself, and FOHDQXSBDUJ
holds the argument to be passed on to the function. FOHDQXSBQH[W links these
structures together.

HighTec EDV-Systeme GmbH 155 20. Mai 1996


PXROS V4 Users Guide Version 1.0

The cleanup structure must still be accessible from outside of the aborted function. In
other words, this structure cannot reside on the local stack. It must either be allocated
dynamically, or stored globally. FOHDQXSBPF specifies the memory class that the
structure was requested from. This is used to later release the memory used. If the
memory does not come from a memory class, the structure is static, and FOHDQXSBPF is
0.

The services are used to initialize a cleanup stack, extend it, to activate the functions
kept on the cleanup stack, and to dismantle the cleanup stack when it is no longer
needed. The cleanup stack is usually used as follows:

([DPSOH

PxuCleanup_T stack;

TaskCode()
{
(1) stack.cleanup_mc = 0;

/* Initialize the cleanup stack */


(2) PxuCleanupInit (&stack);
func1 ( &stack );
....
}

func1 ( PxuCleanup_T *stack)


{
PxuCleanup_t Id;
....
/* determine the current stack status*/
(3) Id = PxuCleanupGetId (stack);

ev = PxExpectAbort (EV_INTR, func2, &stack, ..)

/* On abort: execute the cleanup functions,


pushed on the stack beneath PxExpectAbort
and have not yet been popped*/

(4) if (ev) PxuCleanupActivate (Id);


....
}

HighTec EDV-Systeme GmbH 156 20. Mai 1996


PXROS V4 Users Guide Version 1.0
func2 (PxuCleanup_t stack, ...)
{
PxuCleanup_t cleanup, Id;

....

/* deactivate abort*/
/* request cleanup structure */
PxMcTakeBlk (PXMcTaskdefault, &cleanup, sizeof
(PxuCleanup_T));
/* write values to cleanup1 */
cleanup->cleanup_mc = PXMcTaskdefault;
cleanup->cleanup_arg = ....
cleanup->cleanup_fun = ....

/* place cleanup on the stack, and get Id */


(5) PxuCleanupPush (stack, cleanup, &Id);
/* reactivate abort */
.....
.....
/* dismantle cleanup */
(6) PxuCleanupPop (Id);
}

The initial cleanup stack is initialized with 3[X&OHDQXS,QLW ((1) and (2)). New cleanup
jobs are pushed on the stack with 3[X&OHDQXS3XVK. This returns an Id that shows the
current status of the cleanup stack. With this Id, all cleanups saved to the stack DIWHU
this status can be popped. All cleanup jobs listed prior to this Id will still be executed.

Before 3[([SHFW$ERUW is called, 3[X&OHDQXS*HW,G determines the current status of


the cleanup stack (3). The function called by 3[([SHFW$ERUW writes a cleanup structure
into the cleanup stack before it e.g. requests resources (5). When these resources are
released, the cleanup structure is popped from the stack (6). If the function is aborted,
then all cleanup functions saved to the cleanup stack are executed (4).

The abort may occur just as the cleanup structure is being taken off the cleanup stack.
With this in mind, cleanup functions must be set up to continue to function correctly,
even when the cleanup is finished.

 3[X&OHDQXS,QLW

PxError_t PxuCleanupInit ( PxuCleanup_t stack )

3[X&OHDQXS,QLW initializes a cleanup stack. VWDFN specifies a structure of type


PxuCleanup_T. This structure is not created automatically when this function is called,
(i.e. it must be created before the call). 3[X&OHDQXS,QLW does not set the attribute
FOHDQXSBPF.

HighTec EDV-Systeme GmbH 157 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 3[X&OHDQXS3XVK

PxError_t PxuCleanupPush ( PxuCleanup_t stack,


PxuCleanup_t cleanup,
PxuCleanup_t *Cleanup_id )

3[X&OHDQXS3XVK pushes a cleanup structure on to the cleanup stack VWDFN at the


address FOHDQXS. This service is called within the function that might be aborted.
Because the relevant local variables are not accessible after a function is aborted, this
structure must either be available globally, or allocated dynamically. The attribute
FOHDQXSBPF is written accordingly. An identifier is placed in FOHDQXSBLG. This keeps

track of current state of the cleanup stack. This identifier used to execute cleanup
functions, or to remove cleanup structures from the stack.

 3[X&OHDQXS*HW,G

PxuCleanup_t PxuCleanupGetId ( PxuCleanup_t stack )

3[X&OHDQXS*HW,G returns the current identifier for the cleanup stack VWDFN. This
identifier is used to execute (i.e. with 3[X&OHDQXS$FWLYDWH) the cleaning functions that
are currently on the stack.

 3[X&OHDQXS$FWLYDWH

Void PxuCleanupActivate ( PxuCleanup_t cleanup_id )

3[X&OHDQXS$FWLYDWH executes (and then removes) the cleaning functions currently on


the cleanup stack. This function executes all cleaning functions located underneath the
position specified in FOHDQXSBLG.

 3[X&OHDQXS3RS

Void PxuCleanupPop ( PxuCleanup_t cleanup_id )

This function pops all cleaning functions located beneath the point specified in
FOHDQXSBLG. It does not execute the associated functions.

HighTec EDV-Systeme GmbH 158 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 :DLWLQJDW'LIIHUHQW0DLOER[HV6LPXOWDQHRXVO\

In some applications, a task may need to wait for messages at a number of different
mailboxes simultaneously. This is rarely the case, so PXROS does not support this
option directly; however, this goal can be achieved. PXROS supports so called PDLOER[
KDQGOHUV, which are activated whenever a message arrives in a mailbox (see chapter

9.3).

If a task waits at a mailbox for both messages DQG events, simultaneous waiting is
made possible with the service 3[0VJ5HFHLYHB(Y:DLW. The task installs mailbox
handlers at the other mailboxes, which in turn signal certain events if a message
arrives. If the task is actived by such signals, it evaluates the event and collects the
message from the corresponding mailbox.

The services provided in S[XPE[B F allow the user to perform this function
comfortably and safely. To use these services, a structure of the type 3[X0E[,QIB7
must be alotted to every participating mailbox handler.

PxError_t PxuMbxInfInit ( PxuMbxInf_t mbxinf,


PxMbx_t mbx,
PxMsgType_t msgtype,
PxEvents_t events )

PxError_t PxuMbxInfStart ( PxuMbxInf_t mbxinf )

PxError_t PxuMbxInfStop ( PxuMbxInf_t mbxinf )

PxError_t PxuMbxInfClear ( PxuMbxInf_t mbxinf )

PxError_t PxuMbxInfChange ( PxuMbxInf_t mbxinf,


PxMbx_t mbx,
PxMsgType_t msgtype,
PxEvents_t events )

3[X0E[,QI,QLW initializes a structure of the type 3[X0E[,QIB7 at the address PE[LQI. It


is configured such that the mailbox handler signals the events in the event mask
HYHQWV to the calling task every time a message of the specified type arrives at a

mailboxPE[.

PVJW\SH shows the type of message that activates the mailbox handler upon arrival.
PXROS currently recognizes the values: 3;0VJ$Q\0VJ, 3;0JV3ULR0VJ and
3;0VJ1RUPDO0VJ . PXMsgAnyMsg activates the mailbox handler, UHJDUGOHVV RI WKH

PHVVDJH W\SH. The message type 3;0JV3ULR0VJ activates the mailbox handler only

when a prioritized message arrives and 3;0VJ1RUPDO0VJ only activates the handler
when messages ZLWKRXWSULRULW\ arrive.

3[X0E[,QI,QLW installs the mailbox handler, which remains inactive until it is activated
by the call 3[X0E[,QI6WDUW. If the specified type of message arrives after this function
is called, the mailbox handler becomes active.

HighTec EDV-Systeme GmbH 159 20. Mai 1996


PXROS V4 Users Guide Version 1.0

3[X0E[,QI6WRS is used to deactivate a mailbox handler. The handler does not become
active, even if the specified message type arrives, until the mailbox handler is
reactivated with 3[X0E[,QI6WDUW. In other words, the mailbox handler is still assigned
to the mailbox. The service 3[X0E[,QI&OHDU removes the mailbox handler completely.

3[X0E[,QI&KDQJH allows one to change the set up for the mailbox handler, i.e. to
change the values specified with 3[X0E[,QI,QLW. 3[X0E[,QI&KDQJH automatically
deactivates the mailbox handler. After the changes have been made, the handler must
be explicitely restarted with 3[X0E[,QI6WDUW, otherwise it will not be activated when
messages arrive.

 0HVVDJH3RROV

Creating messages dynamically can be very time consuming. It is much faster to


request a message from a mailbox. For this reason, messages can be created
beforehand and stored in a mailbox until they are needed. During the applications
initialization phase, it does not matter how much time is used to create messages; later
on however, this can reduce run time considerably. Message pools can be particularly
effective in applications that use messages of identical or similar size.

The services in S[XPVJSOF are used to create and delete a message pool.

PxError_t PxuMsgPoolCreate ( PxMbx_t *PoolMbx,


PxUInt_t no,
PxSize_t size,
PxMc_t srcmc,
PxOpool_t srcopool )

PxError_t PxuMsgPoolDelete ( PxMbx_t *PoolMbx )

3[X0VJ3RRO&UHDWH creates QR messages. These mesages use data buffers VL]H


bytes in size. The mailbox 3RRO0E[ is specified as the messages UHOHDVH PDLOER[.
Tasks request one of the prepared messages from the mailbox by calling
3[0VJ5HFHLYH . The memory required for the messages is taken from VUFPF, and the

necessary objects are taken from VUFRSRRO.

3[X0VJ3RRO'HOHWH deletes the message pool 3RRO0E[, along with all of the prepared

messages created for the mailbox. 3[X0VJ3RRO'HOHWH can only release those
messages that are in the mailbox. It is very important that DOO prepared messages are
returned to their release mailbox; otherwise, PxMsgRelease might cause a fatal
PXROS error since the message would no longer have a release mailbox to return to.
3[X0VJ3RRO'HOHWH also fails if there are tasks waiting for messages at the specified

mailbox.

HighTec EDV-Systeme GmbH 160 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 3URWHFWHG'DWD

PXROS does not offer any direct assitance for protecting data from unauthorized
access; however, it offers a kind of semaphore which can be used to protect specific
data. This entails using SURWHFWHG REMHFWV. Functions for protected objects can be
available in the files S[XREMB F.

Protected objects are implemented with the data type 3[X3REMB7 .

 3[X3REM&UHDWH3[X3REM'HOHWH

PxError_t PxuPobjCreate ( PxuPobj_t *Pobj,


PxSize_t objsize )

PxError_t PxuPobjDelete ( PxuPobj_t *Pobj )

3[X3REM&UHDWH creates the protected object 3REM with a data area of REMVL]H bytes in
size. The protected object is accessed by requesting and releasing specific services
(see below).

3[X3REM'HOHWH deletes the protected object, 3REM, and releases the memory it used.

This service may only be called when QR RWKHU WDVN has the right to access 3REM, and
no other task tries to request the access rights. If this is not the case, a call to
3[X3REM'HOHWH leads to a fatal PXROS error.

 3[X3REM5HTXHVW5HI'DWD

PxError_t PxuPobjRequestRefData ( PxuPobj_t pobj,


void **data )

PxError_t PxuPobjRequestRefData_NoWait ( PxuPobj_t pobj,


void **data )

PxError_t PxuPobjRequestRefData_EvWait ( PxuPobj_t pobj,


PxEvents_t events,
void **data )

With 3[X3REM5HTXHVW5HI'DWD services, the calling task requests exclusive access


to the protected objects data (i.e. via SREM). If the access right is available, the address
of the protected objects data area is stored in GDWD; otherwise, GDWD is set to .

HighTec EDV-Systeme GmbH 161 20. Mai 1996


PXROS V4 Users Guide Version 1.0

As with PXROS 3[5HTXHVW services, three different versions of this service are
available:

If access cannot be granted at the time the request is made, 3[X3REM5HTXHVW5HI'DWD


waits until it is available. 3[X3REM5HTXHVW5HI'DWDB1R:DLW returns immediatly with an
error identifier to indicate that the protected object was not available.
3[X3REM5HTXHVW5HI'DWDB(Y:DLW waits until acces to the data is given, or until one of

the events from the event pool HYHQWV is signalled to the calling task.

 3[X3REM5HOHDVH5HI'DWD

PxError_t PxuPobjReleaseRefData ( PxuPobj_t pobj )

This service releases exclusive access to the protected objects data (i.e. SREM).
Pointers received from a previous call to 3[X3REM5HOHDVH5HI'DWD FDQ QR ORQJHU EH
XVHG. This is not tested! If a task attempts references protected data after it is released,

it may receive inconsistent data since protected access is no longer guaranteed.

 0HPRU\5HTXHVWV

When using dynamically allocated memory, one must specify the same memory class
for every request and release. The task releasing the memory might not recognize the
memory class if it did not request the memory itself. For this reason, S[XPHPF offers
special services for requesting and releasing memory. These service solve this problem
internally, thus taking the burden off of the user. The prototypes for these services are
modelled after the standard C library services of the same name.

 PDOORF

Char *malloc ( unsigned int size )

VL]Hbytes of memory are requested from the calling tasks default memory class. If the
request fails, 0 is returned.

HighTec EDV-Systeme GmbH 162 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 UHDOORF

char *realloc ( char *old,


unsigned int size )

VL]H bytes of memory are requested from the calling tasks the default memory class.
When successful, the data is copied, beginning with the address ROG, and the memory
ROG is released. ROG must have been requested with FDOORF PDOORF or UHDOORF. If the

request fails, 0 is returned.

 FDOORF

Char *calloc ( unsigned int n,


unsigned int size )

Memory is requested from the calling tasks default memory class for an array of Q
elements of the size VL]H bytes. The requested area is initialized to 0. If the request
fails, 0 is returned.

 IUHH

Void free ( char *p )

Every memory area that was requested with PDOORF, FDOORF, or UHDOORF PXVW be
rereleased with the function IUHH. If the memory was requested in some other way (for
example, with 3[0F7DNH%ON), IUHH may QRW be used to release it.

 3;526,QLWLDOL]DWLRQ

To ease the initialization process in PXROS, 3[X6WG,QLW (in the file S[XLQLWF ) serves as
a simple interface.

PxTask_t PxuStdInit ( PxUInt_t objno,


PxAligned_t *firstblk_start,
PxSize_t firstblk_size,
char *inittask_name,
PxUChar_t inittask_prio )

This functions parameters correspond to those in VWG,QLW (see chapter 15.2 for details).
3[X6WG,QLW initializes PXROS as configured in the given parameters.

HighTec EDV-Systeme GmbH 163 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 7DVN&UHDWLRQ

To make creating tasks simple, the functions 3[X6WG7DVN (found in the files
S[XWVNB F) offer a simple interface.

PxError_t PxuCreateStdtask ( PxTask_t *Task,


char *name,
void (*fun) (PxTask_t,
PxMbx_t,
PxEvents_t),
PxUInt_t stksize,
PxUChar_t prio )

PxError_t PxuCreateStdtask_Tbl ( PxTask_t *Task,


char *name,
void (*fun) (PxTask_t,
PxMbx_t,
PxEvents_t),
PxUInt_t stksize,
PxUChar_t prio,
PxUInt_t tblimit )

PxError_t PxuCreateStdtask_Abort ( PxTask_t *Task,


char *name,
void (*fun) (PxTask_t,
PxMbx_t,
PxEvents_t),
PxUInt_t stksize,
PxUChar_t prio,
PxUInt_t abtframes )

PxError_t PxuCreateStdtask_Events ( PxTask_t *Task,


char *name,
void (*fun) (PxTask_t,
PxMbx_t,
PxEvents_t),
PxUInt_t stksize,
PxUChar_t prio,
PxEvents_t events )

3[X&UHDWH6WGWDVN corresponds to the function VWGWDVN described in chapter 3.1.

Because there are several versions of 3[X&UHDWH6WGWDVN, certain parameters are not
configured with default values:

3[X&UHDWH6WGWDVNB7EO does not set the tasks WEOLPLW to -; instead, WEOLPLt is used to
pass on this value. 3[X&UHDWH6WGWDVNB$ERUW defines DEWIUDPHV abort frames for the
task, thus allowing it to use the PXROS abort mechanism. Using
3[X&UHDWH6WGWDVNB(YHQWV , the created task is not immediately ready; rather, it waits

for one of the activating events specified in HYHQWV.

HighTec EDV-Systeme GmbH 164 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 7LPH&RQYHUVLRQ

3;526 WLFNV are the time units used in PXROS. To create portable code, it is helpful
when real time units can be specified in the program source. In this way, the developer
need not convert time periods into PXROS ticks by hand. S[XWLPHF offers several
conversion routines from realtime units to PXROS ticks.

void PxuTimeSetFreq ( PxUInt_t hz )

PxUInt_t PxuTimeGetFreq ( void )

PxTicks_t PxuTimeMsecToTicks ( PxULong_t msec )

PxTicks_t PxuTimeSecToTicks ( PxULong_t sec )

PxULong_t PxuTimeTicksToMsec ( PxTicks_t ticks )

PxULong_t PxuTimeTicksToSec ( PxTicks_t ticks )

Before conversion routines can be used, 3[X7LPH6HW)UHT must be called. This service
defines the frequency PXROS uses for time. K] contains the number of PXROS ticks
per second. This information can be retrieved with the service 3[X7LPH*HW)UHT. The
other services convert seconds or milliseconds into PXROS ticks, or vice versa. The
conversion may require that the value be rounded off. Details about how values are
rounded can be found in the header S[XWLPHK.

 5LQJ%XIIHUVZLWKZDNLQJIXQFWLRQV

Ring buffers are a useful medium for communicating information between handlers and
tasks. They are especially useful when the handler receives or passes a great deal of
data from or to a task. This is often the case when communication between the
application and a user is realized over a serial interface.

The header file S[XZUEK defines special macros to safely manage ring buffers with an
arbitrary number of elements. The ring buffer PXVW be used such that it is never read
from while it is being written to, and vice versa. This is the applications responsibility
since PXROS does not check it.

To keep the code size to a minimum, macros should be called via functions if they are
used repeatedly in the program. This does increase the run time slightly. Ring buffers
containing LQWHJHU and FKDU elements can utilize certain macros provided in the files
S[XZUEBLF and S[XZUEBFF. The ring buffer macros use a number of arguments. In

the following description, macros are treated like functions to illustrate the data types of
the individual arguments.

HighTec EDV-Systeme GmbH 165 20. Mai 1996


PXROS V4 Users Guide Version 1.0

3;8:UE'HILQH7\SH

void PXUWrbDefineType ( name, basetype )

A control structure must be created to manage a ring buffer. This macro defines a new
data type QDPH to manage a ring buffer consisting of elements of the data type
EDVHW\SH.

([DPSOHIRUDKHDGHUHQWU\

PXUWrbDefineType (PxuWrbInt_T, int);

The data type 3[X:UE,QWB7 is defined to manage a ring buffer consisting of LQW

elements. This data type is used as example in the following descriptions.

,QLWLDOL]DWLRQ

The application must provide the memory for the ring buffers control structure. This
structure can be allocated either dynamically or globally. If it is placed on a functions
stack, the function may not be exited; otherwise the address area would become
invalid.

Before it is used, the complete structure must be initialized. This can be done in one
step using the macro 3;8:UE,QLW. The structure can also be initialized in successive
steps by calling 3;8:UE,QLW%XIIHU, 3;8:UE6HW3XW&RQWUROV , and
3;8:UE6HW*HW&RQWUROV . The main difference is that the memory for the ring buffer

must already be available for successive initialization. When initializing the structure
with 3;8:UE,QLW, memory is requested dynamically from the calling tasks default
memory class. The parameters have the same meaning, regardless of the initialization
procedure used.

3;8:UE,QLW3;8:UE&OHDU

void PXUWrbInit ( PxuWrbInt_T *wrb,


unsigned int max_elem_num,
int (*put_wait_func) (char *, PxArg_t),
void (*put_wakeup_func) (char *, PxArg_t),
char *put_arg1,
PxArg_t put_arg2,
int (*get_wait_func) (char *, PxArg_t),
void (*get_wakeup_func) (char *, PxArg_t),
char *get_arg1,
PxArg_t get_arg2,
PxError_t *result )

void PXUWrbClear( PxuWrbInt_T *wrb )

HighTec EDV-Systeme GmbH 166 20. Mai 1996


PXROS V4 Users Guide Version 1.0

ZUE is the address of the ring buffers control structure. Using 3;8:UE,QLW, the
structure is merely configured. In this case, the memory for the structure must be
provided beforehand. The ring buffer contains PD[BHOHPBQXP elements. When
choosing the buffer size, realize that although a small buffer requires little memory, it
increases the risk of a full buffer when an element must be inserted. As mentioned
above, the memory for the ring buffer is allocated dynamically.

Attempts to insert or remove an element can fail if the ring buffer is respectively full or
empty. Waking ring buffers react to user-defined ZDLW and ZDNHXS functions. The ZDLW
function is called if the service fails. Once the service can be called successfully, the
ZDNHXS function is activated. These functions allow the following reactions:

the assignment is "forgotten". In this case neither the ZDLW nor the ZDNHXS

function is necessary.

wait until the job can be processed. In this case, the ZDLW function waits for
one or more PXROS events. The corresponding ZDNHXS function signals
these events to the task. The ZDLW functions return value is important: if it is
, the calling task tries to execute the job again once the ZDLW function is

finished. This try is usually successful. If the return value GRHV QRW HTXDO ,
the assignment is "forgotten".

as soon as the job can be processed, do so. Until then, other duties are
performed. To implement this algorithm, only the ZDNHXS function is
required. It signals a specified event to the task. When the task reacts to this
event, the corresponding ring buffer job is called.

SXWBZDLWBIXQF and SXWBZDNHXSBIXQF are ZDLW and ZDNHXS functions (respectively).


They are called when an element must be inserted into a IXOO ring buffer. Both functions
are activated with the arguments SXWBDUJ and SXWBDUJ. JHWBZDLWBIXQF and
JHWBZDNHXSBIXQF are used when a read request is made to an HPSW\ buffer. Both of

these functions use the arguments JHWBDUJ and JHWBDUJ. If neither a ZDLW or ZDNHXS
functions is required, its corresponding parameters are set to .

UHVXO
t reports whether or not initialization was successful ( UHVXOW = 0). The initialization
can only fail if the dynamic memory request for the buffer could not be fulfilled.
3;8:UE&OHDU releases the memory allocated for the ring buffer. When this function is

used, the ring buffer is no longer available.

HighTec EDV-Systeme GmbH 167 20. Mai 1996


PXROS V4 Users Guide Version 1.0

3;8:UEa,QLWB%XIIHUa6HW3XW&RQWUROVa6HW*HW&RQWURO

Void PXUWrbInit_Buffer ( PXUWrbInt_T *wrb,


basetype *wrbbuffer,
unsigned int max_elem_num )

void PXUWrbSetPutControls ( PXUWrbInt_T *wrb,


int (*put_wait_func)
(char *, PxArg_t),
void (*put_wakeup_func)
(char *, PxArg_t),
char *put_arg1,
PxArg_t put_arg2 )

void PXUWrbSetGetControls ( PXUWrbInt_T *wrb


int (*get_wait_func)
(char *, PxArg_t),
void (*get_wakeup_func)
(char *, PxArg_t),
char *get_arg1,
PxArg_t get_arg2 )

These three macros are used to successively initialize the ring buffer.
3;8:UE,QLWB%XIIHU PXVW be called first. This function allocates the memory area
ZUEEXIIHU as the buffer for the ring buffer structure ZUE. ZUEEXIIHU is the starting

address of a memory block that offers space for PD[BHOHPBQXP elements of the type
EDVHW\SH. The control functions that can be called when inserting/removing elements

are set to . This could overwrite previous entries, which is why this macro must be
called before the other two.

3;8:UE6HW3XW&RQWUROV specifies the functions and the arguments called when


attempting to insert an element into a full ring buffer. 3;8:UE6HW*HW&RQWUROV assigns
the functions called when attempting to read an element an empty buffer. The previous
chapter described how to set the individual parameters for the desired reaction.

3;8:UE*HW3;8:UE3XW

Void PXUWrbGet ( PXUWrbInt_T *wrb,


basetype *var,
PxError_t *result )

void PXUWrbPut ( PXUWrbInt_T *wrb


basetype *var,
PxError_t *result )

HighTec EDV-Systeme GmbH 168 20. Mai 1996


PXROS V4 Users Guide Version 1.0

An element is read from a ring buffer with the macro 3;8:UE*HW. If the buffer is not
empty, the result is copied to the address YDU, and UHVXOW is 0. If the buffer was empty,
but the job was succesfully performed after the ZDLW function returned, the empty buffer
remains unnoticed. If no ZDLW function was specified, or the wait-function returns a
value other than 0, than UHVXOW returns a1.

If the buffer is read succesfully, the ring buffer contains one element less than before
the read. If an attempt to insert an element into the buffer failed because the buffer was
full, the SXWBZDNHXS function is called (assuming it was defined).

3;8:UE3XW inserts an element into the ring buffer. If the buffer is not full, the element
YDO is copied into the buffer and UHVXOW is 0. If the buffer is full, but the assignment is
successfull after the ZDLW function returns, this full buffer remains unnoticed. If no ZDLW
function was specified, or the wait-function returns a value other than 0, UHVXOW returns
a -1.

If the element is succesfully inserted, the ring buffer contains one element more than it
did before the write call. If an element was not removed because the buffer was empty,
the JHWBZDNHXS function is called, (assuming it was defined)

3;8:UE*HW5HDG3RLQWHU3;8:UE$GYDQFH5HDG3RLQWHU

Void PXUWrbGetReadPointer ( PXUWrbInt_T *wrb,


basetype **ptr,
PxError_t *result )

void PXUWrbAdvanceReadPointer ( PXUWrbInt_T *wrb )

When elements are read with 3;8:UE*HW, they are always copied. If the ring buffer
contains complex elements, copying them increases the run time. Often times, a
pointer to the buffer's next element is sufficient. This can be requested with
3;8:UE*HW5HDG3RLQWHU . When succesfully executed, this macro enters the address

of the next buffer element in SWU. In contrast to 3;8:UE*HW, the element is not read.
3;8:UE$GYDQFH5HDG3RLQWHU actually reads the element as well. The SXWBZDNHXS

function can be activated with these macros are used, if space becomes available in
the buffer for a new element.

3;8:UE*HW:ULWH3RLQWHU3;8:UE$GYDQFH:ULWH3RLQWHU

Void PXUWrbGetWritePointer ( PXUWrbInt_T *wrb,


basetype **ptr,
PxError_t *result )

void PXUWrbAdvanceWritePointer ( PXUWrbInt_T *wrb )

HighTec EDV-Systeme GmbH 169 20. Mai 1996


PXROS V4 Users Guide Version 1.0

Inserting elements with 3;8:UE3XW always requires the copying of elements. With ring
buffers consisting of complex elements, this can increase run time considerably since
the element must be built before it can be copied. In these cases, it is usually
preferable to request a pointer to the buffers next element. This avoid the need for
copying the complex element. When succesfully executed, 3;8:UE*HW:ULWH3RLQWHU
writes the address of the next free buffer in SWU. The element is not truly entered until
3;8:UE$GYDQFH:ULWH3RLQWHU has been called. The JHWBZDNHXS function might also

be activated within these macros.

3;8:UE*HW(OHP1XP3;8:UE,V)XOO3;8:UE,V(PSW\

unsigned int PXUWrbGetElemNum ( PXUWrbInt_T *wrb )

PxBool_t PXUWrbIsFull ( PXUWrbInt_T *wrb )

PxBool_t PXUWrbIsEmpty ( PXUWrbInt_T *wrb )

3;8:UE*HW(OHP1XP requests the number of elements currently stored in the ring


buffer. 3;8:UE,V)XOO indicates whether the ring buffer is full (return value is 1) or not
(return value is 0). 3;8:UE,V(PSW\ indicates whether the ring buffer is empty (return
value is 1) or not (return value is 0).

 0HDVXULQJWKH6\VWHP/RDG

When developing a realtime application, it is important to estimate the system load


correctly; otherwise the systems periodic interrupt load may leave too little processor
time for the tasks to perform their jobs. The functions in S[XV\VOGF help measure the
available processing time and adjust the systems basic load accordingly.

3[X6\VORDG&DOLEUDWH

PxError_t PxuSysloadCalibrate ( PxTicks_t time )

This function calibrates a scale for the basic system load. 3[X6\VORDG&DOLEUDWH is
called after PXROS has been initialized and the PXROS timer has been started, but
before any other system load is present. This function measures the applications basic
load.

WLPH defines a time period over which the system load is periodically measured. Based
on this interval, a delay handler is activated once the measurements begin. This
records and saves the average system load over this period of time.

HighTec EDV-Systeme GmbH 170 20. Mai 1996


PXROS V4 Users Guide Version 1.0

3[X6\VORDG6WDUW0HDVXUH

PxInt_t PxuSysloadSartMeasure ( void )

3[X6\VORDG6WDUW0HDVXUH starts the continous measurements of the system load. The


function uses up the processor time that remains for the calling task and all other tasks
with a lower or identical priority. 3[X6\VORDG6WDUW0HDVXUH usually does not return, but
continues in a endless loop. The function is excited only after the measurements have
been stopped. Afterwards, no more measurements can be taken.

3[X6\VORDG6WDUW0HDVXUH is normally called during the idle tasks endless loop. This
allows it to determine the remaining processing time. This function may not only be
activated once while the application runs.

3[X6\V/RDG*HW0HDVXUH

PxInt_t PxuSysLoadGetMeasure ( PxuInt-t *Avg )

This function returns the average system load in the variable $YJ This value indicates
the percentage that exeeds the basic load. The system load is measured in intervalls.
The time span of these intervalls is set in the parameter WLPH with the function
3[X6\VORDG&DOLEUDWH . Only the last 64 measurements are returned.

This function must be called by a task that has a higher priority than the task that called
3[X6\VORDG6WDUW0HDVXUH . The result of the measurements can be requested as
needed.

3[X6\VORDG(QG

PxInt_t PxuSysloadEnd ( void )

This function terminates the system load measurement. Thereafter, measurements


cannot be taken again. Calling 3[X6\VORDG(QG causes 3[X6\VORDG6WDUW0HDVXUH to
return.

 0HVVDJHV

When tasks communicate with messages, it is useful to use similar data structures for
the messages (see chapter 5). The files S[XUHT F contain functions that support this
method of communication. These functions offer comfortable interfaces for handling
messages that use a set structure. This structure of type 3[X5HTB7 is defined in
S[XUHTK and can be evaluated or configured with the various services provided. Job

specific data is written behind the structure, where the application can read and write to
it.

HighTec EDV-Systeme GmbH 171 20. Mai 1996


PXROS V4 Users Guide Version 1.0

6\QFKURQRXV&RPPXQLFDWLRQ

3[XUHTVQF contains the function for synchronized communication, which are designed
to work correctly, even when aborted by the PXROS abort mechanism. The task-
specific data is used to accomplish this.

3[X5HT6\Q,QLW

Void PxuReqSynInit (PxuInit_t index )

Synchronized communication services use the tasks specific data. Using the
parameter LQGH[ (see section 23.1), 3[X5HT6\Q,QLW determines which data areas are
used. This function may only be used once, when initializing the application, and must
be used before the first service is called.

3[X5HT6\Q2SHQ

PxError_t PxuReqSynOpen ( void )

Each task must initialize its task-specific data with 3[X5HT6\Q2SHQ before any
messages can be sent.

3[X5HT6\Q

PxError_t PxuReqSyn ( PxuInt_t code,


PxMbx srvmbx,
Pxurep_t req,
PxSize_t size )

3[X5HT6\Q sends data to the server mailbox VUYPE[. The function then waits until the
receiving task responds to this request. This work is recognized when the receiver calls
3[X5HT$FN.

The waiting period can be aborted with PXROS abort mechanism. In this case PXROS
notes that the answer to the request is still out. If the answer arrives later, a future call
to 3[X5HT6\Q recognizes and releases the "old" answer, and continues to wait for the
answer to its request.

The calling function must provide the messages entire data area. It is VL]H bytes in size
and begins at the address UHT. A structure of type 3[X5HTB7 is located at the head of
the data area. This structure is not configured by the calling function. The job specific
data area is located directly behind this structure. The message receives the
assignment Id &RGH, which allows the receiver to interpret the data correctly.

HighTec EDV-Systeme GmbH 172 20. Mai 1996


PXROS V4 Users Guide Version 1.0

3[X5HT6\Q&ORVH

PxError PxuReqSynClose ( void )

3[X5HT6\Q&ORVH releases the resources being used for the task-specific data. The
function waits until all awaited messages have arrived. If the function is aborted with
the PXROS abort mechanism, 3[X5HT6\Q&ORVH may need to be called again.

$V\QFKURQRXVFRPPXQLFDWLRQ

void PxuReqSend ( PxMsg_t *msg,


PxMbx_t svrmbx,
PxUInt_t reqtype,
PxOpaque_t reqid,
PxUInt_t reqacktype,
PxMbx_t reqackmbx )

The sender only requires the service 3[X5HT6HQG for asynchronized communication.
0VJ specifies an existing message that begins with a structure of type 3[X5HTB7. The

job specific data must already contain the desired information. This service only
configures the message head and sends the message to the maillbox VYUPE[. UHTW\SH
specifies the message type, and the message receives the Id UHTLG.

UHTDFNW\SH and UHTDFNPE[ can be evaluated by the receiver 3[X5HT$FN. If


UHTDFNPE[ is 0, the message is released after it has been evaluated; otherwise, the

altered message is returned to the maillbox UHTDFNPE[ with the assignment type
UHTDFNW\SH.

5HFHLYHU6HUYLFHV

The receiver of an asynchronous message may also use certain functions on the
message. These are used to receive, evaluate and process the message.

HighTec EDV-Systeme GmbH 173 20. Mai 1996


PXROS V4 Users Guide Version 1.0

3[X5HT5HFHLYH

PxError_t PxuReqReceive ( PxMbx_t rcvmbx,


PxMsg_t *Msg,
PxuReq_t *Req
PxUInt_t *reqtype,
PxOpaque_t *reqid )

PxError_t PxuReqReceive_NoWait ( PxMbx_t rcvmbx,


PxMsg_t *Msg,
PxuReq_t *Req
PxUInt_t *reqtype,
PxOpaque_t *reqid )

PxError_t PxuReqReceive_EvWait ( PxMbx_t rcvmbx,


PxEvents_t events,
PxMsg_t *Msg,
PxuReq_t *Req
PxUInt_t *reqtype,
PxOpaque_t *reqid )

3[X5HT5HFHLYH takes a message from the mailbox UFYPE[. If 5HT is not equal to 0,
5HT contains the address of a received messages data area. UHTW\SH specifies the
message type, and ist Id is contained in *reqid, assuming these parameter do not point
to 0.

As with 3[0VJ5HFHLYH services, 3[X5HT5HFHLYH waits until the message arrives at


UHFYPE[ , while 3[X5HT5HFHLYHB1R:DLW returns immediately if the mailbox is empty.
This service returns an error code. 3[X5H5HFHLYHB(Y:DLW waits until a message
arrives, or until the task is signalled an event from the event mask HYHQWV. If no
message is given, 0VJ is set to 0 in all versions of htis service.

These services can only be used if the messages were sent to the mailbox with either
3[X5HT6HQG or 3[X5HT6\Q.

3[X5HT'HFRGH

PxUInt_t PxuReqDecode ( PxMsg_t Msg,


PxuReq_t *Req )

3[X5HT'HFRGH returns the type of the received message PVJ. If 5HT is not equal to
0, then 5HT holds the address of the messages data area. This service can only be
used if the message was sent with either 3[X5HT6HQG or 3[X5HT6\Q.

HighTec EDV-Systeme GmbH 174 20. Mai 1996


PXROS V4 Users Guide Version 1.0

3[X5HT$FN

Void PxuReqAck ( PxMsg_t *Msg,


PxError_t error )

After the message has been processed, the receiver calls 3[X5HT$FN. This function
evaluates the information contained in the message head. This should tell the receiver
what to do with the message after it has been processed. The message is either
released, or sent on to a mailbox. HUURU is then set to the messages error code.

HighTec EDV-Systeme GmbH 175 20. Mai 1996


PXROS V4 Users Guide Version 1.0

HighTec EDV-Systeme GmbH 176 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 *ORVVDU\

This glossary briefly describes important terms that are used in PXROS. Detailed
information can be found in the corresponding chapters.

 'HOD\-REV

A delay job is a request to PXROS to activate a GHOD\ KDQGOHU after a certain time. This
mechanism can be used to implement timeouts and periodic events. A delay job is
always associated with a delay object.

 (YHQWV

An event is an occurrence that is important to the system. PXROS assigns an event


mask to every task. If one of these events occurs, it can be signalled to a task. The
application is free to decide how the task interprets and reacts to an event.

 +DQGOHUV

PXROS differentiates between hardware interrupt handlers and software interrupt


handlers. The first type reacts to hardware interrupts, while the second type is triggered
with relevant PXROS services. Software interrupt handlers include delay handlers and
mailbox handlers.

All tasks are interrupted when a handler is executed. Handlers usually perform time
critical application jobs. Handlers use special versions of PXROS services, which are
recognized by the extension B+QG. A handler can communicate with a task by
signalling events to it, or by using shared global memory.

 0DLOER[

A mailbox is a PXROS object that serves as a multi-in, multi-out buffer for messages. A
task sends a message to a mailbox, where it is received by another task. Messages are
usually kept in the mailbox in the order they arrive. They are released in the same
order. If tasks are waiting for a message at a mailbox, the task that has been waiting
longest receives a message first.

HighTec EDV-Systeme GmbH 177 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 0DLOER[+DQGOHUV

A mailbox handler can be assigned to a mailbox. This routine is activated when a


message is sent to the mailbox. With this in mind, a task can use a mailbox handler to
implement a means of waiting at multiple mailboxes simultaneously.

 0HPRU\&ODVVHV

The systems dynamically allocatable memory can be divided into different memory
classes. This is an efficient way to manage memory and limit resource consumption
problems to certain modules. When using fixed block memory classes, the access time
for a memory request and release is considerably shorter than that required for variable
block memory classes.

 0HVVDJHV

Messages facillitate communication between tasks. They consist of a message object


and a corresponding data area. A task becomes the messages owner when it creates
the message, or when it takes the message from the mailbox. Once the messages
data area holds data, it is sent to a mailbox where another task can pick it up.

Usually messages are saved on a first-in, first-out basis. In other words, the first
message to arrive is the first message to be released. Some messages are "labeled"
SULRULW\. Such messages are released before non-priority messages.

 2EMHFWV

Objects are system resources that tasks can use to perform various duties. Unused
objects are stored in object pools until they are requested by tasks. Object types
include delay objects, message objects, mailboxes, memory classes and object pools.
In some PXROS versions, additional object types are available.

 2EMHFW3RROV

An object pool stores unused PXROS objects. Tasks can request these object as they
are needed. This mechansim also serves to limit resource consumption problems to
certain system modules by allocating objects to various UHDO REMHFW SRROV. 9LUWXDO REMHFW
SRROV also limit a tasks access to objects, but without requiring the physical distribution

of the objects. An object pool is a PXROS object itself.

HighTec EDV-Systeme GmbH 178 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 3ULYDWH0DLOER[

During creation, every task receives its own mailbox. This is called the tasks private
mailbox. A task usually waits for messages at its private mailbox.

 3ULRULW\

Control over the processor is regulated by the tasks priority. Of all of the ready tasks
(i.e. those not waiting for an object or events), the task with the highest priority
executes its program code first. It is interrupted if a handler is activated, or if a task with
a higher priority becomes ready. It also relinquishes control of the processor if it enters
a wait state.

The highest priority is 0, the lowest is processor-dependent (usually 15 or 31,


depending on the processor architecture). Processor control is granted based on the
tasks relative priority, not the prioritys absolute value.

 3;5267LFNV

A PXROS tick is the PXROS time unit, and is activated at regular intervals. The
PXROS system clock is increment with the periodic activation of the service
3[7LFN'HILQHB+QG . The length of these intervals defines a PXROS tick. Usually a

hardware timer is used to regulate the system clock.

 5HVRXUFH'LVWULEXWLRQ

Distributing system resources among the various application modules establishes a


sort of flow control. This allows one to restrict resource consumtion errors and
associated problems to a local level.

HighTec EDV-Systeme GmbH 179 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 7DVNV

In a PXROS application, different parts of application run simultaneously. These


modules are called WDVNV, and each one has its own execution context. A task performs
its job (i.e executes its 7DVN&RGH) almost independently of all other tasks in the
system. Almost the entire functionality of the application is implemented in tasks. Other
than tasks and PXROS itself, only handlers are available.

The different tasks run in quasi-parallel. Only one task is active at any given moment,
and only its code is executed. PXROS allocates control of the processor based on the
tasks priority and its status (ready or waiting). This is referred to as priority-based
scheduling.

 7LPH6OLFLQJ

Some versions of PXROS provide an additional time orientated feature: timeslicing.


Time slices are used in conjunction with the PXROS scheduling mechanism. Each task
is alloted a time credit. If the tasks time credit is used up, it is credited again and,
assuming another task at the same priority is ready, the next task is given control of the
processor. Tasks can be specified as exempt from timesliced scheduling.

HighTec EDV-Systeme GmbH 180 20. Mai 1996


PXROS V4 Users Guide Version 1.0

 ,QGH[

_EvWait 19, 54, 129


_Hnd 19, 177
A
Abort 54, 112, 127, 155
D
Delay Job 67, 70, 177
E
Event 15, 20, 25, 51, 68, 127, 177
H
Handler 14, 18, 67, 97, 177
I
Init Task 109, 114, 119
M
Mailbox 16, 19f., 83, 159, 179
Mailbox, Handler 33, 84, 141, 159, 178
Mailbox, Private 23, 25, 32, 83, 179
Memory Class 16, 19f., 108, 111, 154, 162, 178
Memory Class, Fixed 17, 61f., 154, 178
Memory Class, Variable 17, 61f., 119f., 155, 178
Message 14, 16f., 19f., 25f., 29, 83, 111, 141, 159, 171, 178
Message, Prioritized 17, 32, 160, 178
Message Pool 38, 83, 160
O
Object 16, 19, 89, 178
Object Pool, Real 18, 90f., 109, 178
Object Pool, Virtual 18, 89f., 178
P
Periodic Event 69, 179
Priority 14, 21f., 103f., 178
PXmon 9, 22, 118, 145
S
Scheduling 14, 21f., 103, 112, 141, 145, 180
System Memory Class 17, 20, 60, 63, 108, 114, 117, 119
System Pool 18, 109
T
Task 13f., 16, 19, 21, 103, 107, 164, 180
Task Specific Data 153
Task Stack 16, 21f., 109f., 114
Task Status 21, 24ff., 104, 112, 180
Timeout 54, 67f., 79, 177

HighTec EDV-Systeme GmbH 181 20. Mai 1996


PXROS V4 Users Guide Version 1.0

HighTec EDV-Systeme GmbH 182 20. Mai 1996


PXROS V4 Users Guide Version 1.0

HighTec EDV-Systeme GmbH 183 20. Mai 1996


PXROS V4 Users Guide Version 1.0

HighTec EDV-Systeme GmbH 184 20. Mai 1996


PXROS V4 Users Guide Version 1.0

HighTec EDV-Systeme GmbH 185 20. Mai 1996


PXROS V4 Users Guide Version 1.0

HighTec EDV-Systeme GmbH 186 20. Mai 1996


PXROS V4 Users Guide Version 1.0

HighTec EDV-Systeme GmbH 187 20. Mai 1996


PXROS V4 Users Guide Version 1.0

HighTec EDV-Systeme GmbH 188 20. Mai 1996