Ucos ii Task Management 4: Changing the priority of a task

Source: Internet
Author: User

 

Ucos ii Task Management 4: Changing the priority of a task

In ucos ii, the priority of a task can be changed. One advantage of modifying the task priority is that it can solve the priority flip problem.

What is priority flip? Secretly Baidu

Priority inversion: when a high-priority task accesses shared resources through the semaphore mechanism, the semaphore has been occupied by a low-priority task, this low-priority task may be preemptible by some other medium-priority tasks when accessing shared resources. As a result, many high-priority tasks are blocked by low-priority tasks, making it difficult to guarantee real-time performance.

When accessing shared resources, you can modify the priority of a task to solve the priority flip problem.

However, changing the priority of a task also takes a long time. If the priority of a task is increased without a priority flip, and resources are released and changed back to the original priority, a lot of CPU time is wasted. The priorities of tasks were not changed in the mc2008 project.

It is easy to change the priority of a task. It is mainly used to call the ucos ii system function ostaskchangeprio (int8u oldprio, int8u newprio). It requires two parameters, one is the original priority of a task, and the other is the priority after the task is changed.

Next, we will thoroughly dissect the implementation process of ostaskchangeprio (int8u oldprio, int8u newprio. This process is boring.

Program list l 4.15 ostaskchangeprio ().

Int8u ostaskchangeprio (int8u oldprio, int8u newprio)

{

OS _tcb * ptcb;

OS _event * pevent;

Int8u X;

Int8u y;

Int8u bitx;

Int8u bity;

 

 

If (oldprio> = OS _lowest_prio & oldprio! = OS _prio_self) | (1)

Newprio> = OS _lowest_prio ){

Return (OS _prio_invalid );

}

OS _enter_critical ();

If (ostcbpriotbl [newprio]! = (OS _tcb *) 0) {(2)

OS _exit_critical ();

Return (OS _prio_exist );

} Else {

Ostcbpriotbl [newprio] = (OS _tcb *) 1; (3)

OS _exit_critical ();

Y = newprio> 3; (4)

Bity = osmaptbl [y];

X = newprio & 0x07;

Bitx = osmaptbl [x];

OS _enter_critical ();

If (oldprio = OS _prio_self) {(5)

Oldprio = ostcbcur-> ostcbprio;

}

If (ptcb = ostcbpriotbl [oldprio])! = (OS _tcb *) 0) {(6)

Ostcbpriotbl [oldprio] = (OS _tcb *) 0; (7)

If (osrdytbl [ptcb-> ostcby] & ptcb-> ostcbbitx) {(8)

If (osrdytbl [ptcb-> ostcby] & = ~ Ptcb-> ostcbbitx) = 0) {(9)

Osrdygrp & = ~ Ptcb-> ostcbbity;

}

Osrdygrp | = bity; (10)

Osrdytbl [y] | = bitx;

} Else {

If (pevent = ptcb-> ostcbeventptr )! = (OS _event *) 0) {(11)

If (pevent-> oseventtbl [ptcb-> ostcby] & =

~ Ptcb-> ostcbbitx) = 0 ){

Pevent-> oseventgrp & = ~ Ptcb-> ostcbbity;

}

Pevent-> oseventgrp | = bity; (12)

Pevent-> oseventtbl [y] | = bitx;

}

}

Ostcbpriotbl [newprio] = ptcb; (13)

Ptcb-> ostcbprio = newprio; (14)

Ptcb-> ostcby = y; (15)

Ptcb-> ostcbx = X;

Ptcb-> ostcbbity = bity;

Ptcb-> ostcbbitx = bitx;

OS _exit_critical ();

Ossched (); (16)

Return (OS _no_err );

} Else {

Ostcbpriotbl [newprio] = (OS _tcb *) 0; (17)

OS _exit_critical ();

Return (OS _prio_err );

}

}

}

To modify the task priority, follow these steps:

1. First, you cannot change the priority of idle tasks [l4.15 (1)], but you can change the priority of tasks or other tasks that call this function. To change the priority of the task that calls this function, you can specify the current priority of the task or OS _prio_self, ostaskchangeprio () determines the priority of the task. You must also specify the new (desired) Priority of the task. Because μC/OS-ⅱ does not allow many tasks to have the same priority, ostaskchangeprio () needs to check whether the new priority is valid (that is, there is no task with the new priority) [l4.15 (2)]. If the new priority is valid, μ c/OS-ⅱ reserves this priority [l4.15 (3)] by storing something in ostcbpriotbl [newprio]. In this way, ostaskchangeprio () can be interrupted again, because it is no longer possible for other tasks to Establish a task with this priority, or to call ostaskchangeprio () by specifying the same priority (). Next, ostaskchangeprio () can pre-calculate some values in OS _tcb of the new priority task [l4.15 (4)]. These values are used to put the task into or remove from the ready table (see 3.04, ready table ).

2. Second, ostaskchangeprio () checks whether the current task wants to change its priority [l4.15 (5)]. Then, ostaskchangeprio () checks whether the task to change its priority has [l4.15 (6)]. Obviously, if the task whose priority is to be changed is the current task, this test will succeed. However, if the task that ostaskchangeprio () wants to change its priority does not exist, it must put the new priority retained back to the priority table ostcbpriotbl [] [l4.15 (17)], and return an error code to the caller.

3. Again, ostaskchangeprio () removes [l4.15 (7)] from the priority table by inserting a null pointer to OS _tcb of the current task. This allows the old priority of the current task to be reused. Next, let's check if the ostaskchangeprio () task to change its priority is ready [l4.15 (8)]. If the task is in the ready state, it must remove [l4.15 (9)] from the ready table under the current priority. then insert it to the ready table [l4.15 (10)] under the new priority. Note that ostaskchangeprio () uses the recalculated value [l4.15 (4)] to insert the task into the ready table.

If the task is ready, it may be waiting for a semaphore, an email, or a message queue. If the ostcbeventptr is not null (not null) [l4.15 (8)], ostaskchangeprio () will know that the task is waiting for the above. If a task is waiting for an event, ostaskchangeprio () must remove the task from the waiting queue (under the old priority) of the event control block (see 6.00, event control block. And insert the event to the waiting queue under the new priority [l4.15 (12)]. The task may also be waiting for the expiration of the delay (see chapter 5-task management) or suspended (see section 4.07, pending the task, ostasksuspend ()). In these cases, the rows from l4.15 (8) To l4.15 (12) can be skipped.

4. Finally, this is the most critical step. The task priority is modified here. In short, it is to modify the parameters in the task control block. In the task block, the values of the variables ostcbprio, ostcby, ostcbx, ostcbbity, and ostcbbitx indicate the priority of the task. Modifying the task priority is to modify the values of these variables. Ostaskchangeprio () saves the pointer to the task OS _tcb to ostcbpriotbl [] [l4.15 (13)]. The new priority is stored in OS _tcb [l4.15 (14)], and the recalculated value is also stored in OS _tcb [l4.15 (15)]. After ostaskchangeprio () completes the key steps, when the new priority is higher than the old priority or the new priority is higher than the priority of the task that calls the function, the task scheduler is called [l4.15 (16)].

 

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.