CHAPTER 4 TASK MANAGEMENT FUNCTIONS


This chapter describes the task management functions performed by the RI600PX.

4.1 Outline

The task management functions provided by the RI600PX include a function to reference task statuses such as priorities and detailed task information, in addition to a function to manipulate task statuses such as generation, activation and termination of tasks.

4.2 Tasks

A task is processing program that is not executed unless it is explicitly manipulated via service calls provided by the RI600PX, unlike other processing programs (interrupt handler, cyclic handler and alarm 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 RI600PX is saved and the task context of the next task to be executed is loaded.

4.2.1 Task state

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 RI600PX.

The RI600PX classifies task states into the following seven types.

Figure 4-1 Task State



1 ) Non-existent state

The task has not been registered in the RI600PX. This is a virtual state.

2 ) DORMANT state

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 RI600PX, is not subject to RI600PX scheduling.


3 ) READY state

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.

4 ) RUNNING state

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.


5 ) WAITING state

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 RI600PX, the WAITING state is classified into the following 12 types according to their required conditions and managed.



Table 4-1 WAITING State

WAITING State

Service Calls

Sleeping state

Delayed state

WAITING state for a semaphore resource

WAITING state for an eventflag

Sending WAITING state for a data queue

Receiving WAITING state for a data queue

Receiving WAITING state for a mailbox

WAITING state for a mutex

Sending WAITING state for a message buffer

Receiving WAITING state for a message buffer

WAITING state for a fixed-sized memory block

WAITING state for a variable-sized memory block



6 ) SUSPENDED state

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.


7 ) 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.


4.2.2 Task priority

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 RI600PX, 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 RI600PX, the following two types of priorities are used for management purposes.

- Current priority
The RI600PX performs the following processing according to current priority.


- Task scheduling (Refer to "16.4 Task Scheduling Method")

- Queuing tasks to a wait queue in the order of priority

Note The current priority immediately after it moves from the DORMANT state to the READY state is specified at creating the task.

- Base priority
Unless mutex is used, the base priority is the same as the current priority. When using mutex, refer to "8.2.2 Current priority and base priority".


Note 1 In the RI600PX, a task having a smaller priority number is given a higher priority.

Note 2 The priority range that can be specified in a system can be defined by Maximum task priority (priority) in System Information (system)) when creating a system configuration file.

4.2.3 Basic form of tasks

The following shows the basic form of tasks.

 #include    "kernel.h"              /*Standard header file definition*/
 #include    "kernel_id.h"           /*Header file generated by cfg600px*/
 #pragma task Task1                  /*Refer to note 4*/
 void Task1 (VP_INT exinf);          /*Refer to note 4*/
 void Task1 (VP_INT exinf)
 {
     /* ......... */
 
     ext_tsk ();                     /*Terminate invoking task*/
 }


Note 1 The following information is passed to exinf.
How to activate

exinf

TA_ACT attribute is specified at the task creation

Extended information specified at the task creation.

Start code (stacd) specified by sta_tsk or ista_tsk



Note 2 When the return instruction is issued in a task, the same processing as ext_tsk is performed.

Note 3 For details about the extended information, refer to "4.5 Activate Task".

Note 4 These statements are unnecessary for the task which is created by the system configuration file because the cfg600px generates these statement into the "kernel_id.h".

4.2.4 Internal processing of task

In the RI600PX, original dispatch processing (task scheduling) is executed during task switching.

Therefore, note the following points when coding tasks.

- Stack
Tasks use user stacks that are defined in Task Information (task[]), cre_tsk or acre_tsk.


- Service call
Tasks can issue service calls whose "Useful range" is "Task".


- PSW register when processing is started

Table 4-2 PSW Register When Task Processing is Started

Bit

Value

Note

I

1

All interrupts are acceptable.

IPL

0

PM

1

User mode

U

1

User stack

C, Z, S, O

Undefined

Others

0



- FPSW register when processing is started
When setting of Task context register (context) in System Information (system) includes "FPSW", the FPSW when processing is started is shown in Table 4-3. The FPSW when processing is undefined in other cases.


Table 4-3 FPSW Register When Task Processing is Started

Compiler options

Value

-round

-denormalize

nearest (default)

off (default)

0x00000100 (Only DN bit is 1.)

on

0

zero

off (default)

0x00000101 (Only DN bit and RM bit are 1.)

on

