Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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:

prio

is the task priority,

ptos

is a pointer to the top of stack once the stack frame has been built by OSTaskStkInit() (will be described in Chapter 13, Porting µC/OS-II) and is stored in the .OSTCBStkPtr field of the OS_TCB.

pbos

is a pointer to the stack bottom and is stored in the .OSTCBStkBottom field of the OS_TCB.

id

is the task identifier and is saved in the .OSTCBId field.

stk_size

is the total size of the stack and is saved in the .OSTCBStkSize field of the OS_TCB.

pext

is the value to place in the .OSTCBExtPtr field of the OS_TCB.

opt

is the OS_TCB options and is saved in the .OSTCBOpt field.

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

...