μ c/OS-II experiment: second priority inversion and Solution

Source: Internet
Author: User
Tags semaphore
Experiment Description: Note: The CPU cannot be automatically abandoned because of the low priority of the resource. Otherwise, the priority will definitely be reversed. The experiment in the experiment manual is incorrect. Involved μC/OS-II system function :... Experiment code: App. c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/* The task ta0 has the highest priority. It needs to use the semaphore mutex */
Void task0 (void * pdata)
{
Int8u err;
Int8u ID;
Id = * (int *) pdata;
While (1)
{
Printf ("task _ % d waitting for an event \ r \ n", ID );
Ostimedly (1000);/* Delay 1000 clock tick */
Printf ("task _ % d's event came! \ R \ n ", ID );
Printf ("task _ % d trying to get mutex \ r \ n", ID );
Osmutexpend (pmutex, 0, & ERR);/* acquire mutex */
Switch (ERR)
{
Case OS _no_err:
Printf ("task _ % d got mutex. \ r \ n", ID );
Break;
Default:
Printf ("task _ % d cannot get mutex, has been suincluded. \ r \ n", ID );
}
Ostimedly (1000);/* Delay 1000 clock tick */
Printf ("task _ % d release mutex \ r \ n", ID );
Osmutexpost (pmutex);/* release mutex */
}
}
/* The task TA1 has a medium priority. It does not use semaphores */
Void task1 (void * pdata)
{
Int8u ID;
Id = * (int *) pdata;
While (1)
{
Printf ("task _ % d waitting for an event \ r \ n", ID );
Ostimedly (500);/* Delay 500 clock tick */
Printf ("task _ % d's event came! \ R \ n ", ID );
Ostimedly (500 );
}
}

/* The task TA2 has the lowest priority, and the task ta0 shares the semaphore mutex */
Void task2 (void * pdata)
{
Int8u err;
Int8u ID;
Int32u I;
Id = * (int *) pdata;

While (1)
{
Printf ("task _ % d trying to get mutex \ r \ n", ID );
Osmutexpend (pmutex, 0, & ERR);/* acquire mutex */
Switch (ERR)
{
Case OS _no_err:
Printf ("task _ % d got mutex. \ r \ n", ID );
/* At this time, Task 2 occupies resources and CPU, but is preemptible by Task 1. The priority is reversed */
For (I = 0; I <40000000; I ++ );
Break;
Default:
Printf ("task _ % d cannot get mutex, has been suincluded. \ r \ n", ID );
/* At this time, Task 2 occupies resources and CPU, but is preemptible by Task 1. The priority is reversed */
For (I = 0; I <40000000; I ++ );
Break;
}
Printf ("task _ % d release mutex \ r \ n", ID );
Osmutexpost (pmutex);/* releasemutex */
}
}

App. h
1
2
3
4
5
Global OS _event * PSEM;
Global OS _event * pmutex;

# Define n_tasks 3
Global int8u taskdata [n_tasks];

App_cfg.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Define task0_stk_size 64
# Define task1_stk_size 64
# Define task2_stk_size 64

# Define task0_task_prio 4
# Define taskdetailtask_prio 5
# Define task2_task_prio 6

# Ifdef global_stask_define
# Define global
# Else
# Define global extern
# Endif

Global OS _stk task_task0_stk [task0_stk_size];
Global OS _stk task_task1_stk [task1_stk_size];
Global OS _stk task_task2_stk [task2_stk_size];

Void task0 (void * pdata );
Void task1 (void * pdata );
Void task2 (void * pdata );

Main. c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// Start the task
Static void taskstart (void * pdata)
{
Int8u err;
Int8u I;
For (I = 0; I <n_tasks; I ++) // create n_tasks identical tasks
{
Taskdata [I] = I;
}
Pdata = pdata;
// App Initialization
// The system clock must be called after osstart ()
Systick_configuration ();

# If (OS _task_stat_en> 0)
Osstatinit ();
# Endif
# If OS _sem_en> 0 & OS _max_events> 0
PSEM = ossemcreate (int16u) 1 );
# Endif
# If OS _mutex_en> 0 & OS _max_events> 0
Pmutex = osmutexcreate (1, & ERR );
# Endif

/* Reverse the priority of Experiment 2 */
Ostaskcreate (task0, (void *) & taskdata [0], (OS _stk *) & task_task0_stk [TASK0_STK_SIZE-1], task0_task_prio );
Ostaskcreate (task1, (void *) & taskdata [1], (OS _stk *) & task_task1_stk [TASK1_STK_SIZE-1], task1_task_prio );
Ostaskcreate (task2, (void *) & taskdata [2], (OS _stk *) & task_task2_stk [TASK2_STK_SIZE-1], task2_task_prio );

// Delete yourself after creating other tasks
Ostaskdel (OS _prio_self );
}
To use the switch branch, you need to modify the ossempend function in OS _sem.c: otherwise, the switch branch does not work. The default branch indicates whether the switch Branch has been interrupted while obtaining the semaphore. PS: For the convenience of observation, the OS _sem.c file has not been modified. Experimental results: When binary semaphore is used, Task 1 interrupts the latency of Task 2, and the priority is reversed. Note: If the app. in C, all semaphores in the task are changed to mutex semaphores-mutex, and their priority is increased to the highest priority. In this case, Task 2 will not be interrupted by Task 1 during the delay process and will not reverse the priority.
Related Article

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.