CHAPTER 3 TASK MANAGEMENT FUNCTIONS
This chapter describes the task management functions performed by the RI78V4.
The task control functions provided by the RI78V4 include a function to reference task statuses, in addition to a function to manipulate task statuses.
A task is processing program that is not executed unless it is explicitly manipulated via service calls provided by the RI78V4, unlike other processing programs (cyclic handler and interrupt handler), and is called from the scheduler.
Note The execution environment information required for a task's execution is called "task context". During task execution switching, the task context of the task currently under execution by the RI78V4 is saved and the task context of the next task to be executed is loaded.
Tasks enter various states according to the acquisition status for the OS resources required for task execution and the occurrence/non-occurrence of various events. In this process, the current state of each task must be checked and managed by the RI78V4.
The RI78V4 classifies task states into the following six types.
State of a task that is not active, or the state entered by a task whose processing has ended.
A task in the DORMANT state, while being under management of the RI78V4, is not subject to the RI78V4 scheduling.
State of a task for which the preparations required for processing execution have been completed, but since another task with a higher priority level or a task with the same priority level is currently being processed, the task is waiting to be given the CPU's use right.
State of a task that has acquired the CPU use right and is currently being processed.
Only one task can be in the running state at one time in the entire system.
State in which processing execution has been suspended because conditions required for execution are not satisfied.
Resumption of processing from the WAITING state starts from the point where the processing execution was suspended. The value of information required for resumption (such as task context) immediately before suspension is therefore restored.
In the RI78V4, the WAITING state is classified into the following six types according to their required conditions and managed.
|
|
|
A task enters this state if the counter for the task (registering the number of times the wakeup request has been issued) indicates 0x0 upon the issuance of a slp_tsk or tslp_tsk.
|
|
A task enters this state upon the issuance of a dly_tsk.
|
Waiting state for a semaphore resource
|
A task enters this state if it cannot acquire a resource from the relevant semaphore upon the issuance of a wai_sem or twai_sem.
|
Waiting state for an eventflag
|
A task enters this state if a relevant eventflag does not satisfy a predetermined condition upon the issuance of a wai_flg or twai_flg.
|
Sending WAITING state for a data queue
|
A task enters this state if cannot send a data to the relevant data queue upon the issuance of a snd_dtq or . tsnd_dtq
|
Receiving WAITING state for a data queue
|
A task enters this state if cannot receive a data from the relevant data queue upon the issuance of a rcv_dtq or trcv_dtq.
|
Receiving waiting state for a mailbox
|
A task enters this state if cannot receive a message from the relevant mailbox upon the issuance of a rcv_mbx or trcv_mbx.
|
Waiting state for a fixed-sized memory block
|
A task enters this state if it cannot acquire a fxed-sized memory block from the relevant memory pool upon the issuance of a get_mpf or tget_mpf.
|
State in which processing execution has been suspended forcibly.
Resumption of processing from the SUSPENDED state starts from the point where the processing execution was suspended. The value of information required for resumption (such as task context) immediately before suspension is therefore restored.
- WAITING-SUSPENDED state
State in which the WAITING and SUSPENDED states are combined.
A task enters the SUSPENDED state when the WAITING state is cancelled, or enters the WAITING state when the SUSPENDED state is cancelled.
A priority level that determines the order in which that task will be processed in relation to the other tasks is assigned to each task.
As a result, in the RI78V4, the task that has the highest priority level of all the tasks that have entered an executable state (RUNNING state or READY state) is selected and given the CPU use right.
In the RI78V4, the following two types of priorities are used for management purposes.
- Task initial priority
Priority set when a task is created.
- Task current priority
This is the general term used to describe the priority level of a task from the time it enters the READY state from the DORMANT state until it returns to the DORMANT state.
Therefore, the current priority level of a task that enters the READY state from the DORMANT state has the same value as the "initial priority level," and the current priority level when the priority level is changed by issuing
chg_pri or
ichg_pri is the same value as the "priority level after change".
Note 1 In the RI78V4, a task having a smaller priority number is given a higher priority.
Tasks therefore cannot be created dynamically using a method such as issuing a service call from a processing program.
- Static create
Static task creation is realized by defining
Task information in the system configuration file.
The RI78V4 executes task creation processing based on data stored in information files, using the
Kernel Initialization Module, and handles the created tasks as management targets.
In the RI78V4, tasks created statically by the
Kernel Initialization Module cannot be deleted dynamically using a method such as issuing a service call from a processing program.
3.2.5 Basic form of tasks
When coding a task, use a void function with one VP_INT argument (any function name is fine) .
The following shows the basic form of tasks.
#include <kernel.h> /*Standard header file definition*/
#include <kernel_id.h> /*System information header file definition*/
void
func_task ( VP_INT exinf )
{
/* ............ */ /*Main processing*/
ext_tsk ( ); /*Terminate invoking task*/
}
|
Note The the #pragma rtos_task directive is defined in the file "kernel_id.h" (CF78V4 outputs automatically). Therefore please the file "kernel_id.h" be sure to do include.
$INCLUDE (kernel.inc) ;Standard header file definition
$INCLUDE (kernel_id.inc) ;System information header file definition
.PUBLIC _func_task
.SECTION .text, TEXT
_func_task:
PUSH BC ;Stores the higher 2 bytes of argument exinf into stack
PUSH AX ;Stores the lower 2 bytes of argument exinf into stack
; ............ ;Main processing
BR !!_ext_tsk ;Terminate invoking task
|
3.2.6 Internal processing of task
In the RI78V4, original dispatch processing (task scheduling) is executed during task switching.
Therefore, note the following points when coding tasks.
- Stack switching
In the RI78V4, switching to the stack for the switching destination task (task stack) is executed during task switching.
The user is therefore not required to code processing related to stack switching in tasks.
- Interrupt status
In the RI78V4, the initial interrupt state specified in
Task information when a task is switched from the READY state to the RUNNING state.
To change (disable or enable) the interrupt status in the task, calling of the __DI or __EI function are therefore required.
- Service call issuance
Service calls that can be issued in tasks are limited to the service calls that can be issued from tasks.
The RI78V4 provides two types of interfaces for task activation: queuing an activation request queuing and not queuing an activation request.
3.3.1 Queuing an activation request
A task (queuing an activation request) is activated by issuing the following service call from the processing program.
-
act_tsk,
iact_tsk
These service calls move a task specified by parameter
tskid from the DORMANT state to the READY state.
As a result, the target task is queued at the end on the ready queue corresponding to the initial priority and becomes subject to scheduling by the RI78V4.
If the target task has been moved to a state other than the DORMANT state when this service call is issued, this service call does not move the state but increments the activation request counter (by added 0x1 to the wakeup request counter).
The following describes an example for coding this service call.
#include <kernel.h> /*Standard header file definition*/
#include <kernel_id.h> /*System information header file definition*/
void
func_task ( VP_INT exinf )
{
ID tskid = ID_tskA; /*Declares and initializes variable*/
/* ............ */
act_tsk ( tskid ); /*Activate task (queues an activation request)*/
/* ............ */
}
|
Note 1 The activation request counter managed by the RI78V4 is configured in 7-bit widths. If the number of activation requests exceeds the maximum count value 127 as a result of issuing this service call, the counter manipulation processing is therefore not performed but "E_QOVR" is returned.
3.3.2 Not queuing an activation request
A task (not queuing an activation request) is activated by issuing the following service call from the processing program.
-
sta_tsk,
ista_tsk
These service calls move a task specified by parameter
tskid from the DORMANT state to the READY state.
As a result, the target task is queued at the end on the ready queue corresponding to the initial priority and becomes subject to scheduling by the RI78V4.
The following describes an example for coding this service call.
#include <kernel.h> /*Standard header file definition*/
#include <kernel_id.h> /*System information header file definition*/
void
func_task ( VP_INT exinf )
{
ID tskid = ID_tskA; /*Declares and initializes variable*/
VP_INT stacd = 1048575; /*Declares and initializes variable*/
/* ............ */
sta_tsk ( tskid, stacd ); /*Activate task (does not queue an activation
request)*/
/* ............ */
}
|
Note 1 This service call does not perform queuing of activation requests. If the target task is in a state other than the DORMANT state, the counter manipulation processing is therefore not performed but "E_OBJ" is returned.
Note 2 An start code "
stacd" is passed to the task activated by issuing this service call.
3.4 Cancel Task Activation Requests
An activation request is cancelled by issuing the following service call from the processing program.
-
can_act
This service call cancels all of the activation requests queued to the task specified by parameter
tskid (sets the activation request counter to 0x0).
When this service call is terminated normally, the number of cancelled activation requests is returned.
The following describes an example for coding this service call.
#include <kernel.h> /*Standard header file definition*/
#include <kernel_id.h> /*System information header file definition*/
void
func_task ( VP_INT exinf )
{
ER_UINT ercd; /*Declares variable*/
ID tskid = ID_tskA; /*Declares and initializes variable*/
/* ............ */
ercd = can_act ( tskid ); /*Cancel task activation requests*/
if ( ercd >= 0x0 ) {
/* ............ */ /*Normal termination processing*/
}
/* ............ */
}
|
The RI78V4 provides two types of interfaces for task termination: termination of invoking task and forced termination of other tasks.
3.5.1 Terminate invoking task
An invoking task is terminated by issuing the following service call from the processing program.
-
ext_tsk
This service call moves an invoking task from the RUNNING state to the DORMANT state.
As a result, the invoking task is unlinked from the ready queue and excluded from the RI78V4 scheduling subject.
If an activation request has been queued to the invoking task (the activation request counter is not set to 0x0) when this service call is issued, this service call moves the task from the RUNNING state to the DORMANT state, decrements the wakeup request counter (by subtracting 0x1 from the wakeup request counter), and then moves the task from the DORMANT state to the READY state.
The following describes an example for coding this service call.
#include <kernel.h> /*Standard header file definition*/
#include <kernel_id.h> /*System information header file definition*/
void
func_task ( VP_INT exinf )
{
/* ............ */
ext_tsk ( ); /*Terminate invoking task*/
}
|
Note 1 This service call does not return the OS resource that the invoking task acquired by issuing a service call such as
sig_sem or
get_mpf. The OS resource have been acquired must therefore be returned before issuing this service call.
Note 2 When moving a task from the RUNNING state to the DORMANT state, this service call initializes the following information to values that are set during task creation.
- Priority (current priority)
Note 3 If the return instruction is written in a task, it executes the same operation as this service call.
Note 4 In the RI78V4, code efficiency is enhanced by coding the return instruction as a "Terminate invoking task".
Other tasks are forcibly terminated by issuing the following service call from the processing program.
-
ter_tsk
This service call forcibly moves a task specified by parameter
tskid to the DORMANT state.
As a result, the target task is excluded from the RI78V4 scheduling subject.
If an activation request has been queued to the target task (the activation request counter is not set to 0x0) when this service call is issued, this service call moves the task to the DORMANT state, decrements the wakeup request counter (by subtracting 0x1 from the wakeup request counter), and then moves the task from the DORMANT state to the READY state.
The following describes an example for coding this service call.
#include <kernel.h> /*Standard header file definition*/
#include <kernel_id.h> /*System information header file definition*/
void
func_task ( VP_INT exinf )
{
ID tskid = ID_tskA; /*Declares and initializes variable*/
/* ............ */
ter_tsk ( tskid ); /*Terminate task*/
/* ............ */
}
|
Note 1 This service call does not return the OS resource that the target task acquired by issuing a service call such as
sig_sem or
get_mpf. The OS resource have been acquired must therefore be returned before issuing this service call.
Note 2 When moving a task to the DORMANT state, this service call initializes the following information to values that are set during task creation.
- Priority (current priority)
The priority is changed by issuing the following service call from the processing program.
-
chg_pri,
ichg_pri
These service calls change the priority of the task specified by parameter
tskid (current priority) to a value specified by parameter
tskpri.
The following describes an example for coding this service call.
#include <kernel.h> /*Standard header file definition*/
#include <kernel_id.h> /*System information header file definition*/
void
func_task ( VP_INT exinf )
{
ID tskid = ID_tskA; /*Declares and initializes variable*/
PRI tskpri = 15; /*Declares and initializes variable*/
/* ............ */
chg_pri ( tskid, tskpri ); /*Change task priority*/
/* ............ */
}
|
Note If the target task is in the RUNNING or READY state after this service call is issued, this service call re-queues the task at the end of the ready queue corresponding to the priority specified by parameter
tskpri, following priority change processing.
A task status is referenced by issuing the following service call from the processing program.
-
ref_tsk
Stores task state packet (such as current status) of the task specified by parameter
tskid in the area specified by parameter
pk_rtsk.
The following describes an example for coding this service call.
#include <kernel.h> /*Standard header file definition*/
#include <kernel_id.h> /*System information header file definition*/
void
func_task ( VP_INT exinf )
{
ID tskid = ID_tskA; /*Declares and initializes variable*/
T_RTSK pk_rtsk; /*Declares data structure*/
STAT tskstat; /*Declares variable*/
PRI tskpri; /*Declares variable*/
STAT tskwait; /*Declares variable*/
ID wobjid; /*Declares variable*/
UINT actcnt; /*Declares variable*/
UINT wupcnt; /*Declares variable*/
UINT suscnt; /*Declares variable*/
/* ............ */
ref_tsk ( tskid, &pk_rtsk );/*Reference task state*/
tskstat = pk_rtsk.tskstat; /*Reference task current state*/
tskpri = pk_rtsk.tskpri; /*Reference task current priority*/
tskwait = pk_rtsk.tskwait; /*Reference reason for waiting*/
wobjid = pk_rtsk.wobjid; /*Reference object ID number for which the task is
waiting*/
actcnt = pk_rtsk.actcnt; /*Reference activation request count*/
wupcnt = pk_rtsk.wupcnt; /*Reference wakeup request count*/
suscnt = pk_rtsk.suscnt; /*Reference suspension count*/
/* ............ */
}
|