UC/OS-II creates a record table in Ram, where each task occupies a position in the table and uses the status (0 and 1) to indicate whether the task is ready. This table is called the task readiness table.
The ready task table is actually an array of int8u type osrdytbl []. Each bit of each byte represents a task, so that an array element can indicate the readiness of eight tasks. In the order of task priority level, for example, the 1st bits of osrdytbl [0] indicate task priority 0, and the 8th bits of osrdytbl [1] indicate task priority 15. when its bit is 1, the task is in the ready state, and 0 is not in the ready state.
We can regard the eight tasks of the array element as a task group, in order to facilitate the search of the ready table, uC/OS-II defines a data type for int8u variable osrdygrp, each bit of the variable corresponds to a Task Group (an element of the array) of osrdytbl ). If a Task Group has a task ready, set the corresponding position of the task group to 1 in the variable osrdygrp; otherwise, set it to 0. For example, if osrdygrp = 0x00000011, it indicates that osrdytbl [0] And osrdytbl [1] has a ready task in the task group.
Because the variable osrdygrp is 8 bits, the osrdytbl [] array element also has 8 bits, so the uC/OS-II can manage 8x8 = 64 tasks. The following is a task readiness table:
How to locate a task in the ready table based on the task priority level. UC/OS is set in this way, because the priority is a single-byte number, and its maximum value does not exceed 63, that is, 00111111 of the binary format, therefore, we can regard the priority level as a 6-bit binary number. In this way, the specific data bit of the variable osrdygrp can be specified with a 3-bit height, and the table below is used to determine the elements of the ready table array, that is, Y. Use the lower 3 bits to specify the specific data bit of the array element, that is, X. Therefore, the exact position of the task in the ready table can be determined based on the priority of the task. In addition, the uC/OS-II creates a job-ready table at initialization and sets all data bits to 0.
There are two operations for the ready table: one is to register the ready tasks in the ready table, and the other is to delete the tasks from the ready table.
1. register the readiness task in the readiness table
With the following two lines of code, you can set the task with priority of PRIO to the ready state.
Osrdygrp | = osmaptbl [PRIO> 3];
Osrdytbl [PRIO> 3] | = osmaptbl [PRIO & 0x07];
This is the code written based on the above analysis.
Here, osmaptblp [] is an array defined by uC/OS-II to speed up the operation, the array is as follows:
Int8u const osmaptbl [] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
2. delete a task from the ready table
The priority is Prio, and the code is as follows:
If (osrdytbl [PRIO> 3] & = ~ Osmaptbl [PRIO & 0x07]) = 0)
Osrdygrp & = ~ Osmaptbl [PRIO> 3];
If each element in the osrdytbl [] array is 0, the binary bits in the corresponding osrdygrp must be cleared.
3. obtain the highest priority ready tasks from the ready table
The operation code is as follows:
Y = osunmaptbl [osrdygrp];
X = osunmaptbl [osrdytbl [y];
Prio = (Y <3) + X;
There is also a code:
Y = osunmaptbl [osrdygrp];
Prio = (int8u) (Y <3) + osunmaptbl [osrdytbl [y]);
With the above code, we can find out the priority level of the highest priority ready task, in which osunmaptbl [] and osmaptblp [] are similar, is the uC/OS-II to speed up the calculation of an array, there are a total of 256 elements. The array is as follows:
Int8u const osunmaptbl [] = {
0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x00 to 0x0f */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x10 to 0x1f */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x20 to 0x2f */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x30 to 0x3f */
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x40 to 0x4f */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x50 to 0x5f */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x60 to 0x6f */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x70 to 0x7f */
7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x80 to 0x8f */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x90 to 0x9f */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/* 0xa0 to 0xaf */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/* 0xb0 to 0xbf */
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/* 0xc0 to 0xcf */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/* 0xd0 to 0xdf */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/* 0xe0 to 0xef */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0/* 0xf0 to 0xff */
};
The above array is very interesting. At the beginning, I was curious about how this came about. I read the book and thought about it carefully. I had to sigh the brilliant person who wrote the source code.
As shown in the code above, when using the array osunmaptbl [], it is based on osrdygrp. Therefore, this array has a total of 256 elements. That is to say, no matter what the osrdygrp value is, the corresponding element value can always be found in the array osunmaptbl [], and this element value is Y with the highest priority of the ready task. Because the values of each element in the array osunmaptbl [] are set based on the following idea: the variable osrdygrp of the Task Group is an 8-bit binary number, which is searched from the second bit to the high bit, the ready task group corresponding to the first digit of 1 must be the group of the highest priority ready task, therefore, its group number must be the highest priority level for ready tasks (6 digits. For example, if the first BIT in osrdygrp is 3rd bits, the top 3 bits at the highest priority level must be, therefore, in the 256 element values of the array osunmaptbl [], all the element values with the 3rd bits as 1 are defined as 3.
Therefore, with such an array, you can obtain the Y value of the ready task in the array osunmaptbl [] as long as the variable osrdygrp is used as the subscript when you look for the most advanced ready task. Otherwise, it is necessary to write a loop program to search in the ready table, which is not only time-consuming, but also a taboo of real-time systems-unpredictable computing time.
Of course, this array is also used to find the X value of the highest ready task. Of course, it is found in the table osrdytbl [Y. This is similar to finding Y coordinates. For example, if osrdygrp is 0x28 (00101000), the highest priority group is osrdytbl [3], while osrdytbl [3] Has 01100000 elements, the first bit with 1 is the ready task with the highest priority we are looking. If the value of 5 is 1, the X coordinate is 5, that is, the low 3 bits of the highest task priority must be 5. Therefore, in the 256 elements of the array osunmaptbl [], all the element values whose subscript is 5 and its bit is 1 are defined as 5.
UC/OS-II often uses a table similar to a ready table to record a certain state of a task. Isn't this an algorithm?