Available Languages?:

TNKernel : Tasks

Introduction

In TNKernel, a task is a branch of the code that runs concurrently with another tasks from the programmer's point of view. At the physical level, tasks are actually executed using processor time sharing. Each task can be considered to be an independed program, which executes in its own context (processor registers, stack pointer, etc.).

When the currently running task loses its claim for executing (by the issuing of a system call or interrupt), a context switch is performed. The current context (processor registers, stack pointer, etc.) is saved and the context of another task is restored. This mechanism in the TNKernel is called the "dispatcher".

Generally, there are more than one executable task, and it is necessary to determine the order of the task switching (execution) by using some rules. "Scheduler" is a mechanism that controls the order of the task execution.

TNKernel uses a priority-based scheduling based on a priority level assigned to the each task. The smaller the value of the priority, the higher the priority level. TNKernel uses a 16 levels of priority for PIC24/dsPIC port and 32 levels for original ARM version.

Priorities 0 (highest) and 15(31) (lowest) are reserved by the system for the internal using. The user may create tasks with priorities from 1 to 14(30).

In TNKernel, more than one task can have the same (identical) priority.

Task States

There are four task states in TNKernel:

RUNNING
The task is currently executing
READY
The task is ready to execute, but cannot do so because a task with higher priority (sometimes same priority) is already executing. A task may execute at any time once the processor becomes available. In TNKernel, both RUNNING and READY states are marked as RUNNABLE
WAIT/SUSPEND
When a task is in the WAIT/SUSPEND state, the task cannot execute because the conditions necessary for its execution have not yet been met and the task is waiting for them. When a task enters the WAIT/SUSPEND state, the task's context is saved. When the task resumes execution from the WAIT/SUSPEND state, the task's context is restored. WAIT/SUSPEND actually have one of three types:

WAITING The task execution is blocked until some synchronization action occurs, such as timeout expiration, semaphore available, event occurring, etc.
SUSPENDED The task is forced to be blocked (switched to the non-executing state) by another task or itself
WAITING_SUSPENDED Both WAITING and SUSPENDED states co-exist. In TNKernel, if a task leaves a WAITING state, but a SUSPENDED state exists, the task is not switched to the READY/RUNNING state. Similarly, if a task leaves SUSPENDED state, but a WAITING state exists, the task is not switched to the READY/RUNNING state. A task is switched to READY/RUNNING state only if there are neither WAITING nor SUSPENDED states flagged on it.

DORMANT
The task has been initialized and it is not yet executing or it has already exited. Newly created tasks always begin in this state.


One especial state when the task is not created/initialized yet is NON-EXISTENT.

The following picture describe the task states switching rules:

The API fuctions that prompts for a state switsh is shown near the switch direction. For simply prefix tn_task_ and prefix i (call from interrupt) is dropped.

Scheduling rules

In TNKernel, as long as the highest privilege task is running, no other task will execute unless the highest privilege task cannot execute (for instance, for being placed in the WAITING state).

Among tasks with different priorities, the task with the highest priority is the highest privilege task and will execute.

Among tasks of the same priority, the task that entered into the runnable (RUNNING or READY) state first is the highest privilege task and will execute.

Example: Task A has priority 1, tasks B, C, D, E have priority 3, tasks F,G have priority 4, task I has priority 5. If all tasks are in the READY state, this is the sequence of tasks executing :


1. Task A - highest priority (priority 1)
2. Tasks B, C, D, E - in order of entering into runnable state for this priority (priority 3)
3. Tasks F, G - in order of entering into runnable state for this priority (priority 4)
4. Task I - lowest priority (priority 5)

In TNKernel, tasks with the same priority may be scheduled in round robin fashion by getting a predetermined time slice for each task with this priority.

System Tasks

In TNKernel, the task (timer_task) with priority 0 (highest) is used for supporting the system tick timer functionality and the task (idle_task) with priority 15(31) (lowest) is used for performing statistics.

