16 - Multi Tasking
16 - Multi Tasking
MULTI-TASKING
Contents
16–1
16. MULTI-TASKING MARRC75KR07091E Rev I
Multi-tasking allows more than one program to run on the controller on a time-sharing basis, so that
multiple programs appear to run simultaneously.
Multi-tasking is especially useful when you are executing several sequences of operations which
can generally operate independently of one another, even though there is some interaction between
them. For example:
It is important to be aware that although multiple tasks seem to operate at the same time, they are
sharing use of the same processor, so that at any instant only one task is really being executed. With
the exception of interruptible statements, once execution of a statement is started, it must complete
before statements from another task can be executed. The following statements are interruptible:
• READ
• DELAY
• WAIT
• WAIT FOR
Refer to Section 16.4 , “Task Scheduling” for information on how the system decides which task
to execute first.
A task, or user task, is a user program that is running or paused. A task is executed by an
"interpreter." A task is created when the program is started and eliminated when the interpreter it
is assigned to, becomes assigned to another task.
• Interpreter
An interpreter is a system component that executes user programs. At a cold or controlled start,
($MAXNUMTASKS + 2) interpreters are created. These interpreters are capable of concurrently
executing tasks.
• Task name
Task name is the program name specified when the task is created. When you create a task,
specify the name of the program to be executed as the task name.
16–2
MARRC75KR07091E Rev I 16. MULTI-TASKING
Note The task name does not change once the task is created. Therefore, when an external routine
is executing, the current executing program name is not the same as the task name. When you
send any requests to the task, use the task name, not the current program name.
• Motion control
Motion control is defined by a bit mask that specifies the motion groups of which a task has
control. Only one task at a time can control a motion group. However, different tasks can
control different motion groups simultaneously. Refer to Section 16.3 , “Motion Control,” for
more information.
• When the task starts, if the controller directive %NOLOCKGROUP is not used. If the
%LOCKGROUP directive is not used, the task requires control of all groups by default. If
%LOCKGROUP is used, control of the specified groups is required.
For teach pendant programs, motion control is required when the program starts, unless the
DETAIL page from the SELECT screen is used to set the Group Mask to [*,*,*,*,*].
• When a task executes the LOCK_GROUP built-in, it requires the groups specified by the group
mask.
16–3
16. MULTI-TASKING MARRC75KR07091E Rev I
• When a task calls a ROUTINE or teach pendant program, it requires control of those group(s).
The group(s) required by a ROUTINE or TPP+ program are those specified, or implied, by
controller directives or in the teach pendant DETAIL setup.
A task will be paused if it is not able to get control of the required group(s).
After a task gets control of a group, it keeps it until one of the following:
16–4
MARRC75KR07091E Rev I 16. MULTI-TASKING
A task is ready to run when it is in running state and has no hold conditions. Only one task is
actually executed at a time. There are two rules for determining which task will be executed when
more than one task is ready to run:
• Priority - If two or more tasks of different priority are ready to run, the task with higher priority is
executed first. Refer to Section 16.4.1 , “Priority Scheduling,” for more information.
• Time-slicing - If two tasks of the same priority are ready to run, execution of the tasks is
time-sliced. Refer to Section 16.4.2 , “Time Slicing,” for more information.
If two or more tasks with different priorities are ready to run, the task with the highest priority will run
first. The priority of a task is determined by its priority number. Priority numbers must be in the range
from -8 to 143. The lower the priority number, the higher the task priority.
For example: if TASK_A has a priority number of 50 and TASK_B has a priority number of 60, and
both are ready to run, TASK_A will execute first, as long as it is ready to run.
In addition to affecting other user tasks, task priority also affects the priority of the interpreter
executing it, relative to that of other system functions. If the user task has a higher priority (lower
priority number) than the system function, as long as the user task is ready to run, the system function
will be not be executed. The range of user task priorities is restricted at the high priority end. This is
done so that the user program cannot interfere with motion interpolation. Motion interpolation refers
to the updates required to cause a motion to complete.
The following table indicates the priority of some other system functions.
16–5
16. MULTI-TASKING MARRC75KR07091E Rev I
If two or more tasks of the same priority are ready to run, they will share the system resources by
time-slicing, or alternating use of the system.
A time-slice permits other tasks of the same priority to execute, but not lower priority tasks.
The default time-slice for a task is 256 msec. Other values can be set using the %TIMESLICE
directive or the SET_TSK_ATTR built-in.
In each case, the task will not start running if it requires motion control that is not available.
16–6
MARRC75KR07091E Rev I 16. MULTI-TASKING
16.5.1 Running Programs from the User Operator Panel (UOP) PNS Signal
A program is executed:
• If the binary value of the UOP PNS signals is non-zero and the UOP PROGSTART signal
is asserted
• If there is currently a program with the name “PNSnnnn,” where nnnn is the decimal value of the
PNS signals plus the current value of $SHELLCFG.$jobbase.
Multiple programs can be started in this way, as long as there is no motion group overlap.
If the task name determined from the PNS is in a paused state, the PROGSTART signal is interpreted
as a CONTINUE signal. If $SHELLCFG.$contonly is TRUE, this is the only function of the
PNS/PROGSTART signals.
If $SHELLCFG.$useabort is TRUE, the PNS signals can be used to abort a running task. The name of
the task to be aborted is the same as that used with the PROGSTART signal. In this case, abort is
triggered by the UOP CSTOPI signal
A running task can create new tasks. This new task is called a child task. The task requesting creation
of the child task is called the parent task. In teach pendant programs, a new task is created by executing
a RUN instruction. In KAREL programs a new task can be created using the RUN_TASK built-in.
The parent and child task may not require the same motion group. In the case of RUN_TASK,
however, it is possible to release control of motion groups for use by the child task.
Once a child task is created, it runs independently of its parent task, with the following exception:
• If a parent task is continued and its child task is paused, the child task is also continued.
• If a parent task is put in STEP mode, the child task is also put in STEP mode.
If you want the child task to be completely independent of the parent, a KAREL program can initiate
another task using the KCL or KCL_NOWAIT built-ins to issue a KCL>RUN command.
16–7
16. MULTI-TASKING MARRC75KR07091E Rev I
There are a number of built-ins used to control and monitor other tasks. See the description of these
built-ins in Appendix A .
The following KCL commands can be used to control and monitor the status of tasks. Refer to
Appendix C , "KCL Command Alphabetic Descriptions,” for more information.
16–8
MARRC75KR07091E Rev I 16. MULTI-TASKING
The KAREL controller supports counting semaphores. The following operations are permitted on
semaphores:
• Clear a semaphore (KAREL: CLEAR_SEMA built-in): sets the semaphore count to zero.
All semaphores are cleared at cold start. It is good practice to clear a semaphore prior to using
it. Before several tasks begin sharing a semaphore, one and only one of these task, should clear
the semaphore.
• Post to a semaphore (KAREL: POST_SEMA built-in): adds one to the semaphore count.
If the semaphore count is zero or greater, when the post semaphore is issued, the semaphore
count will be incremented by one. The next task waiting on the semaphore will decrement the
semaphore count and continue execution. Refer to Figure 16–1 .
If the semaphore count is negative, when the post semaphore is issued, the semaphore count will
be incremented by one. The task which has been waiting on the semaphore the longest will then
continue execution. Refer to Figure 16–1 .
• Read a semaphore (KAREL: SEMA_COUNT built-in): returns the current semaphore count.
• Wait for a semaphore (KAREL: PEND_SEMA built-in, SIGNAL SEMAPHORE Action):
If the semaphore count is greater than zero when the wait semaphore is issued, the semaphore
count will be decremented and the task will continue execution. Refer to Figure 16–1 .
If the semaphore count is less than or equal to zero (negative), the wait semaphore will decrement
the semaphore count and the task will wait to be released by a post semaphore. Tasks are released
on a first-in/first-out basis. For example, if task A waits on semaphore 1, then task B waits on
semaphore 1. When task D posts semaphore 1, only task A will be released. Refer to Figure 16–1 .
16–9
16. MULTI-TASKING MARRC75KR07091E Rev I
P P P
D
B W
Task
A C W W
T0 T1 T2 T3 T4 T5 T6 T7 Tn
Example: Semaphores can be used to implement a task that acts as a request server. In the
following example, the main task waits for the server to complete its operation. Semaphore[4]
is used to control access to rqst_param or R[5]. Semaphore[5] is used to signal the server task
that service is being requested; semaphore[6] is used by the server to signal that the operation is
complete.
Main Task
--KAREL
CLEAR_SEMA(4)
CLEAR_SEMA(5)
CLEAR_SEMA(6)
RUN TASK(‘server’,0,TRUE,TRUE,1,STATUS)
PEND_SEMA(4,max_time,time_out)
rqst_param=10
POST_SEMA(5)
PEND_SEMA(6,max_time,time_out)
16–10
MARRC75KR07091E Rev I 16. MULTI-TASKING
Server Task
--KAREL
POST_SEMA (4)
WHILE TRUE DO
PEND_SEMA(5,max_time,time_out)
IF rqst_param=10 THEN
do_something
ENDIF
POST_SEMA(4)
POST_SEMA(6)
ENDWHILE
Example: The program example in Semaphore and Task Synchronization Program Example - MAIN
TASK thru Semaphore and Task Synchronization Program Example - TASK B shows how semaphores
and tasks can be used together for synchronization. MAIN_TASK.KL is used to initialize the semaphore
(MOTION_CTRL) and then runs both TASK_A.KL and TASK_B.KL. MAIN_TASK.KL then waits for
TASK_A and TASK_B to abort before completing. TASK_A waits until you press F1 and then moves the
robot to the HOME position. TASK_B waits until you press F2 and then moves the robot along a path.
PROGRAM main_task
%nolockgroup
VAR
motion_ctrl: INTEGER
tsk_a_done : BOOLEAN
tsk_b_done : BOOLEAN
tmr : INTEGER
status : INTEGER
------------------------------------------------
-- --
-- INIT_LOCK: Initialize the semaphore --
-- to make sure its count is at --
-- zero before using it. Then --
-- post this semaphore which will--
-- allow the first pend to the --
-- semaphore to continue --
-- execution. --
------------------------------------------------
ROUTINE init_lock
BEGIN
CLEAR_SEMA (motion_ctrl) -- makes sure semaphore is zero before using it.
POST_SEMA (motion_ctrl) -- makes motion_ctrl available immediately
END init_lock
------------------------------------------------
16–11
16. MULTI-TASKING MARRC75KR07091E Rev I
-- --
-- IS_TSK_DONE : Find out if the specified --
-- task is running or not. --
-- If the task is aborted then --
-- return TRUE otherwise FALSE.--
------------------------------------------------
ROUTINE is_tsk_done (task_name:STRING): BOOLEAN
VAR
status : INTEGER -- The status of the operation of GET_TSK_INFO
task_no : INTEGER -- Receives the current task number for task_name
attr_out: INTEGER -- Receives the TSK_STATUS output
dummy : STRING[2] -- Does not receive any information
BEGIN
GET_TSK_INFO (task_name, task_no, TSK_STATUS, attr_out, dummy, status)
IF (attr_out = PG_ABORTED) THEN
RETURN (TRUE) -- If task is aborted then return TRUE
ENDIF
RETURN(FALSE) -- otherwise task is not aborted and return
FALSE
END is_tsk_done
BEGIN
motion_ctrl = 1 -- Semaphore to allow motion control
init_lock -- Make sure this is done just once
FORCE_SPMENU ( tp_panel, spi_tpuser, 1) -- Force the Teach Pendant
-- user screen to be seen
RUN_TASK(’task_a’, 1, FALSE, FALSE, 1, status) -- Run task_a
RUN_TASK(’task_b’, 1, FALSE, FALSE, 1, status) -- Run task_b
REPEAT
tsk_a_done = is_tsk_done (’task_a’)
tsk_b_done = is_tsk_done (’task_b’)
delay (100)
UNTIL (tsk_a_done and tsk_b_done) -- Repeat until both task_a
END main_task -- and task_b are aborted
PROGRAM task_a
%nolockgroup
VAR
motion_ctrl FROM main_task: INTEGER
home_pos : XYZWPR
status : INTEGER
------------------------------------------------
-- --
-- RUN_HOME : Lock the robot motion --
-- control. This task is --
16–12
MARRC75KR07091E Rev I 16. MULTI-TASKING
PROGRAM task_b
%nolockgroup
VAR
motion_ctrl FROM main_task : INTEGER
work_path : PATH
move_pos : XYZWPR
status : INTEGER
------------------------------------------------
-- --
-- do_work : Lock the robot from other --
-- tasks and do work. This --
-- task is doing motion and --
-- must lock motion control so --
-- that another task does not --
-- try to do motion at the --
-- same time. --
------------------------------------------------
ROUTINE do_work
VAR
time_out: BOOLEAN
16–13
16. MULTI-TASKING MARRC75KR07091E Rev I
BEGIN
PEND_SEMA (motion_ctrl,-1,time_out) -- lock motion_ctrl from other
-- tasks keep other tasks from
-- moving robot
LOCK_GROUP (1, status)
FOR i=1 to PATH_LEN(work_path) DO
move_pos = work_path[i]
SET_POS_REG(1, move_pos, status)
do_move -- call TP program to move to path node
ENDFOR
UNLOCK_GROUP (1, status)
POST_SEMA(motion_ctrl) -- unlock motion_ctrl allow
-- other task to move robot
END do_work
BEGIN
set_cursor(tpfunc, 1, 10, status)
write tpfunc(’WORK’,CR)
wait for TPIN[131]+ -- wait until F2 is pressed
do_work
END task_b
A QUEUE_TYPE Data Type has one user accessible element, n_entries . This is the number of
entries that have been added to the queue and not read out. The array of integer used with a queue, is
used by the queue built-ins and should not be referenced by the KAREL program.
Example: The following example illustrates a more powerful request server, in which more than one
task is posting requests and the requester does not wait for completion of the request.
16–14
MARRC75KR07091E Rev I 16. MULTI-TASKING
Requester
--declarations
VAR
rqst_queue FROM server: QUEUE_TYPE
rqst_data FROM server: ARRAY[100] OF INTEGER
status: INTEGER
seq_no: INTEGER
-- posting to the queue --
APPEND_QUEUE (req_code, rqst_queue, rqst_data, seq_no, status)
Server
PROGRAM server
VAR
rqst_queue: QUEUE_TYPE
rqst_data : ARRAY[100] OF INTEGER
status : INTEGER
seq_no : INTEGER
rqst_code : INTEGER
BEGIN
INIT_QUEUE(rqst_queue) --initialization
WHILE TRUE DO --serving loop
WAIT FOR rqst_code.n_entries > 0
GET_QUEUE (rqst_queue, rqst_data, rqst_code, seq_no, status)
SELECT rqst_code OF
CASE (1): do_something
ENDSELECT
ENDWHILE
END server
16–15