Ucos Task Control block detailed

Source: Internet
Author: User

Ucos the basis for multi-tasking consists of several aspects: Task control block, task stack, interrupt, task priority, and so on.

First, the structure of the task control block is as follows

When the system runs a task, it gets the task control block according to the priority of the task, and then obtains the task code pointer in the task stack.

typedef struct OS_TCB {//Task control block

OS_STK *ostcbstkptr; /* Pointer to top of task stack stack */

#if os_task_create_ext_en > 0u

void *ostcbextptr; /* Pointer to the task control block extension */

OS_STK *ostcbstkbottom; /* Pointer to the bottom of the task stack */

INT32U ostcbstksize; /* Length of the task stack */

int16u ostcbopt; /* Select item when creating a task */

int16u Ostcbid; /* The domain is not currently in use */

#endif

struct OS_TCB *ostcbnext; /* Pointer to the back of a task control block */

struct OS_TCB *ostcbprev; /* Pointer to the previous task control block */

#if (os_event_en)

Os_event *ostcbeventptr; /* */

#endif

#if (os_event_en) && (Os_event_multi_en > 0u)

Os_event **ostcbeventmultiptr; /* Pointer to the event control block */

#endif

#if ((Os_q_en > 0u) && (Os_max_qs > 0u)) | | (Os_mbox_en > 0u)

void *ostcbmsg; /* Point to the pointer passed to the task message */

#endif

#if (Os_flag_en > 0u) && (Os_max_flags > 0u)

#if os_task_del_en > 0u

Os_flag_node *ostcbflagnode; /* Pointer to Event flag node */

#endif

Os_flags Ostcbflagsrdy; /* Event flag Settings make task ready to execute */

#endif

INT32U ostcbdly; /* Number of Beats waiting on task */

Int8u Ostcbstat; /* The current status flag for the task */

The task status has the following list

/******************************************

Os_stat_rdy Status Ready

Os_stat_sem Waiting Signal Volume

Os_stat_mbox Waiting for message mailbox

Os_stat_q waiting for Message Queuing

Os_stat_suspend Task hangs

Os_stat_mutex waiting for mutex signal volume

Os_stat_flag Wait Sign

Os_stat_multi wait for more that what, still don't know

************************************************/

Int8u Ostcbprio; /* Priority level of the task */

Int8u OSTCBX; /* Data for quick access to ready tables */

Int8u Ostcby; /* Quick access to Ready table data */

Os_prio Ostcbbitx; /* Quick access to Ready table data */

Os_prio ostcbbity; /* Quick access to Ready table data */

#if os_task_del_en > 0u

Int8u Ostcbdelreq; /* Flag requested when deleting a task */

#endif

#if os_task_profile_en > 0u//This is used to monitor the execution status of a task.

INT32U ostcbctxswctr; /* The number of times the task is switched to */

INT32U Ostcbcyclestot; /* Total number of Beats running on the task */

INT32U Ostcbcyclesstart; /* Fast clock cycle at start of task */

OS_STK *ostcbstkbase; /* Start position of the task stack */

INT32U ostcbstkused; /* Number of stacks already in use */

#endif

#if os_task_name_en > 0u

int8u *ostcbtaskname;//Task TCB's name string pointer

#endif

#if os_task_reg_tbl_size > 0u

INT32U ostcbregtbl[os_task_reg_tbl_size];//here should be a quick save data for the task register

#endif

} OS_TCB;

This structure has more than the macro definition of open variables, for the time being not discussed, mainly have these several more important

OS_STK *ostcbstkptr; /* Pointer to top of task stack stack */

struct OS_TCB *ostcbnext; /* Pointer to the back of a task control block */

struct OS_TCB *ostcbprev; /* Pointer to the previous task control block */

Int8u Ostcbprio; /* Priority level of the task */

Why there is no pointer to the task code, this is because the task code is stored in the stack area of the operating system, we know, for the task, the task code pointer actually refers to the execution of this code, the processor's PC pointer, when the system is interrupted, the pointer automatically saved, after the execution of the interrupt automatic recovery, Execution of the original process, the principle of ucos is to design a system-level interrupt, the timing of the interruption, the execution of the interruption and automatic recovery process changes into a task switching process, the switching process to restore our own task stack to the actual CPU stack, Automatically switch to a new task to achieve multitasking. Visible, the task code is exactly what should be placed on the stack, followed by the code.

In addition, the operating system's task control block is not a dynamic application, but the compile time has been determined how many, as follows

Os_ext OS_TCB ostcbtbl[os_max_tasks + os_n_sys_tasks]; /* Table of TCBs */

Os_max_tasks and os_n_sys_tasks are defined by the Os_cfg file, the previous refers to the maximum number of system tasks, the latter is the number of system retention tasks, the system has only a few of these task control blocks, so up to so many tasks, There is also an associated global variable

Os_ext OS_TCB *ostcbpriotbl[os_lowest_prio + 1u];

This variable will save a pointer to all the task control blocks already set in the system (that is, create Task), his size is the maximum system priority, Ucos does not allow the priority to repeat the reason is here, he will be the system's task control block in the form of priority in this array, so, When switching tasks, it is not necessary to poll the task control block list, but to get the task priority immediately after getting the task control block in the Ostcbpriotbl table, the efficiency is much faster (not just a lot of problems, real-time system requirements code running efficiency is predictable, The time to poll the list is not deterministic, it may be found for the first time, or it may not be found at the end.

There are also several necessary variables

