Beruflich Dokumente
Kultur Dokumente
Variables
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
Parameters:
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
@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.
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
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
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.
Function RTKSuspend
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
Function RTKSetPriority
20 R7'Kf-
rt?,1-C 3.0
Tci.yk ,@laiza,@eiizeizi'
Parameters:
Function RTKProtect8087
-,,oid RTKProtect8087(void);
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
Function RTKCurrentTaskHandle
Tas',-@@--dle RTKCu----entTaskHandle(void);
Function RTKGetTaskStack
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 RTKGetTaskState
22 R7Kei-iiel-
C 3.01
Etiqi,tiritig Task@
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.
Dead',-oc@-,@-@ I ,
and the receiver task has been terminated -In the inezintime.
Usei-'s Maizual
Cizapter 2 Alodtile RTKeniel
Function RTKGetTaskPrio
Function RTKListTasks
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:
The last field (WaldngAt) can contain any of the following stnnes:
24 RTKcritel-C3-0
Titize
Time
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-
Usei-'s Maizrial
Function RTKGetTime
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.
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:
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
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.
U,@er's Manual
2-1
Semaphore S;
void TaskA(void)
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.
Function RTKCreateSema
User's Ma7ziial
Function RTKSemaValue
Function RTKResourceOwner
Function RTKSignal
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
0
Any number of tasks can wait for events at a semaphore. The tasks
are re-acdvated in sequence of their priorities.
Function RTKWaitCond
bocl R@:<-,..,'a@-tCc.-id(Seraphore 5)
Function RTKWaitTimed
imum time (in dmer ticks) to be waited for the irfival of an event.
User's Afatiiial
Mailboxes
Any number of tasks may use the same mailbox for sto 'rip
"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
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
User's Maiiual
3
Function RTKMessages
Function RTK-N4essaces returns the number of messares currently
stored in a 'Ibox.
Function RTKPut
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
34 RTKertiel-C
3.0
Mailboxe3
Function RTKPutCond
cl
the mailbox is full, this is indicated by the return value and no data is
Iraiisferred.
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.
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.
Uscr's illaiiiial 35
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
t>
l@fessag@@-Passiti,@
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;
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.
Function RTKReceive
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.
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.
If the return value is true, the data transfer has been successfully
completed.. othenvise, no task was ready for immediate data transfer.
Function RTKSendTimed
Parameters:
Receikrer Handle of the receiving task.
User's Manital
39
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
Parameters:
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.
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.
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
L,'ser's iwatzi@al
41
Cliapter 2 AIodule R ,-,Kernel
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.
Function RTKSetldieDelay
Function RTKDiskintsON
void RTKDiskInzsON(void);
unction RTKDiskintsOFF
void RTKDiskIntsOFF(void);
terrupts should be turned off when disk-IIO must not lead to blockin.
task itches or if there are compatibility problems.
ic RTKemel standard version will not recognize the error and crash-
unction RTKSetDiskTimeout
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.
L- c
/* 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 strucz {
DataKind -Pipe;
union f
Recl 51;
Rec2 S2;
Data;
MultiData;
mailbox BigBcx;
void
MultiData
while (True)
U.@er's Maizual 71
tion. Inste c,
numbers or pointers to the data may be used.
lia@-lbox Pool,
"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
/* ...
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.
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.
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;
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
Priorities
void CyClicTask(void)
NextActivation = Nexr-.cliva:@@on
RTKDelayU-til(Ticks(l,.-,ex@-Act-vatic7.;@;
/* the tas)-,,s job is done here
Priorities liasre the sole purpose of -uararteeine zood response times ol'
time-ciitical tasks, even when other, less critical tasks run or could
run.
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
Constants
MIN-=R--0 Smallest priority available for application tasks.
RTKemel's Idle Task his priority MIN-PRIO - 1.
Types
,-CC Enumeration type with values False and True.
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.
U.,;er's @fcziziial
17