1 (Only RM bit is 1.)



4.2.5 Processor mode of task

The processor mode at the time of task execution is always user mode. It is impossible to execute a task in the supervisor mode.

Processing to execute in the supervisor mode should be implemented as an interrupt handler for INT instruction.

For example, the WAIT instruction, that changes the CPU to the power saving mode, is privilege instruction. The WAIT instruction should execute in the supervisor mode.

Note, INT #1 to #8 are reserved by the RI600PX, application cannot use INT #1 to #8.

4.3 Create Task

Tasks are created by one of the following methods.

1 ) Creation by the system configuration file
The static API "task[]" described in the system configuration file creates a task.
Refer to "20.10 Task Information (task[])" for the details of "task[]".



2 ) Creation by cre_tsk or acre_tsk
The cre_tsk creates a task with task ID indicated by parameter tskid according to the content of parameter pk_ctsk.
The acre_tsk creates a task according to the content of parameter pk_ctsk, and returns the created task ID.
The information specified is shown below.



- Task attribute (tskatr)
The following informations are specified as tskatr.


- The domain to which the task belongs
Refer to "3.2 Domain, Memory object, Access permission vector" for the details of the domain.


- Specification started after creation (TA_ACT attribute)
When the TA_ACT attribute is specified, the created task makes a transition to the READY state. When the TA_ACT attribute is not specified, the created task makes a transition to the DORMANT state.


- Extended information (exinf)

- Task start address (task)

- Task initial priority (itskpri)

- User stack size (stksz), Start address of user stack (stk)
The user stack area must satisfy the following.


- The start address must be 16-bytes boundary.

- The size must be multiple of 16.

- The user stack area must not overwrap with either all user stacks and all memory objects.

These service calls can be called from tasks that belong to Trusted Domain.
The following describes an example for coding acre_tsk as a representative.


 #include    "kernel.h"              /*Standard header file definition*/
 #include    "kernel_id.h"           /*Header file generated by cfg600px*/
 
 extern void Task2 (VP_INT exinf);
 #pragma section B SU_STACK2         /*Section for user stack area*/
                                     /*It is necessary to locate 16-byte boundary*/
                                     /*address at linking.*/
 #define STKSZ2 256                  /*The user stack size must be multiple of 16.*/
 static UW Stack2[STKSZ2/sizeof(UW)]; /*User stack area*/
 #pragma section
 
 #pragma task Task1                  /*Refer to note*/
 void Task1 (VP_INT exinf);          /*Refer to note*/
 void Task1 (VP_INT exinf)
 {
     ER_ID  tskid;                   /*Declares variable*/
     T_CTSK pk_ctsk = {              /*Declares and initializes variable*/
         TA_DOM(1)|TA_ACT,               /*Task attribute (tskatr)*/
         0,                              /*Extended information (exinf)*/
         (FP)Task2,                      /*Task start address (task)*/
         1,                              /*Task initial priority (itskpri)*/
         STKSZ2,                         /*User stack size (stksz)*/
         (VP)Stack2                      /*Start address of user stack (stk)*/
     };
     /* ......... */
 
     tskid = acre_tsk ( &pk_ctsk );  /*Creates task*/
 
     /* ......... */
 }


Note These statements are unnecessary for the task which is created by the system configuration file because the cfg600px generates these statement into the "kernel_id.h".

4.4 Delete Task

Tasks are deleted by one of the following methods.

1 ) Delete invoking task by exd_tsk
The exd_tsk terminates the invoking task normally and deletes the task.
The following describes an example for coding this service call.


.
 #include    "kernel.h"              /*Standard header file definition*/
 #include    "kernel_id.h"           /*Header file generated by cfg600px*/
 #pragma task Task1                  /*Refer to note*/
 void Task1 (VP_INT exinf);          /*Refer to note*/
 void Task1 (VP_INT exinf)
 {
     /* ......... */
 
     exd_tsk ();                     /*Terminate and delete invoking task*/
 }


Note 1 When the invoking task has locked mutexes, the locked state are released at the same time (processing equivalent to unl_mtx).

Note 2 These statements are unnecessary for the task which is created by the system configuration file because the cfg600px generates these statement into the "kernel_id.h".

2 ) Delete another task by del_tsk
The del_tsk deletes the task in the DORMANT state indicated by parameter tskid.
This service call can be called from tasks that belong to Trusted Domain.
The following describes an example for coding this service call.