TNKernel automatically creates these tasks at the system start.

Task Control Block

Each task has an associated task control block (TCB), defined as:

typedef struct TN_TCB_S_STRUCT
{
    TN_UWORD                * task_stk;
    CDLL_QUEUE_S              task_queue;
    CDLL_QUEUE_S              timer_queue;
    CDLL_QUEUE_S              block_queue;
    CDLL_QUEUE_S              create_queue;
    CDLL_QUEUE_S              mutex_queue;
    CDLL_QUEUE_S            * pwait_queue;
    struct TN_TCB_S_STRUCT  * blk_task;
 
    TN_UWORD                * stk_start;
    TN_UWORD                  stk_size;
 
    void                    * task_func_addr;
    void                    * task_func_param;
 
    TN_UWORD                  base_priority;
    TN_UWORD                  priority;
    TN_UWORD                  id_task;
 
    TN_WORD                   task_state;
    TN_UWORD                  task_wait_reason;
    TN_WORD                   task_wait_rc;
    TN_UWORD                  tick_count;
    TN_UWORD                  tslice_count;
 
    TN_UWORD                  ewait_pattern;
    TN_UWORD                  ewait_mode;
 
    void                    * data_elem;
 
    TN_UWORD                  activate_count;
    TN_UWORD                  wakeup_count;
    TN_UWORD                  suspend_count;
} TN_TCB_S;
task_stk Pointer to the task's top of stack
task_queue Queue to include task in the ready/wait lists
timer_queue Queue to include task in the timer(timeout,etc.) list
block_queue Queue to include task in the blocked task list only used for mutexes priority ceiling protocol
create_queue Queue is used to include task in create list only
mutex_queue List of all mutexes locked by the tack
pwait_queue Ptr to the object's (semaphor,event,etc.) wait list, the task is waiting for
blk_task Store task blocking our task (for the mutexes priority ceiling protocol only)
stk_start Base address of the task's stack space
stk_size The task stack size (in sizeof (void*), not bytes)
task_func_addr The task function pointer
task_func_param The task function parameter pointer
base_priority Task base priority
priority Task current priority
id_task ID for verification
task_state Task state
task_wait_reason Reason for the waiting
task_wait_rc Waiting return code (reason why waiting finished)
tick_count Remaining time until timeout
tslice_count Time slice counter
ewait_pattern Event wait pattern
ewait_mode Event wait mode: _AND or _OR
data_elem Location to store data queue entry, if the data queue is full
activate_count Activation request count
wakeup_count Wakeup request count
suspend_count Suspension count - for statistic

Task Control Block is available only when TN_DEBUG defined. Nevertheless direct access to Task Control Block is not recommend for the system safety.

Task API

TNKernel has the following API functions for control tasks:

Function Description
Creata and delete task
  tn_task_create() Create task
  tn_task_delete() Delete task
Reset task
  tn_task_exit() Exit from the current task
  tn_task_terminate() Terminate task
  tn_task_activate() Activate task
  tn_task_iactivate() Activate task from interrupt
Suspend and resume task
  tn_task_suspend() Suspend task
  tn_task_isuspend() Suspend task from interrupt
  tn_task_resume() Resume task
  tn_task_iresume() Resume task from interrupt
Sleep and wakeup task
  tn_task_sleep() Sleep task
  tn_task_wakeup() Wakeup task
  tn_task_iwakeup() Wakeup task from interrupt
Forced release from WAITING
  tn_task_release_wait() Forced release from WAITING state
  tn_task_irelease_wait() Forced release from WAITING state in interrupt
Change task priority
  tn_task_change_priority() Change task priority
Get task reference
  tn_task_reference() Get task reference
  tn_task_ireference() Get task reference from interrupt
 
en/tnkernel/ref/task/intro.txt · Last modified: 20.07.2008 22:31 by admin
 
Creative Commons License Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki