Sie sind auf Seite 1von 73

Clzapter 2 Module RTKemel

,-AskSrate Enumeradon type of all possible task states. A complete


list of the
I
task states is -iven in the section abrotit function
0 -
RTKGetTaskState.

-askHand-,-e Variables of this type can store a reference to


a task.
i

-ze.r,aphore RTKcmel semaphore type. The same type is used


for binary,
counting. and resource semaphores.

?.'ailbox RTKemel mailbox t).pc.

Variables

R,-.KHeapSemaphore Semaphore used b). RTKemcl to protect non-


rccntrant heap operations.

Task Management
This -section describes RTKcrnel operatio.,is for creadn-,
and man

C7
a?iln-, tasks.

Function RTKCreateTask

Any task of a pro-ram may create other tasks using this fu,-iction:
c

TaskHandle RTw@r@-az:eTask(7askF,--.-ictio,-. *Tasl-.Code,


S 1 C-. e Cl Pricr@@ty,
,,insic.-ed Stack,
@har *Aware)

Parameters:

-a.skCod@- Pointer to a paramet.-rless C function containing die code


to be executed by the new task. A-riy number of tasks may be create
d usinc, the same TaskFuncdo,-i. All these tasks perform the same
0

code, but each would have its own local data.

Priority Ureency of the new task as an integer bet-,veen I and 16.


The c
higher the priority, the higher is the ur-ency of the task. If the

c
priority of the new task is higher than that of the creating task, the
new task is immediately activated.

:-:rack The net stack required by the new task (in b@-ies). R-
I'Kz-rnel allo-
cates a memory block of corresponding size from th,, hcip and
provides it to the new task. Please note that the compiler's stackcheck
mechanism will work- for all tasks (except Boriancl C, near data). At
least during the program development lilia.@e, stack-chccking should
be turned on and the st,,ick@,; sl)oul(l be dimensioned generously. 40
96 bytes are sufficient for most tasks.

Task Maizageineitt

The actual size of the stack allocated by RTKemel is the sum of


parameter Stack, 256 bytes for interrupts and 27 bytes for RTKemel's
internal usage.

@j@.e Pointer to the name of the task. The name of the new
task is merely used for easy identification of the task. RTKernel only
copies the pointer pointing to the name. The.-cfore, the name should
not be modified after the task has belii created.
Tbc function value returned to the caller is a handle. It is a
reference to the
newly created task.

Tle handle must under no circumstances be directly manipulated by


the application. It is used by RTKemel internally. If a handle is man
ipulated direct]-,,, a pro?!ram crash can be expected.