.
 #include    "kernel.h"              /*Standard header file definition*/
 #include    "kernel_id.h"           /*Header file generated by cfg600px*/
 #pragma task Task1                  /*Refer to note*/
 void Task1 (VP_INT exinf);          /*Refer to note*/
 void Task1 (VP_INT exinf)
 {
     ID      tskid = 8;              /*Declares and initializes variable*/
     /* ......... */
 
     del_tsk ( tskid );              /*Delete other task*/
 }


Note These statements are unnecessary for the task which is created by the system configuration file because the cfg600px generates these statement into the "kernel_id.h".

4.5 Activate Task

The RI600PX provides two types of interfaces for task activation: queuing an activation request queuing and not queuing an activation request.

4.5.1 Activate task with queuing

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 the 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 RI600PX.
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 1 to the activation request counter).
The following describes an example for coding these service calls.




 #include    "kernel.h"          /*Standard header file definition*/
 #include    "kernel_id.h"       /*Header file generated by cfg600px*/
 #pragma task Task1                  /*Refer to note 3*/
 void Task1 (VP_INT exinf);          /*Refer to note 3*/
 void Task1 (VP_INT exinf)
 {
     ID      tskid = 8;          /*Declares and initializes variable*/
 
     /* ......... */
 
     act_tsk (tskid);            /*Activate task (queues an activation request)*/
 
     /* ......... */
 }


Note 1 The activation request counter managed by the RI600PX is configured in 8-bit widths. If the number of activation requests exceeds the maximum count value 255 as a result of issuing this service call, the counter manipulation processing is therefore not performed but "E_QOVR" is returned.

Note 2 Extended information specified at creating the task is passed to the task activated by issuing these service calls.

Note 3 These statements are unnecessary for the task which is created by the system configuration file because the cfg600px generates these statement into the "kernel_id.h".

4.5.2 Activate task without queuing

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 the 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 RI600PX.
This service call does not perform queuing of activation requests. If the target task is in a state other than the DORMANT state, the status manipulation processing for the target task is therefore not performed but "E_OBJ" is returned.
Specify for parameter stacd the extended information transferred to the target task.
The following describes an example for coding these service calls.





 #include    "kernel.h"              /*Standard header file definition*/
 #include    "kernel_id.h"           /*Header file generated by cfg600px*/
 #pragma task Task1                  /*Refer to note*/
 void Task1 (VP_INT exinf);          /*Refer to note*/
 void Task1 (VP_INT exinf)
 {
     ID      tskid = 8;          /*Declares and initializes variable*/
     VP_INT  stacd = 123;        /*Declares and initializes variable*/
 
     /* ......... */
 
     sta_tsk (tskid, stacd);     /*Activate task (does not queue an activation */
                                 /*request)*/
 
     /* ......... */
 }


Note These statements are unnecessary for the task which is created by the system configuration file because the cfg600px generates these statement into the "kernel_id.h".

4.6 Cancel Task Activation Requests

An activation request is cancelled by issuing the following service call from the processing program.

- can_act, ican_act
This service call cancels all of the activation requests queued to the task specified by parameter tskid (sets the activation request counter to 0).
When this service call is terminated normally, the number of cancelled activation requests is returned.
The following describes an example for coding these service calls.



 #include    "kernel.h"              /*Standard header file definition*/
 #include    "kernel_id.h"           /*Header file generated by cfg600px*/
 #pragma task Task1                  /*Refer to note 2*/
 void Task1 (VP_INT exinf);          /*Refer to note 2*/
 void Task1 (VP_INT exinf)
 {
     ER_UINT ercd;                   /*Declares variable*/
     ID      tskid = 8;              /*Declares and initializes variable*/
 
     /* ......... */
 
     ercd = can_act (tskid);         /*Cancel task activation requests*/
 
     if (ercd >= 0) {
         /* ......... */             /*Normal termination processing*/
     }
 
     /* ......... */
 }


Note 1 This service call does not perform status manipulation processing but performs the setting of activation request counter. Therefore, the task does not move from a state such as the READY state to the DORMANT state.

Note 2 These statements are unnecessary for the task which is created by the system configuration file because the cfg600px generates these statement into the "kernel_id.h".

4.7 Terminate Task

4.7.1 Terminate invoking task

The invoking task is terminated by issuing the following service call from the processing program.

