...
An OS_TCB
is initialized by the function OS_TCBInit()
(see Listing 3.6) when a task is created. OS_TCBInit()
is called by either OSTaskCreate()
or OSTaskCreateExt()
(see Chapter 4, Task Management). OS_TCBInit()
receives seven arguments:
| is the task priority, |
| is a pointer to the top of stack once the stack frame has been built by |
| is a pointer to the stack bottom and is stored in the .OSTCBStkBottom field of the |
| is the task identifier and is saved in the |
| is the total size of the stack and is saved in the |
| is the value to place in the |
| is the |
Ready List
Each task is assigned a unique priority level between 0 and OS_LOWEST_PRIO
, inclusive (see OS_CFG.H
). Task priority OS_LOWEST_PRIO
is always assigned to the idle task when µC/OS-II is initialized. Note that OS_MAX_TASKS
and OS_LOWEST_PRIO
are unrelated. You can have only 10 tasks in an application while still having 32 priority levels (if you set OS_LOWEST_PRIO
to 31).
...
The code in Listing 3.7 is used to place a task in the ready list. prio is the task’s priority.
As you can see from Figure 3.4, the lower three bits of the task’s priority are used to determine the bit position in OSRdyTbl[]
, and the next three most significant bits are used to determine the index into OSRdyTbl[]
. Note that OSMapTbl[]
(see OS_CORE.C
) is in ROM and is used to equate an index from 0 to 7 to a bit mask, as shown in Table 3.1.
Table 3.1 Contents of OSMapTbl[]
.
Index | Bit Mask (Binary) |
---|---|
0 | 00000001 |
1 | 00000010 |
2 | 00000100 |
3 | 00001000 |
4 | 00010000 |
5 | 00100000 |
6 | 01000000 |
7 | 10000000 |
A task is removed from the ready list by reversing the process using the code in Listing 3.8.
This code clears the ready bit of the task in OSRdyTbl[]
and clears the bit in OSRdyGrp
only if all tasks in a group are not ready to run; that is, all bits in OSRdyTbl[prio >> 3]
are 0. Another table lookup is performed, rather than scanning through the table starting with OSRdyTbl[0]
, to find the highest priority task ready to run. OSUnMapTbl[256]
is a priority resolution table (see OS_CORE.C
). Eight bits represent when tasks are ready in a group. The least significant bit has the highest priority. Using this byte to index OSUnMapTbl[]
returns the bit position of the highest priority bit set — a number between 0 and 7. Determining the priority of the highest priority task ready to run is accomplished with the code in Listing 3.9.
For example, as shown in Figure 3.5, if OSRdyGrp
contains 01101000 (binary) or 0x68, then the table lookup OSUnMapTbl[OSRdyGrp]
yields a value of 3, which corresponds to bit 3 in OSRdyGrp
. Note that bit positions are assumed to start on the right with bit 0 being the rightmost bit. Similarly, if OSRdyTbl[3]
contains 11100100 (binary) or 0xE4, then OSUnMapTbl[OSRdyTbl[3]]
results in a value of 2 (bit 2). The task priority (prio) is then 26 (i.e. 3 x 8 + 2). Getting a pointer to the OS_TCB
for the corresponding task is done by indexing into OSTCBPrioTbl[]
using the task’s priority.
Task Scheduling
µC/OS-II always executes the highest priority task ready to run. The determination of which task has the highest priority, and thus which task will be next to run, is determined by the scheduler. Task-level scheduling is performed by OS_Sched()
. ISR-level scheduling is handled by another function [OSIntExit()
] described later. The code for OS_Sched()
is shown in Listing 3.10. µC/OS-II task-scheduling time is constant irrespective of the number of tasks created in an application.
...
The code for OSStatInit()
is shown in Listing 3.16.
The code for OS_TaskStat()
is shown in Listing 3.17.
Interrupts under µC/OS-II
...