Os_ext OS_TCB *ostcbcur;

Os_ext OS_TCB *ostcbfreelist;

Os_ext OS_TCB *ostcbhighrdy;

Os_ext OS_TCB *ostcblist;

Ostcbcur identifies the currently running TCB block, ostcbfreelist the free TCB block chain header pointer in all TCB in the system, Ostcbhighrdy the highest priority TCB block currently ready, the target of the next switch, Ostcblist System effective TCB block's chain header pointer

As we have seen before, there is a pointer to next in the TCB variable structure and a prev pointer, which is used to construct the linked list, which is constructed when the system is initialized, but first we need to understand one thing, regardless of whether the linked list forms a divine horse structure, The actual data elements are still stored in the OSTCBTBL array, but only when the program is used to organize a linked list.

When the system is initialized, the program calls the Os_init function (external programming call), calls the Os_inittcblist function in the Os_init, implements the empty list initialization in the Os_inittcblist, as follows

static void Os_inittcblist (void)

{

Int8u IX;

Int8u Ix_next;

OS_TCB *PTCB1;

OS_TCB *PTCB2;

OS_MEMCLR ((int8u *) &ostcbtbl[0], sizeof (OSTCBTBL));

OS_MEMCLR ((int8u *) &ostcbpriotbl[0], sizeof (OSTCBPRIOTBL));

for (ix = 0u; IX < (os_max_tasks + os_n_sys_tasks-1u); ix++)

{

Ix_next = IX + 1u;

PTCB1 = &OSTCBTbl[ix];

PTCB2 = &OSTCBTbl[ix_next];

Ptcb1->ostcbnext = PTCB2;

#if os_task_name_en > 0u

Ptcb1->ostcbtaskname = (int8u *) (void *) "?";

#endif

}

PTCB1 = &OSTCBTbl[ix];

Ptcb1->ostcbnext = (OS_TCB *) 0;

#if os_task_name_en > 0u

Ptcb1->ostcbtaskname = (int8u *) (void *) "?";

#endif

Ostcblist = (OS_TCB *) 0;                Ostcbfreelist = &OSTCBTbl[0]; }

You can see, enter this function, through a loop, all the elements in the ostcbtbl into a large linked list, the head of the list is ostcbfreelist, so that the empty task block list is initialized, and then the ostcblist assignment is null, wait for the task to be created

The function called when creating a task is ostaskcreate, and we analyze some of its structure

First, he's going to make a decision. First, you cannot create a task in an interrupt second, task priority cannot be duplicated

if (Ostcbpriotbl[prio] = = (OS_TCB *) 0)

As we said before, when a task is created, its TCB control block is placed in the corresponding position in the OSTCBPRIOTBL based on the priority of the task, then the data at that location will not be 0, at this point, if a new task is detected the priority of the creation of the TCB already has data, indicating that the priority is duplicated, cannot create

Two functions are then called

Ostaskstkinit (Task, P_arg, PTOs, 0u);

Os_tcbinit (Prio, PSP, (OS_STK *) 0, 0u, 0u, (void *) 0, 0u);

The first function is the function that we need to port in OS_CPU_C.C, which is related to the processor architecture, and a detailed view of the porting guide, with a focus on this sentence in Ostaskstkinit

* (Stk) = (int32u) 0x01000000l; /* XPSRXPSR T bit (24th bit) Set 1, otherwise the first time the task is performed fault*/

* (--STK) = (int32u) task; /* Entry POINTPC must point to the mission entrance.

The pointer to the task is stored in the stack, which matches the previous word.

After the stack area is set up, the TCB control block is initialized, and this section of code is longer, with several details.

First, the system should remove a control block from the idle control block and join the effective TCB control block, as follows

PTCB = Ostcbfreelist

if (PTCB! = (OS_TCB *) 0)

{

Ostcbfreelist = ptcb->ostcbnext;

Visible, the table header of the empty list is replaced by the second node, and the table header is used for subsequent operations, that is, the task control block used as the current task.

Ptcb->ostcbstkptr = PTOs;

Ptcb->ostcbprio = Prio;

Ptcb->ostcbstat = Os_stat_rdy;

Ptcb->ostcbstatpend = OS_STAT_PEND_OK;

ptcb->ostcbdly = 0u;

The stack top pointer, task priority, the stack has a task code pointer, to live, after the completion of some of the signal volume and so on after the operation (said later), came to this section

Ostcbpriotbl[prio] = PTCB;

Ptcb->ostcbnext = ostcblist;

Ptcb->ostcbprev = (OS_TCB *) 0;

if (ostcblist! = (OS_TCB *) 0)

{

Ostcblist->ostcbprev = PTCB;

}

Ostcblist = PTCB;

The control block pointer of the currently created task is placed in the OSTCBPRIOTBL, followed directly by priority, the new task control block is connected to the head of the task control block already existing in the system, thus completing an idle control block to the effective control block transfer, and creating the task, Wait for late call

In addition, UCOS defines an idle task to perform the task without a task, so the task must be of the lowest priority, otherwise he will preempt other priority tasks, the task function name

Os_taskidle

The task does nothing at all, in that similar idling run, called by Os_inittaskidle, while Os_inittaskidle is called by Os_init, which automatically creates the task when initializing the system

In addition to the idle task, also defined a statistical task, dedicated to statistical system implementation, such as CPU utilization, to monitor the system, you can then count the task hook function to do the operation of the system output, the relevant variable is oscpuusage

Ucos Task Control block detailed

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.