- ext_tsk
This service call moves the 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 RI600PX scheduling subject.
If an activation request has been queued to the invoking task (the activation request counter > 0) when this service call is issued, this service call moves the task from the RUNNING state to the DORMANT state, decrements the wake-up request counter (by subtracting 1 from the activation 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"           /*Header file generated by cfg600px*/
 #pragma task Task1                  /*Refer to note 3*/
 void Task1 (VP_INT exinf);          /*Refer to note 3*/
 void Task1 (VP_INT exinf)
 {
     /* ......... */
 
     ext_tsk ();                     /*Terminate invoking task*/
 }


Note 1 When the invoking task has locked mutexes, the locked state are released at the same time (processing equivalent to unl_mtx).

Note 2 When the return instruction is issued in a task, the same processing as ext_tsk is performed.

Note 3 These statements are unnecessary for the task which is created by the system configuration file because the cfg600px generates these statement into the "kernel_id.h".

4.7.2 Terminate Another task

- ter_tsk
This service call forcibly moves the task specified by parameter tskid to the DORMANT state.
As a result, the target task is excluded from the RI600PX scheduling subject.
If an activation request has been queued to the target task (the activation request counter > 0) when this service call is issued, this service call moves the task to the DORMANT state, decrements the activation request counter (by subtracting 1 from the wake-up 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"           /*Header file generated by cfg600px*/
 #pragma task Task1                  /*Refer to note 2*/
 void Task1 (VP_INT exinf);          /*Refer to note 2*/
 void Task1 (VP_INT exinf)
 {
     ID      tskid = 8;              /*Declares and initializes variable*/
 
     /* ......... */
 
     ter_tsk (tskid);                /*Terminate task*/
 
     /* ......... */
 }


Note 1 When the target task has locked mutexes, the locked state are released at the same time (processing equivalent to unl_mtx).

Note 2 These statements are unnecessary for the task which is created by the system configuration file because the cfg600px generates these statement into the "kernel_id.h".

4.8 Change Task Priority

The priority is changed by issuing the following service call from the processing program.

- chg_pri, ichg_pri
This service call changes the base priority of the task specified by parameter tskid to a value specified by parameter tskpri.
The changed base priority is effective until the task terminates or this servie call is issued. When next the task is activated, the base priority is the initial priority which is specified at the task creation.
This service call also changes the current priority of the target task to a value specified by parameter tskpri. However, the current priority is not changed when the target task has locked mutexes.
If the target task has locked mutexes or is waiting for mutex to be locked and if tskpri is higher than the ceiling priority of either of the mutexes, this service call returns "E_ILUSE".
When the current priority is changed, the following state variations are generated.





1 ) When the target task is in the RUNNING or READY state.
This service call re-queues the task at the end of the ready queue corresponding to the priority specified by parameter tskpri.


2 ) When the target task is queued to a wait queue of the object with TA_TPRI or TA_CEILING attribute.
This service call re-queues the task to the wait queue corresponding to the priority specified by parameter tskpri. When two or more tasks of same current priority as this service call re-queues the target task at the end among their tasks.


Example When three tasks (task A: priority level 10, task B: priority level 11, task C: priority level 12) are queued to the semaphore wait queue in the order of priority, and the priority level of task B is changed from 11 to 9, the wait order will be changed as follows.



The following describes an example for coding these service calls.

 #include    "kernel.h"              /*Standard header file definition*/
 #include    "kernel_id.h"           /*Header file generated by cfg600px*/
 #pragma task Task1                  /*Refer to note 2*/
 void Task1 (VP_INT exinf);          /*Refer to note 2*/
 void Task1 (VP_INT exinf)
 {
     ID      tskid = 8;              /*Declares and initializes variable*/
     PRI     tskpri = 9;             /*Declares and initializes variable*/
 
     /* ......... */
 
     chg_pri (tskid, tskpri);        /*Change task priority*/
 
     /* ......... */
 }


Note 1 For current priority and base priority, refer to "8.2.2 Current priority and base priority".

Note 2 These statements are unnecessary for the task which is created by the system configuration file because the cfg600px generates these statement into the "kernel_id.h".

4.9 Reference Task Priority

A task priority is referenced by issuing the following service call from the processing program.