Apart from the stack, RTKemel allocates a TCB (Task Control Block.
used bv RTKcmel internally) and a buffer for the math coprocessor (9
4 bytes) or the software emulator (272 bytes for Borland C, 368 bytes
for Microsoft C). Should RTKemcl be unable to allocate sufficient he
ap space, the program is aborted with a correspondin(, error incssacie.
Please note that creating a with d [d?!her priority immediately leads to
a task switch.

Function RTKTerminateTask

Function RTKTcrminatcTask need not be called norTnall-,,. The


iiatu,-2', termir,--don of a task happens when the task reaches the end
of its task furicdoil. Oni\. the Main Task terminates all tasks (and, co
nsequend\.. the whole Dro"ram) when it reaches the end of function in
ain, or when function exit is cdled.

vcid RTKTerm'@7,a@leTas@(TaskHardle *Handle);


Parameter Handle is a pointer to a task handle identifying die task to
b,- tcrrnl-ated. It must have been assigned a legal value by RTKCt-ca
t;-Task o.RTKCurrentTaskHandle. If an illegal value is passed @o R
TKTei-miiiateTa-,'t,-. the program is aborted with an error inessa!-,e.
RTKTcmiinatcTask- initiates a task switch if the task to be terminated
is the active task. Handle Is assi(,ned the, s@alUC NOTASK.

Prior to actually te@nadns! the task. RTKcrnel makes sure the task is
no[ occupying, a resource semaphore (see Section Seiilapliores). If
tlils 1,, the ca@.. the task continues running until all resources have b
een released. The task cal'@inc, RTKTer@nateTask does not wait unt
il this has been completed. but condnues c-unnin(y immediately.

User's Maiziial

Clzapter 2 Modiile RTKeniel

Stack and TCB of the task to be terminated are deallocated from the
heap, provl 'ded that *Handle does not reference the current.task. Tle h
eap memory of a ta,-,k ten-nliiating itself is released by the next call t
o RTKCreateTask or RTKDcallocTerminat,-dTasks. Until then, the tas
k still exists in the state Terrrunated; however, it cannot run any more.
Care should be taken that a task is not tern-tinated twice (e.g.. by
it.-,elf mid another task), because the task would not exist any, more
wii,-.n RTKTerminateTask is called the second time. RTKen, cl woul
d in this case abort the pro-ram with an error message, since the handl
e @votild ha\,c an llle,-,al value.

As in sequential pro?!ranis, ftjnc6on exit may be called at ln)7 tliiic to


(crillii)@I(C the pro-ram (and, consequently, all tasks). Function abort
should be @i@,ol(icd, however, because abort does not restore the
interrupt @,ectors manipulated f)V RTKemel or other modules.

Function RTKSuspend

Function RTKSuspend may be used to deactivate a task.


Stib@lcquentl\. d,,e task can only be reactivated by a call to function
RTKResuine.

vo'-d R-.@S-,lspend'7askHandle Handle);

Parameter Handle references the task to be de-acti@@ated. If the


task- is suspended. RTKSuspend has no effect.

Prior to actually suspending the task, RTKemel makes sure the task is
llot occupyin. a resource semaphore. If this is the case, the task conti
nues runnilic

c-
until all resources ha@.-, been released. The suspending task does not
wait unit this has been completed, but continues runninc, immediately.

Function RTKResume

RTKResume is the counterpart to RTKSuspend. A task suspended by


RTKSuspend may be re-acdvatl-d using RTKResume.

void RTKResume(-@-skHandle Handle);

If task "Handle" is not suspended, RTKResunie has no effect.

Function RTKSetPriority

Function RTKSetPriority serves to modify a task's priority.

void R@-Ksetprior-'@t:y(TaskFlandle Handle, unsigned Priority);

20 R7'Kf-
rt?,1-C 3.0

Tci.yk ,@laiza,@eiizeizi'
Parameters:

,:andle References the task whose priority is to be chanccd. @r@-ority


New priority of the task.

After a call to RTKSetPriodty, the scheduler performs a task switch if


-cquired.

Function RTKProtect8087

Besides the main processor, a task may use a math coprocessor. if


installed, or the 8087-software emulator. During a task switch, the sta
te of the coprocessor wl ill then also be saved and restored. Coproces
sorlemulator usage may be turned on or off using RTKProtect8087 an
d RTKFrec8087. RTKProtect80@7 turns on coprocessor protection if
it was previously @med off.

-,,oid RTKProtect8087(void);

The coprocessor task switch only takes place if actually required.

All Intel math coprocessors (8087, 80287, 80387, 80486 on-chip) as


well as the software emulator are supported.

Naturally, task switch time suffers if the coprc)cessor is used, since its
registers must be saved and restored durin. a task switch. If
benchmark RTBench ';S executed on a computer equipped with a copr
ocessor, the coprocessor task switch times will be displayed.

The default for a newly created task (as well as the Main Task) is that
coprocessor protection is turned on.

Function RTKFree8087
To turn off coprocessorlemulator usage, function RTKFree8087 may
be used: -.-o-d RTKFree8087(void);
In this manner, task switch time may be improved significantly,
depending on
0 c
the compiler and memory model used and the presence of a
coprocessor.

The default for a newly created task (as well as the Main Task) is that
coprocessor protection is turned on. If tasks should use the
coprocessor after havin@ called RTKFrec8087, calculations may yield
faulty results or the prorram may crash due to an error interrupt of the
coprocessor.

User's Maiiual
Clzapter 2 Alodiile RTKenzel

Enquiring Tasks

This section discusses all RTKemel operations serving to enquire the


properties of tasks.

Function RTKCurrentTaskHandle

Function RTKCurrentTaskHandle returns the handle of the task


currentl), runaing:

Tas',-@@--dle RTKCu----entTaskHandle(void);

Function RTKGetTaskStack

Function RTKGetTaskStack returns the remaining free stack space of a


task: u.-isigne@- RTKGetTaskStack(TaskHandle Handle);

Parameter Handle references the task whose stack is to be enquired.


To enquire le stack of the current task, RTKGctTaskStack(RTKCurrent
TaskHandleo) can be used. Please note that sufficient stack space for
interrupts must be available at all times.

Should RTKcmel find that the task concerned is using a forci-n stack
(c.... a DOS stack), the remaining free stack space cannot be determin
ed. In this case, the value OXFFFF is returned. The actual free stack
space can never have Cnl'S value.

Function RTKGetMinStack

Function RTKGciMinStack returns the least number of b@.tes itiit has


been free on a task's stack since it was created:

unsiann-4- RTKGetM'@-@stack(Tas)-,Handle Handle);

Parameter Handle references the task whose stack is to be enquired.

RTKemel initializes the stack memory of a task with the ASCII-code


of the letter "S". RTKGetMinStack searches the stack from bottom to
top for a b),te not havln,- @-alue 'S' to dete@ne how far the stack has
been used.

Function RTKGetTaskState

Function RTKGetTaskSiate returns the current state of a task:


TaskS-@aze RTKGet7askState(TaskHandle Handle);

22 R7Kei-iiel-
C 3.01
Etiqi,tiritig Task@

The result is of enumeration type TaskState. One of the following


values may
be returned:
Rear-ly The task is ready.
CurrenC The task is active.
suspende@- The task has been suspended by a call to RTKSuspend.
Delaying The task is waiting in an RTKDelay or RTKDelayUndl.
BlockedWai-@ The task is waiting in an RTKWait at a semaphore.
TimedWait The task is waiting in an RTKWaitTimed at a semaphore.
BlockedPuz The task is waiting to store a messace at a full mailbox.
BlockedGe@ The task is waiting to read a message from an
empty mallbox.
TimedPut The task is waiting with a dme-out to store a message in
a full mailbox.
T@-medGe@ 'ne task is waidnc, with a dme-out to read a i-
ncs@a?ic from an empty mailbox.
BlockedSe-d The task is waidn- -,n an RTKSeiid or the receiver
task.
BlockedR@-@eive The task is waitin. in an RTKReccl\,c to
receive dita.

c
-,-medSen@- 'Re task is waiting in an RTKSendTlmcd for the
receiver task.
TimedRee@-,-ve The task is waiting in an RTKReccix.eTlnied to
receive data.

'ne task is blocked in a send operation (message-pass'n-)

Dead',-oc@-,@-@ I ,
and the receiver task has been terminated -In the inezintime.

--!!@3aa" The handle passed does not reference an existing task.


E@.eny other RTKemel operation expecting a task handle a--, paramet
er will abort the program with an error niessa2e if an invalid handle is
passed to it.

Term@-na--@-d The task has te@nated itself by calling


RTKTcrrdnatcTask with its own handle or bx? reach;@ng the end of
its task function. The task cannot run in-,; more btit still exists. becau
se its memory has not yet been deallocated.

Usei-'s Maizual
Cizapter 2 Alodtile RTKeniel

Function RTKGetTaskPrio

Function RTKGetTaskPrio returns the priority of a task:


unsianed RTKGetTaskPri--(Task@andle

Parameter Handle references the task A-hose priority is to be efi


(i@jlrL,d.

Function RTKListTasks

Function RTKListTasks writes a list of all tasks currently exislin. to a


strin(,: vo@.d RTK@-'-sr-Tasks(char *Buffer, uns@-gned Bu.'ferLen,);
Parameters:

Bu@~fer Pointer to the strinc, variable to -store the text in.

@-u~@@'erLen Lcn-th of the strin. pointed to by Buffer. Buffer


should be at lcwt

c L-
approx. 150 + (70 * number-of-tasks) bytes lonc,

01
RTKLIstTasks writes up to BufferLen characters to the buffer.
IZI'KLisiTa@1-1@ returns the following information for each task:

1. Name of the task.

2. Priority of the task.

3. State of the task.

4. If the task is blocked in a timed operation, the time of i-e-actl


\.;itioil.

5. The return value of RTKGetTaskStack (------- if the task is


uslii!-, a stack other than its oA@n).

6. The return value of RTKGetMinStack.

7. Usage of the coprocessor.

8. If the task is blocked at an RTKemcl-lntemal semaphore, the


reason for the block is -Oven.

The last field (WaldngAt) can contain any of the following stnnes:

DOS Call The task is waiting to be permitted a DOS call.


R-KHeapSeT.aphore The task is waitinc, to call malloc or free.
D-@sk BIOS The task is waitin. to be permitted a floppy disk or
hard disk operation.

HD-Compleiion The task is waiting for the end of a hard disk


operation.

@D-Co.mpleiion The task is waidne for the end of a floppy disk


opei-,itioll.

24 RTKcritel-C3-0

Titize

Network The task is waiting for the end of a net-,k;ork- operation.

Task-Name For tasks in the state BlockedSend or TimedScnd, the


name of the receiver task is given.

RTKListTasks is intended for debugging purposes.

Time

For a real-dme system, time is of great importance. RTKemel


maintains- an interrupt-driven clock which may be set and read. Furth
ermore, tasks may block themselves for a certain time span i.-i order t
o make CPU-time available to other tasks.

Time is expressed in tiiizer ticlw. RTKemel- uses d]C type Ti.-.ie to


Store dll]CS

and the type Duration to store time intervals. Time and Duration have
type 216 , signed long. The PC's timer hardware usually -cnerates
approx- interrupts

c'

per hour (or approx. 18.2 interrupts per second) if the interrupt rate
has not been changed usin. module Timer. To simplify the discussion
in this ,@ccdon, It assumed that the timer-interrupt rate is not modifie
d-

Since RTKemel's clock is limited to a precision of 32 bits, an


overflow can occur after about 3.7 years. If the clock is initialized
with a value of -214748364C-. an overflow only occurs after about 7.
5 years. RTKerrel does not recognize an overflow; applications runnin
. for Ion-er time spins niu,,t therefore re,,ularly reset RTKemel's clock.
Please note that the overflow will occur after a shorter time span, if th
e clock is running faster than default. With a dmer-interrupt rate of 1
000 Hertz (I.e., I timer tick = I millisecond), an ovci-flow will occur a
fter 25 or 50 days, respectively.
Function RTKSetTime

Using function RTKSetTime, RTKernel's internal clock may be set.


void RTKSe--Ti-me(Time Ne,.,Time);

Parameter NewTime is the new value for RTKemcl's internal clock.


RTKemellnit calls RTKSctTlme(O).

The behavior of tasks ivaltinc,, in an RTKDelay, RTKDela),Undl. or a


tliiicd operation is not affected by RTKSetTime.

Usei-'s Maizrial

Cliapter 2 Module RTKenzel

Function RTKGetTime

Usina, function RTKGetTime, RTKemel's clock may be read.


T'-r.e RTKGetTi,7.@-,.void)
The return value is the current time of RTKemel's internal clock. If
RTKSC[Time has not been called, RTKGetTime returns the number of
tinier ticks procrram start (up to about 3.7 years).

c
Function RTKDelay
RTKDelay blocks the calling task for the specified time span and
other tasks having the same or lower priorities to-r-un.

vo'-d R-,KDelay(r-,-,rat:ion Ticks);

Parameter Ticks specifies the number of timer interrupt--, the ta-sk is


to be blocked. Please note that the actual time interval of suspension
@?311 lie in the ran?!e [ (Ticks-1)118.2.. Ticks/18.2 1, depending on
how lonc, a.o the last timer interrupt occurred.

If RTKDelay is called with Ticks <= 0, RTKemel cheeks @@,liether


other tasks with the sai-ne priority are Ready. In this case, the task n
ot lia@,iil?Z run lon?est 1"@ activated. Consequend5,, RTKDelay(O)
may be used to iiiiplejiieiii @-oiiiid-robili scheduling, also known as c
o-operative time-slicitig.

t>

Function RTKDelayUntil
Tasks wisffin- to continue running at a certain time may use
RTKDelayUntil: vo@-d RTKDelayU-::il(Time Ticks);

Parameter Time specifies the absolute time for the task to continue.
RTKDelay. on the other hand, interprets its parameter as a time
interval during which the task should not run.

Function RTKTimeSlice

The term dme-sllcln- denotes forced task switches after a certain time
span, if other tasks having the same priorities as the active task are Rc
@idv. Function RTKTimeSlice activates this algorithm:

void RTKTimeSl-'-=e(Duration Ticks);

Ticks defines the maximum time span a task is allowed to run before
another task is activated. If Ticks <= 0, time slicing is disabled (RTK
cmel's default).

Seiii,apliores

Time slicin?! only comes into effect when several tasks having the
same priority are Ready and no tasks having a higher priority can run.
If, for example, three tasks of priority 7 are Ready and another of prio
rity 8, only the task of priority 8 ill run. As soon as this task blocks i
tself, however, the other three are acUwl
vated in turn after Ticks dmer ticks.

Semaphores

Semaphores are a popular mechanism for synchronlzinp- tasks. A


semaphore may be thought of as an event counter which can never be
come necative. A semaphore is created using RTKCreateSema and m
ay subsequently be referenced by any number of tasks, using the funct
ions described in llils section. A program may use any number of se
maphores..

Function RTKSignal stores an event in a semaphore; RTKWait


retrieves an event from the semaphore. if one is available; otherwise. it
waits until an event is si,,naled. RTKcrrici distinguishes three types of
semaphores: counting binan,. and r;--sourcc semaphores.

Countina, sc-iapliores can store up to 65535 events. They are suitable


for -cnera] synchronization purposes.

Binary semaphores cannot count, they can only assume, the values 0
and 1. Function RTKSignal will always set a binary semaphore to valu
e 1. even if it already has a value of 1; RTKWalt always sets its valu
e to 0. Countin?! and binary semaphores are equally fast; so binary se
maphores should not be used only for performance reasons.
Resource scnaphores are especially suited for resource management
(resource management is discussed in detail in Chapter 5, - Mlitiial Ev
clLisioiz). A resource semaphore guarantees die priority of a taste occ
upying a resource to be at least the maximum of the priorities of all ot
her tasks also requiring the respective resource. This technique is kno
wn as priori@, ittliet-itaizcc. A task rccucstine a resource using', RTK
Wait hands down its priority to the task occupyln?, the resource. @s
makes sure that a high-priority task is ncvci, unc@-ccssaril@. blocked
b\- a task of lower priority.

Another property of resource semaphores facilitatcs safe termination


and suspension of tasks. A task can only be suspended or terminated
immediately. if it does not occupy anv resources. Otherwise, it contin
ues to run until it has released all -csotirces and subsequently suspends
or terminates itself.

U,@er's Manual
2-1

Citapter 2 Module RTKeniel

Compared to other semaphore types, there are two important


restrictions: resource must always be released (using RTKSlgnal) by th
e task that ha( acquired it using RTKWait. A task can occupy an-@
number of resoultes simul taneously. However. it must release the res
ources exactly in the revers( sequence as they have been acquired. Ex
ample:
RTK;.;ait(R1);
RTK@,'ait(R2);
RTKSicr,ial (R2)
RTKsignal(R1);

If the sequence of RTKSicnal calls were exchan<,ed. RTKcmei's


debti. version would abort the pro-ram with an error messace. Since t
he debtl,, i,ersioii cai check for compliance to the rules for resource se
i-nip,,,,-)rcs. cj-.ors like thosi described in Chapter 6, Deadlock cannot
occur. Tlii,@ i,@ @,.no:lier iniportan advanta-c of resource scmaphor
es.

Resource semaphores are, because of these rules, not suited for


interrup handlers.

RTKHeapSemaphore and the internal semaphore for RTKemel's DOS-


protec don are resource semaphores.

The following, example serves to show how a semaphore can be used


for task, synchronization. -

Assume Task A is to be activated when Task B recognizes an event


(input ol the letter 'A'). Task B is the main program.
,@@-nc-@-ude <stdio.',>
@1.inc'l-ude llrtkern-21.h'
@r@-nc'4-ude 'Irtkeybrd.h'

Semaphore S;
void TaskA(void)

P--intf(,Task A -'@s waiting at semaphore RTK'o,'ait (S) ;


prinef(l\ntask A has resumed runn-'-ng\n"/;
void main(void)
char c;

28
RTKerii@,I- C 1.01

Sei?iaplzores

RTKerr.elInit(3);
RTKeybrdInit();
S = RTKCreateSema(Court-@'ng, 0);
RTKCreateTask(TaskA, 4, 1024, 'Task A,); do {
pr@-ntf('Please enter a capital 'A'\n,); c = RTGetCho;
pr@-ntf('Ke,,, pressed: %c\nl, c); while (C != 'A');
RTKSianal(S);
The semaphore is initialized with 0 events. Task A has a higher
priority and is therefore started immediately after RTKCreateTask. Its
second statement is RTKWait(S). Since there are no events stored, Ta
sk A is blocked and the Main Task runs until the event (input of letter
'A') has arrived. When the attain Task executes statement RTKsignal(
S), Task A is immediately activated a-rd retrieves the event. Both tas
ks then -un to completion and the procra!ii ates.

A ty,pical use for a binary semaphore would be, for example.


communication between a task -cneradn- data (Task A) and a second t
ask p,-ocessiiis@ die da:,i (Task B). Task A sltnals to Task B that da
ta has been -c.-icrated usin,' semaphore. If Task A creates data faster
than Task B cm process it. Task would continually try to catch up, si
nce the countin@ semapl-,ore stor,-s all si@nals from A. even when t
he corresponding data is not available ans, more. If. 0'11 the other ha
nd, the semaphore is binary, it m,-rely indicates to Task- B whctliz-@
data is available or not. Task B would never read the same data i-,@.
ice, bu, could skip single data records.

Function RTKCreateSema

Function RTKCreateSema serves to create and initialize semaphores.


A semiphore must under no circumstances be used before it has been i
nitialized.

Semaphore RTKCreateSema(SemaType @ype,


uns-'gned
Parameters:

Type of the semaphore. Values Countinc,, Bin,@', ard Resource are


valid.

User's Ma7ziial

Clzapter 2 Modiile RTKer7zel

-r,i-ialValue The number of events toinitialize the seniaplioll@,


@'@ith. For
binary semaphores, InidalValue must be 0 or 1. fo,- resou,-ce
semaphores, it must be 1.

RTKCreateSema allocates the semaphore using rnalloc. The reign


value l@ reference to the new semaphore.

Function RTKSemaValue

Using function RTKSemaValue, the number of may be enquired. It


never leads to a task.s",Itch.

unsig-,ed RTKSer,.aValue(Seiaphore S);


Parameter S references the semaphore to be enquired. The number of
even@'s returned.

Function RTKResourceOwner

Using function RTKRcsourceOA,ner it may be enquired, A,hich t,-.@k


curr@-7,@il occupies a resource. This function can only be used for
resource s@-,-naptior@,.

unsianed RTKSen@aValue(Ser.=-Phore S);

Parameter S references the resource semaphore to be enquired. If


sciiiip,]()l is free, the function returns the value NOTASK; otherwise,
die 'F@,@klian(lizl the task occupying the resource is returned.

Function RTKSignal

RTKSiznal stores an event in a semaphore. @,oid RTKSignal


(Semaphore 5);

S references the semaphore that Is to store the event. If one or ;-.-,ore


@ks ai waiting at the semaphore, the task that has been waiting
longest is made Read, If its priority is hicher than that of the canine, t
ask, it is activated immediately.
If no task is waiting at the semaphore, the event is stored. A counting
sern@ phore can store up to 65535 events. The application should
make sure that th limit is not exceeded.

Attempting to set a resource semaphore to a value > I using


RTKSi@nal resul
in an error messa-,e and abortion of the pro-ram.

0
If S is a resource semaphore, the priority of the active task is ne"-]@.
determine following die rules of priority inheritance.

a sc[iia,,)hore con,,i@n

Seiiwphores

Function RTKWait

RTKWait retrieves an event from a semaphore:


void RT:Cilait(Semaphore S);

S references the semaphore the event is to be retrieved from. If no


event is available, the calling task is blocked. It can only be
reactivated by a different task canine, RTKSignal for the semaphore.

0
Any number of tasks can wait for events at a semaphore. The tasks
are re-acdvated in sequence of their priorities.

if S is a non-empty resource semaphore, the requesting task's priority


is set to the priority of the active task, if this is higher. After the call
to R'FKWait, the active w@ occupies the resource semaphore. It cann
ot be suspended or terminated until it has released all its resources.

Function RTKWaitCond

RTKWaitCond (wait conditional) retrieves an event from a semaphore


under

the condition that one is immediately available. RTKWaliCond never


leads to a block-i'n- task switch.

bocl R@:<-,..,'a@-tCc.-id(Seraphore 5)

S references the semaphore the event is to be retrieved from. If the


return value is true. a sl?!nal was retrieved, otherwise noL

Function RTKWaitTimed

Usin2 function RTKWal(Ti-ned, a dmc-out for the a@s-al of an


c@7c.,it may be spec] 'fied.
bool RT-@aitTined(Se7.aphore S, Duration
Parameters:

S The semaphore to wait at.


'i,neou:: The max'

imum time (in dmer ticks) to be waited for the irfival of an event.

If the return value is true, an event was retrie,,,ed; otherwise, no


c@,ciit \vas avillable and the dmc-out has expired.

User's Afatiiial

Clicipter'@7 illodiile RTKel71CI

Mailboxes

The previous section covered semaphores. which may be employed to


s@ii chronlze tasks and thus provide a mechanism all'o@ing orderly.
inter-tgisk coil]-

municadon using global data.


Howes,cr. communication via global data is hard to keep track of and
errorproiic, since a task might "forcet" the required semaphore operatio
n before accessing die data. Nloreover. no protocol has yet been intro
duced for a controlled exchui(,c of data.

.@lailboxes serve to close this ?!ap. A mailbox is a data buffer that


can store a fixed number of itiessages. As implemented by RTKcmcl,
nic.@a?!es may hx%,, any size and die size of iiiailboxcs can be freel
y configurecl (til) to 64 kbytes).

Tasks can store messa-es in a iiiailbox. Should the mailbox be full,


the task I'@ suspended until space becomes available.
Tasks can also retrieve niessa@es from mailboxcs. In this case. the
task is siispended if no inessa(,es are available in the mailbox.

Any number of tasks may use the same mailbox for sto 'rip

n _- and retiicviticy nies@ac,es.


c,
,@lailboxcs use the FIFO-al-odthm (first in, first out), i.c., mcssa{,cs
@ic retrieved from a mailbox in the same sequence as they have been
stored.

The following sections discuss how to use mailboxes with RTKcrriel.


As an example, we shall now extend the little semaphore dcino pro-
rani foi mailboxes- In addition to a si-nal. data can now be sent to ano
ther task:

"include <stdio.h>
#include Irtkernel.h'

#define Slots 7

14ailbox Box;

void TaskA(void)

int: i-;
prir.r@L('Task A is Jangling at r,,ailbox\n,);
RTKGer(Box, &i);
printf("\nTask A has received a %i\n', i);
32 RTKertiel-
C

Mailb(yxes

void main(void)

int i;
RTKernelInit(3);
Box = RTKCreateMailbox(sizeof(int), Slots); RTKCrear-eTask(TaskA,
4, 1024, 'Task A"); do f
printf('Please enter a nurnberlln,);
fflush(stdin);
while (scanf(l%i,,, &i)
RTKPut(Box, &i);

Function RTKCreateMailbox

Function RTKCreateMailbox creates and initializes mailboxcs. An


uninidalized mailbox will only be recognized by the debug version of
RTKcmel; the standard version will crash when an uninitialized mailbo
x is used.

Mailbox RT.KCreatemailbox(unsigned Ea@-aLen, unsigned Slc:s);


Parameters:

DataLen Len _gth of the niailboxes' messages in bytes.

Slots i\,laxiiiium number of niessa-es the mailbox can.store. The


product

n
of DataLen and Slots must not exceed 64 kbytes (less a few b@rtes
o@,crhead).
RTKCreateN4ailbox allocates the mailbox usiii. malloc. The return
valu-- is a reference to the new mailbox.

Function RTKDeleteMailbox

Function RTKDeleteMailbox releases the stora?!c used by a iiiailbox:


void RTK2e!-eteMai-,-box(Ma,'-!Box *Box);

RTKcmel checks whether a task is waiting at the mailbox. If so, the,


procraill is aborted with an error messace. The application must make
sure that deleted mailboxes are not used any more. RTKemel assigns
*Box tlic, value of constant NOMAILBOX.

User's Maiiual
3

Clzapter 2 Modiile RTKeniel

Function RTKMessages
Function RTK-N4essaces returns the number of messares currently
stored in a 'Ibox.

c r-.s PTKI.,es --e S (m a -,. '-box Box);

Box specifies the mailbox to be enquired. The return @,altic x@.ill


always lie between 0 and the value of parameter Slots passed to RTK
CreateMailbox when the mailbox was created.

Function RTKPut

RTKPut stores a message in a mailbox.

void RTKPut: (Ma@-1b@x Box, void 'Dat:a)


Parameters:
Box The mailbox to store the message in.

@ata Pointer to the data to be stored in the niailbox.

If the mailbox is full, the calllnr task is blocked until ano,,her task (or
all lliter-
r-,ipt handler) retrieves a messa-e. Should the mailbox bL- empty,
ho,,s,cver, iii(l
0

another task is waltinfi for a ii]cssa,,,e at the niailbox. the


Ready. If it has a hicher priority, it is immediately acti\@at@d.
Function RTKGet

RTKGet retrieves a message from a mailbox. void RTKGet(Mai'.---ox


Box, void *Da--a); Parameters:
Box The mailbox to retrieve the messace from.
tp
Data Pointer to the i,an'able to store the message in.
If the mailbox is empty, the calling task is blocked until another task
(or an interrupt handler) stores a message. Should the mailbox be full,
however, and another task is waiting to store a message in the mailbo
x, the awaiting task is made Ready. If it has a hi-her priority, it is im
mediately activated.
tisk is iiIII(IC

34 RTKertiel-C
3.0

Mailboxe3
Function RTKPutCond

RTKPutCond stores a -nessa,,

,c in a mailbox under the condition that space is


available in the inailbox. RTKPutCond never leads to a blockinc, task
switch. If

cl

the mailbox is full, this is indicated by the return value and no data is
Iraiisferred.

bool RTKPutcond(,-!a-'-!box Box, void *Dat:ai;


Parameters:

Box 7le mailbox to store the message in.


Data Pointer to the data to store in the mailbox.

If the return value is true, the message has been successfully stored;
otherwise,
there was no space available in the mailbox.
Function RTKGetCond
.RTKGctCond reuic@,es a message from a mailbox under the condiu-
on that or.L is available immediately. RTKGetCond never leads to a
@iock-jnc, las'fl- switch. If the mailbox is empty,, this is indicated by
the return @-alu,- and no daa is transferred.

bool FTKGelcond(,.,a@-@-.sDx Box, void *Dac:a,;


Parameters:

Box The mailbox to retrieve the message from.

Data Pointer to the variable to store the message in-

If the return value is true, the messace has been successfully, rct-
rie,..cd-. other-
wise. there was no message @i,ailable in the mailbox.
Function RTKPutTimed
RTKPutTimed stores a mcssa,,e in a mailbox if space b,-corncs
available w'dl' a certain time span.

bcol RTK@zutTimed(mai---@ox Box, void *Dat=-, -t,-@tion Ti-eouc);


Parameters:

Box The mailbox to store [he message in.


Data Pointer to the data to store in the mailbox.

Uscr's illaiiiial 35

Citapter 2 Module RTKentel


Timeour Tirne-out for waiting until space becomes a@@ailable in
the inailbo.,@ (in timer ticks).

If the return ,,alue is true, the 'Message has been 'Sutcessfully sto@-,d;
othen@'is.,
there was no space available in the mailbox and the time-out has
expired.

Function RTKGetTimed

RTKGetTimed retrieves a messa-c from a mailbox if a licssa-e


beconi,-s able within a certain time span.

bool @7-@'GetTimed(.?.,ailbox Box, .,--@-d Parameters:

Box The mailbox to retrieve the messace from.

t>

Data Pointer to the variable to store the message in.

Timeout Time-out for waiting until a messace becomes available in


the mail box (in timer ticks).
If the return value is true, the messa-e has been successfully reuieved:
other wise, there was no message available in the mailbox and the
dme-out ha., expired.
Function RTKNextCond

Function RTKNextCond enquires the next messa,,e of a niailbox under


the condition that at least one message is available. But, unlike
RTKGetCond. the message is not retrieved. RTKNextCond never lead
s to a task switch.

bool RI.J-NextCond(.@lailbox Box, vo@-d *Data);


Parameters:
Box The mailbox from which to enquire the message.

Data Pointer to the variable to store the message in.

If tile return value is true, at least one message is available in the


niailbox an(
*Data contains a copy of the message; otherwise, there @s;as no
message avail able in the mailbox.
Message-Passing

As an alternative to mailboxes, RTKernel offers messa@e-passin?! as


a rnechail. ism for inter-task communication. In messa-e-passin.. no
data objects likt
36
RTKerizel-C 3.@

l@fessag@@-Passiti,@

semaphores or mailboxes are required for intermediate data stora,,e;


data is copied directly between tasks. Messaee-passinc, may be thoug
ht of as a mailbox of size 0.

A fundamental difference to mailboxcs is that the sending task


explicitly specifies the receiving task. A receiving task, on the other
hand, can accept data from any other task. With mailboxes, any task
may use any mailbox; a sending task cannot determine who is to recei
ve the data, and a receiving task does not know who sent the data.

Another difference is the lack of a data buffer. Therefore, the sending


as well as the receiving task must be ready for the data transfer before
data can be copied. Thus. if two tasks want to exchanoe data usin.
message-passing, the first task is blocked when it reaches its RTKsend
or RTKReceive until die second task in turn reaches its respective RT
KSend or RTKReceive. The data transfer then takes place and both ta
sks can continue runnin.. Mailboxes do not provide such a ti-ht coupli
n., c.-., a task can immediately continue running after a Put opcr-
fz
auon, even if there was no task ready to receive the data.
cvlessage-passing may also be used solely for synchronization. In this
case, the
receiving task specifies a data len-th of 0. The pointers to the data
may assume
0

the value NULL, since RTKcmel does not per-form a data transfer.

The tight coupling bc@veen tasks and the lack of data buffering
in ,cncral disqualify this mechanism for use by interrupt handlers; tio
@k,evcr. it may also be used by interrupt handlers.

The little mailbox demo program can now be modified foi- message-
passin-,' Instead of storing the data in a mailbox, it is passed directly
to another task:

-include <scdio.h>
'-include 'rtker,-iel.h'

'd Tas'@@(void)

@-nt i;

print@-('Task A is @.iaitina for da:=-\n,); RTKRe--@-,-ve(&i, sizeof


(i)),print--("\nTask A has received a @i-\n", i);
User's Maiiiial
37

Chapter 2 Modiile RTKeniel

void main(vo--d)

int i;
TaskHandl=- handlea;

RTKernelInit(3);
HandleA = RTKCreateTask(TaskA, 4, 102", 'Task

do
printf(,Please enter a number\n'); 'Lflush(stdin);
@.,,hile &i) 1);

Function RTKSend
RTKSend sends data to another task.

void RTKSend(TaskHandle Receiver, void 'Da@a);


Parameters:
Rece@Iver Handle of die task to receive the data. -@ata Pointer to the
data to be sent.
If the receiving task is waiting in an RTKReceive or RTKReccl
\.cTlmed, data transfer takes place immediately and the task with high
er pn'orit@@ contini ninnin-,. Otherwise, the sending task is blocked
until the receivitie task is rc to accept the data.

Function RTKReceive

RTKRecelve receives data from any other task.

void RTKRece--ve(void *Data, unsigned Da-laLen);


Parameters:
Data Pointer to the variable to store the received data in.

Daz:aLen Length of the expected data.

If a task sends data using RTKSend or RTKSendTlmed to @i


receiving ti
blocked in RTKReceive, the data transfer takes place immediately,
and the ta
with higher priority continues running. Othenvise, the receiving, task
is bloom
until another task sends data.

Message-Passitig

Function RTKSendCond

RTKSendCond sends data to another task under the condition that the
receiving task is immediately ready to accept dat@ otherwise, the
return value indicates failure and no data is transferred. RTKSendCon
d never leads to a block-in. task switch.

bool RTKSendCond(TaskHandle Receiver, void *Data);


Parameters:

Receiver Handle of the receiving task.


Data Pointer to the data to be transferred.

If the return value is true, the data transfer has been successfully
completed; otherwise, the receiving task was not ready to accept data.

Function RTKReceiveCond

RTKReccisreCond receli,es data from any task under die condition that
a task is immediately ready to send, otherwise, the return value
indicates failure and no data is transferred. RTKReceiveCond never le
ads to a blocking task switch.

bool RTKRece@-veCcnd(void *Data, unsi@ed DaiaLen);


Parameters:

Da@a Pointer to the variable to store the received data in.


Dar-aLen Length of the data expected.

If the return value is true, the data transfer has been successfully
completed.. othenvise, no task was ready for immediate data transfer.

Function RTKSendTimed

RTKSendTimcd sends data to another task if the receivir,@- task


becomes ready to accept data within the dmc-out; othenvise, the return
uc indicates failure and no data is transferred.

boo! R-K5endTimed(TaskHandle Receiver,


void *Dat:a, @uration Ti-,ieout);

Parameters:
Receikrer Handle of the receiving task.
User's Manital
39

Cllapter 2 Module RTKeniel


Dar-a Pointer to the data to be transferred.

Timeout Time-out for waiting until the receiviho task becomes


regdy to accept data (in timer ticks).

If the return value is true, the data transfer has been successfully
completed
otherwise. the receiving, task was not ready to accept (1@it@i and the
dine-out h expired.

Function RTKReceiveTimed

RTKRecei@,eTlmed receives data from any other task if a task


becomes read). send data within the dme-out; otherwise, the return val
ue indicates failure and no data is transferred.

boo! R7KReceiveT'-med(void *Data,


unsigned DataLen, Duration Timeout);

Parameters:

Dara Pointer to the variable to store the received data in.

DataLe--i Len(,th of the data expected.


Timeou@ Time-out fo7 waidn- until a task becomes reader to send
data (in timer ticks).

If the return value is true, the data transfer has been successfully
completed otherwise, no task was ready to send data and the dme-out
has e>-.pired.

DOS and BIOS

The operating system MS-DOS/PC-DOS does not provide for


niultltaskTherefore, a multitasking system like RTKemel must offer sol
utions to problems encountered when runninc, under DOS (c.-., DOS's
non-reentranc,

One of the main reasons for DOS being non-reentrant is that it uses
its stack. If a task were to perform a DOS call even thou(,h adothcr
task bad completed its DOS call, DOS would re-initialize its stack and
thereby dcs the return address of the first task. A system crash would
llicxltat)ly follo the next activation of the first task.

To solve this problem, RTKemel implements a mutual-exclusion area


in A'@( all DOS calls are executed. This makes sure that at most one
task perforo DOS calls at any one time.

DOS atzd BIOS


Please note that task switches may take place even when the task to
be suspended is in DOS. It is only prevented that a task executes a D
OS call while another task has not yet completed its DOS call. Theref
ore, real-dme performance does not suffer.

Another problem is the use of file handles. Unfortunately, a file


handle is not unique wldiin a DOS system. File handles are file count
ers starting widi 0 for each DOS process. If, for example, four progra
ms are active at a criveii time, there may be four files each having a f
ile handle value of 3. DOS will interpret file handles in the context of
the program currendy running and its PSP - normally, this is the progr
am that was loaded last. The current PSP is switched by DOS only w
hen an EXEC call (DOS function Ox4B) activates another program or
when a pro-ram terminates.

However, under RTKernel, everal DOS processes may run in parallel.


Therefore, RTKemel must inform DOS that a switch to another
process has taken place.

In addition to the current PSP, DOS maintains another -Iobal variable:


the DTA (Disk Transfer Address). RTKemel maintains a unique DTA
for each task.

The various RTKemcl operations concerned with DOS and BIOS arc
introduccd in die folloivin?t sections. Additional information abort resi
dent RTKemel pro!zrai-ns, RTKExec, and Windom,s is -Iven in Cliapt
e.. 3, Riiiiiiilig DOS Processes iii Parallel.

Function RTKExec

Function RTKExec provides the DOS EXEC-funcdon (funcdo;i Ox4B)


to RTKemcl multitasking pro-rams. An external DOS procram is
ex..cut.-d (with parameters). The task calling RTKExec runs until the
external pro2.-an] temliiiates. It then continues running after the RTK
Exec call.

@nt RTKExec(const c-ar *Path, const c-zr *@mdLine):


Parameters:

@=-r-h Pointer to the complete pathname (Includliic,, dii-cctorv)


o7 - the program to be executed. It must be a COM or EXE file.

L i,-i e Pointer to the command line to be passed to the cxtenial


Dro-ram. Any number of parameters may be passed in a striii.. Th---
to@tal lenc,th of the command line is limited to 11-7 characters.

L,'ser's iwatzi@al
41
Cliapter 2 AIodule R ,-,Kernel

In case of successful completion, the exit code of the external


proctrani is

C?
returned; otherwise, -I is returned and errno contains the error number.

The exec... and spai@-n... functions of the standard libraries are riot
re-entraiit and should not be used in RTKemel programs.

Please refer to Section Runnin. DOS Processes in Parallel for more


information cl
about running DOS processes in parallel to an RTKcmcl application.

Function RTKSetldieDelay

Function RTKSetIdleDelay may be used to take astray, CPU-tij-nc


from DOS processes running in parallel:

void RTKSetIdle-@elay (Duration D0Sidle, Parameters:

DC)SIdle Parameter for RTKDelay called by RTKemel when DOS


(or other programs) execute interrupt Ox28. This interrupt is
ever DOS is idle. The CPU-time in this RTKDclay iii;iy thus be used
by other tasks having lower priorities.
KeyPoll Parameter for RTKDelay called by RTKemel when DOS
(or othc,programs) are polling the keyboard while no keystroke is avail
able.

None of the RTKDelays is called if keystrokes are available iii the


ke@;boa-d
buffer. In this case, RTKemel assumes that the external process could
and does not interrupt it.

RTKemellnit calls RTKSctldleDelay(O,O). For more information


about RTKS@.. tldledelay, please refer to Chapter 3, Runniizg DOS
Processes iii Parallel.

Function RTKDiskintsON

Using function RTKDlsklntsON, RTKernel may be instructed to


process flopp] disk and hard disk accesses using interrupts. This make
s idle times durin(, rea( or wnte operations available to other tasks wit
h lower priorities.

void RTKDiskInzsON(void);

RTKemellnit calls RTKDiskIntsON. This function assumes an AT-


compadbl@ disk BIOS. On XTs (or ATs with an XT disk BIOS), RT
KDlsklntsON has iii effect.
42
RTKeriiel-C 3.

DOS acid BIOS

unction RTKDiskintsOFF

unction RTKDisklntsOFF instructs RTKemel to perform disk-I/O


without sing interrupts (@ough polling). This does not require
blocking task switches, ut the idle times cannot be used by other tasks
with lower priorities.

void RTKDiskIntsOFF(void);

terrupts should be turned off when disk-IIO must not lead to blockin.
task itches or if there are compatibility problems.

isk interrupts must also be turned off if a delayed-write cache program


is ing used. Delayed-wn'te cache programs perform disk-IIO in the
timer-interpt handler and can then cause blocking task switches. There
fore, it is recom,ended not to use dclayed-write cache programs. RTK
ernel's usage of idle rnes during disk accesscs is superior to that of del
ayed-wdtc cache programs. owever, a read cache program is no proble
m.

hould a program per-form disk-I/O in an interrupt handler and


disk-110 interupts are enabled, the RTKemel debug version will issue
the error messa-c

Task blocked in interrupt

ic RTKemel standard version will not recognize the error and crash-

unction RTKSetDiskTimeout

disk-110 interrupts are enabled. RTKernel makes idle times dudna


disk-UO .ailable to other tasks. However, the BIOS requires a number
of iime-outs that ..ust be supplied by RTKcmel:

void RTKSe@-DiskTimeou@-(Duration Dis , wette,


Duration MotorStart, Duration HardD@-sk);

ammeters:
'sketteTime-out for floppy disk read arid write operations In timer
ticks.
,@torst:ar-. Dela), for floppy disk motor start-up in timer ticks.
:z-rddisk Time-out for hard disk read and @vdte operations in timer
ticks.
TKemcl initializes these values by calling RTKSetDlskTimeOut
(37,2,10). iese settincs correspond to the waiting loops normally used
by the BIOS. If incommonly slow drives are used or the dmer-interru
pt frequency is modified, @TKSetDlskTlnieout should be used to set t
he dmc-outs to new values. Funcion SetTil-nerlnter-val in module Ti
mer calls RTKSctDlsk-Timeout, if required.

,I I I -1
A'l

Mutii,al Exclusioiz

Chapter 5
Some Hints

This chapter -ives some hints about how to solve common problems
best using RTKemel, and what constructs to avoid.

Mutual Exclusion

Assume that two or more tasks have to manipulate the same global
data object. In order to assure consistency of the data, care has to be
taken that only one task accesses the data at any one time.
In this case, a semaphore may be utilized for co-ordination. The
semaphore is initialized with one event. This event thereafter represen
ts the pern-iission to access die data. Before a task iiiodifies the data,
it calls RTKWait with the correspoiidinq semaphore In order to get pe
rmission to access the data. When a task is done accessing the data. i
t must call RTKSignal to store the access permission in the semaphore
and thus enable other tasks to access the data. If all tasks adhere to t
his protocol, no more than one task will ever change the data at any o
ne dine. Tiils al-orithi-n may be used with coundnc,,,binary, and reso
urce semaphores. Resource semaphores arc especially suited for this p
urpose. because of priority inheritance and the debu. version's error ch
eckin. for resource semaphores.

Avoid Polling

Polling is often used when a task has to wait for something,. To this
purpose. something is continually tested in a loop until the expected e
vent is recognized. In sequential programs, this is the only, wa@, to
wait since the processor can't simpl), be paused. On the other hand, i
n a multitaskin?! en@,jroliillc@ilt, this is a quite uncooperative behavi
or of a task, because precious CPU-time that @-ht othenvise be used
more efficiently by other tasks is wasted. While a task has nothing to
do, it should not be in the state Ready or Current.

If the polled event is generated by another task, pollinc,, can be


replaced by inter-task communications in all cases. The waiting task c
ould, for example.
User's Matzzial
69

Cliapter 5 Soitie Hiiits

block itself using RTKReceive. It can be re-activated when another


task has r.-co-nlzed die event and transniits a correspondin..messa-e
using RTKScnd to the waiting task.

For hardware events. interrupts offer the desired functionality. A task


can be blocked in order to be re-activated b@, an interrupt as soon ac,
the expected event occurs. All of the waidno time is available to othe
r tasks in this manner and response tiine is optimal. For hardware co
mmonly found in PC systems. RTKernel provides appropriate interrup
t handlers (Timer, floppy and hard disk drives in the Kernel, keyboard
in RTKeybrd, COMX in RTCoiii, No@rell I,ANs in RTIPX). For oth
er hardware you may be usin., You should implement lar drivers if the
liardi@,arc supports interrupt,-,. This results in itic best pcrforii,,ance
of your system by far.
Unfortunately, many 1/0 boards do not support interrupts (c.o., soi-nc
dl,-Ital-110 boards). In this case, polling cannot be avoided.
Ho@k,ex,cr, pollin.. si'ioulcl be @l,@ cooperative as possible, c.-., by
providin. CPU-dme to other tasks in polling cycle using RTKDelay.
The task in module Spooler uses this technique.

Waiting for Several Events

Even if a task must react to different types of event.-, polling sliould


b;: avoided. if possible. The best-strategy in this case 'Is to split the t
ask so thit cich task only has to wait for one event.

Alternatively, events may be bundled. Given that a task must react to


two different data packets passed to it throu-h mailboxes. One not
particularly,
cle-ant - solution @cht be:

L- c

typedef struct { int a, b, c; } Recl; tv pedef struct { @loat a, b, c; }


Rec2;

!@ailbox Boxl, Box2;


,.,oid PollTask(void)
Recl Sl;
Rec2.S2;
while (True)

if (RTKGetCond(Boxl, &S1)) /* process Sl */ ; if (RTKGetCond


(Box2, &S2))

A i,oid Cage Data T@,pesfoi- Mailboxes aizd Afessage-Passiizg

/* process S2 I/

Even if no data is ready for processing, this task would "gobble up"
all CPUd me.

A better solution A.ould be to combine types Rec I and Rec2, and use
only one inai 'Ibox:

typedef enum ( Rec_'-, Rec-2 D=-caKind;

typedef strucz {
DataKind -Pipe;
union f
Recl 51;
Rec2 S2;
Data;
MultiData;

mailbox BigBcx;

void

MultiData

while (True)

RTKGer (@-igBo>,, sS)


switch S.Type) {
case Rec-l: /* process S.Daca.Si break; case Rec 2: /* process
S.Dar~a.-@@@ --real,;

In this example, no CPU-time is wasted.

Avoid Large Data Types for Mailboxes and


Message-Passing
The length of the data packets fo,- communications @-ia niailboxes or
messa,,e-passin(,, may be up to 64 kbvtes. Howe@.cr, large data
packets can result in

U.@er's Maizual 71

Citapter 5 Sotiie Hiizts

performance problems. since the data is copied in ever), 'nter-task corn


munl 'ca ad of channelling, the data itself through mailboxes, lo-' -d
packet

tion. Inste c,
numbers or pointers to the data may be used.

In the follo@srin(, exampl,-. 10 data buffers are allocated. !Jnused


buffers are con'tiqe@.pail ox PooL ProducerTask retrieves buffers from
Pool as req i'red and passes them @oisumerTask using mailbox NcwD
ata. Since only pointers - not the buffers themselves - are copied to d
w mailbox. @pzformance is ind '@gdent of the data packet size.
-2.-4 e fs@ruct
@-har x[5000];
/1 more fields ...
B-..: f f-: er @ e

lia@-lbox Pool,

vo--.d ProducerTasi-l -.ro@-d)

Eu@'erT, _ape *P@r;

"le (,rue)
RTKGet(Poo@@, &Ptr); /* get new /* Pr-r-> is -@illed with
dat@P,TKPut (Ne-wE@-ia, &Pr-r) P7--zs on

VC-'-d ConsumerTask@-.-oid)
Buj'ferType *Ptr;
while (True)
RTKGet(NewE@---a, &Ptr); /* wait for new data
process @-r->
RT-,,zwut(Poc'-, @ip@r);

/* r,-'-ease buf@-@-r

void main(void)
int i;
BufferType *Ptr;

RTKerre!Init(7);

A i,oid Titne-Slicilzg

Pool =RTKCreateMailbox(s-'@zeof(@uffer.@@e*), @4a>.Buf,er);


NewData=RTKCreateMailbox(sizeo@@(Buffer.@,,@e*), '.!
axBufl@er@;

/* allocate and make available all buf,@@---s for {i = <= MaxBuffer;


i++)

Ptr = malloc(sizeof(BufferType)); RTK-Put(Pool, &Ptr);

/* ...

The same technique can be used for messa-e-passing.

Avoid Time-Slicing
Time-sllcinR is a technique that originated in dme-sharinc-, systeriis.
In Chapter 1. die differences between time-sharing systems and real-dn
ic systems @@,cre discussed briefly. Actually, dmc-sllcing only make
s sense if ),our tasks don't have to meet re@-dme requirements, never
have to wait for soiiicdiiilc,, and cut run largely independently of each
other. In this case, however, you could let the tasks run sequendally a
nd thus avoid the overhead incurred by RTKcmcl.

The "fairness" strived for by time-sharing systems cannot be attained b


\. RTKemel anyhow. The simplest definition of "fairness" could be
thai CPUdme is to be shared evenly among all tasks. (Systems like Un
ix use a much more involved definition of "fairness".) The scheduling
rules of RTKemel can only achieve this if all tasks of a program have
the same priority, can run completely independently of each other, and
never block themselves (c.-., throu@h DOS calls). If these conditions
are not true, time-slicing will only -uarantee that each task receives CP
U-time in die long run - when and how much is, in (,eneral, indetermi
nate.

In many applications, RTKDelay(O) may be a feasible altematl,,,e to


dmc-slicing. Usin- RTKDclay(O), round-robin scheduling (tasks are
acd@,ated in tum.) can be implemented easily. Assume the followin.
problem shall be solved:
U,Yer's Maizual
73

Cliapter.5 Soiize [Iiiits

Two tasks must recognize an event using polling. The pollin,,, cycle
must be as short as possible. A simple solution would be to switch
amoii. tasks usin,' dmc-slicin.. Then, however, the polling cycle would
'bc, -@5 iiii]li,@conds. in di-, worst case. Moreover, the timer-interru
pt rate might be iricreic,,2d using module Tinier, thus achieving a polli
nc,, cycle of a few milliseconds. I lo@@?es;er, it would be much mo
re eleant to call RTKDelay(O) in each poll'n,-, cycle. Each task invol
ved could then process a polling cycle without beinq disrupted and aft
erwards allow the next task to run. Assuminc, the pollinc,, itself requi
res only, 10 p,,ecs, approx. 20,000 cycles per second could be achieve
d on a 20-MHz 80386. By the way.. this algorithm would also ensur
e "fairness", even if more than two tasks participate.

Cyclic Tasks (Timer)

Tasks that must run in a fixed time frame are frequently encountered
in rea Itime applications. The structure of such a wk might be as
follows:
iide-@-@ne Cycle 5
T@-rr,e @lextActiva--,-on;

Next@.::,.@-vaticn = R-,.@GetTimeo; wh@'@'-,e (True)

@'@x@AC-ivat4on = @,lextACtivat-on + R-'.@DelayUnt@-1


(NexrActivatio,-,);

/* @he tasks job is done here

This task would run exactly once every 5 timer ticks, provided
the task's job S
takes no loncer than 5 timer ticks. The actual cycle time ma@,
he adjusted usip,@, 'Cl
constant C,,,c--, e and the dmcr-interrupt interval.R

If the cycle time of a task is not an exact multiple of the dmer-


lnterrupt inten,,al, 6 . -
the following task can be used: rii
74
RTAfp-zi(,1-C 3,0

Priorities

void CyClicTask(void)

#define Cycle 0.7 /* seconds float NextAct@-vation;

NextActivati-cn = SecPerTick * RTKGet7imeo; while (True)

NextActivation = Nexr-.cliva:@@on
RTKDelayU-til(Ticks(l,.-,ex@-Act-vatic7.;@;
/* the tas)-,,s job is done here

Since RTKemel can only activate tasks waidn-g in an RTKDelay or


RTKDelayUntil throuch a timer interrupt, these tasks would, on the av
era,-e, conform to their cycle exactly. The s@ of a cycle can deviate
from the desired point in time up to one dck. @s round-off error arise
s from the conversion ot a float number to a lone integer in function T
icks of module Timer. Hoxvek,er, the error does not accumulate; it is
the same in each cvcle.
Priorities

Priorities liasre the sole purpose of -uararteeine zood response times ol'
time-ciitical tasks, even when other, less critical tasks run or could
run.

Priorities should not be used to synchronize tasks. It is iie@.cr certain


that no other task runs A7[iile the task widi the lil,-hest priori,,,-
appears to be ready i"t-)F runnin.. If, for example, this task performs a
DOS call. it could be suspeiidc;; by the kernel if some other task has
not yet completed 'is DOS call. NIorco@@er I

each floppy or hard disk access makes CPU-dme as-ailable to other


tasks @k7idi lower priorities.
Svmchro@tion among tasks can only be achieved using explicit inter-
taskc@mmunications.
RTKemel exhibits the best performance when die smallest pocsible
rajice of ii,,2
64 priorities is used. Since the Idle Task has a r)nont@. of 0, fe\,@,
and small plit)-
rities should be used (see Appendix A). RTKcmel 64
in ordc:-
not to impose unnecessary restrictions, in general, ho,,ke@,cr, to
1.0 priorities
wl 'I] (and should) suffice.
User's Maizidal 7@
-j

Cliapter 5 Soiyie Hiizts

Starting Methods as Tasks

-Re code of a task must always be a function without pparanicters.


This coiid'ldon cannot be met by methods of objects, becausd they
always ha@,e dx in@,15ible parameter "this". If a method is to be us
ed as a task anyhow, two stratec,' are possi 'ble:

Encapsulate the method by a nomial function and start the function a.,;
a task:

=include 'RTKernel.h'

::lass
j

P,b

:-iyobjecz @bjecr-l;
void RTY--rnelTask(void)

Objec::'-.Task(j;

R T @,, e -- ni r-,
RTKCr@-=-,--eTask(R-@Kerne!Task, 7, 4G,@6, 'Objec@-@ask");
Alternatively, the task can be sent a pointer to the object to be used:
--include 'RTKernel.h'
--lass Y,jobiect
public:
vir@ual void Task(vcid);
void RTKernelTask(void)
14yObj@-c:t *LocalObject;

RTKRec=---ve(&Localobjec@, sizeoL(Local,)bi@--L));
LocalObject->Tasko;

76 RTKer?zel-C
3.0
Types, Co?istazzts alibi 1,'ai-iable.@

Chapter 2
Module RTKernel

Module RTKemel contains all constants, types, and functions needed


for multitaskin2 operation. A multitasking program should #include
flIC w; It contains the declarations detailed in this chapter.

All identifiers declared PUBLIC in module RTKemel start with the


letters "RTK" in order to avoid naming conflicts with other modules.
If naming conflicts with other identifiers (e.g., types or consiants) do a
rise, the identifier concciiicd may be renamed in RTKEI@EL. H.

Types, Consta nts and Variables

The complete declaration of each identifier is contained in file Z-


@=-.RNEL. H. Only the respective meanings shall be alven here.

Constants
MIN-=R--0 Smallest priority available for application tasks.
RTKemel's Idle Task his priority MIN-PRIO - 1.

La-r-est prio 'ty available for application ta-sis.


R 7-,3 c:
1

1,3 T.1. z-: A TaskHandic referencing no task. The application's


task handles
may be initialized with and compared to this value.

@-,:)x An un-initialized or deleted mailbox. The


application's mailboxes
may be initialized with and compared to tli.is va.iiie.

Types
,-CC Enumeration type with values False and True.

'7as,'.c- Function type of a task. Only C functions of this type can


be
Fun@:i--'cn started as a task.

7RQ'@andier Function type of a hardware interrupt handler.

T This type serves as a basic type for types Time and Duration,
which express times. A "Tick" is the time span between two dmer int
errupts.

@i.7e Absolute tii-ic in tiiner ticks.


:)ur@-:: icr, Time span. difference between two absolute times.

Sema-@e Enumeration type of the semaphore types. It contains the


values Counting, Binary, and Resource.

U.,;er's @fcziziial
17

Das könnte Ihnen auch gefallen