- get_pri, iget_pri
Stores current priority of the task specified by parameter tskid in the area specified by parameter p_tskpri.
The following describes an example for coding these service calls.


 #include    "kernel.h"              /*Standard header file definition*/
 #include    "kernel_id.h"           /*Header file generated by cfg600px*/
 #pragma task Task1                  /*Refer to note 2*/
 void Task1 (VP_INT exinf);          /*Refer to note 2*/
 void Task1 (VP_INT exinf)
 {
     ID      tskid = 8;              /*Declares and initializes variable*/
     PRI     p_tskpri;               /*Declares variable*/
 
     /* ......... */
 
     get_pri (tskid, &p_tskpri);     /*Reference task priority*/
 
     /* ......... */
 }


Note 1 For current priority and base priority, refer to "8.2.2 Current priority and base priority".

Note 2 These statements are unnecessary for the task which is created by the system configuration file because the cfg600px generates these statement into the "kernel_id.h".

4.10 Reference Task State

4.10.1 Reference task state

A task status is referenced by issuing the following service call from the processing program.

- ref_tsk, iref_tsk
Stores task state packet (current state, current priority, etc.) of the task specified by parameter tskid in the area specified by parameter pk_rtsk.
The following describes an example for coding these service calls.


 #include    "kernel.h"              /*Standard header file definition*/
 #include    "kernel_id.h"           /*Header file generated by cfg600px*/
 #pragma task Task1                  /*Refer to note 2*/
 void Task1 (VP_INT exinf);          /*Refer to note 2*/
 void Task1 (VP_INT exinf)
 {
     ID      tskid = 8;              /*Declares and initializes variable*/
     T_RTSK  pk_rtsk;                /*Declares data structure*/
     STAT    tskstat;                /*Declares variable*/
     PRI     tskpri;                 /*Declares variable*/
     PRI     tskbpri;                /*Declares variable*/
     STAT    tskwait;                /*Declares variable*/
     ID      wobjid;                 /*Declares variable*/
     TMO     lefttmo;                /*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 current state*/
     tskpri = pk_rtsk.tskpri;        /*Reference current priority*/
     tskbpri = pk_rtsk.tskbpri;      /*Reference base priority*/
     tskwait = pk_rtsk.tskwait;      /*Reference reason for waiting*/
     wobjid = pk_rtsk.wobjid;        /*Reference object ID number for which the */
                                     /*task is waiting*/
     lefttmo = pk_rtsk.lefttmo;      /*Reference remaining time until time-out*/
     actcnt = pk_rtsk.actcnt;        /*Reference activation request count*/
     wupcnt = pk_rtsk.wupcnt;        /*Reference wake-up request count*/
     suscnt = pk_rtsk.suscnt;        /*Reference suspension count*/
 
     /* ......... */
 }


Note 1 For details about the task state packet, refer to "[Task state packet: T_RTSK]".

Note 2 These statements are unnecessary for the task which is created by the system configuration file because the cfg600px generates these statement into the "kernel_id.h".

4.10.2 Reference task state (simplified version)

A task status (simplified version) is referenced by issuing the following service call from the processing program.

- ref_tst, iref_tst
Stores task state packet (current state, reason for waiting) of the task specified by parameter tskid in the area specified by parameter pk_rtst.
Used for referencing only the current state and reason for wait among task information.
Response becomes faster than using ref_tsk or iref_tsk because only a few information items are acquired.
The following describes an example for coding these service calls.




 #include    "kernel.h"              /*Standard header file definition*/
 #include    "kernel_id.h"           /*Header file generated by cfg600px*/
 #pragma task Task1                  /*Refer to note 2*/
 void Task1 (VP_INT exinf);          /*Refer to note 2*/
 void Task1 (VP_INT exinf)
 {
     ID      tskid = 8;              /*Declares and initializes variable*/
     T_RTST  pk_rtst;                /*Declares data structure*/
     STAT    tskstat;                /*Declares variable*/
     STAT    tskwait;                /*Declares variable*/
 
     /* ......... */
 
     ref_tst (tskid, &pk_rtst);      /*Reference task state (simplified version)*/
 
     tskstat = pk_rtst.tskstat;      /*Reference current state*/
     tskwait = pk_rtst.tskwait;      /*Reference reason for waiting*/
 
     /* ......... */
 }


Note 1 For details about the task state packet (simplified version), refer to " [Task state packet (simplified version): T_RTST]".

Note 2 These statements are unnecessary for the task which is created by the system configuration file because the cfg600px generates these statement into the "kernel_id.h".