Professional Documents
Culture Documents
Kernel Structure
1
Objectives
• To understand what a task is.
• To learn how μC/OS-II manages tasks.
• To know how an interrupt service routine (ISR)
works.
• To learn how to determine the percentage of
CPU that your application is using.
2
The μC/OS-II File Structure
4
Critical Sections
• A critical section is a portion of code that is not safe
from race conditions because of the use of shared
resources.
• They can be protected by interrupt
disabling/enabling interrupts or semaphores.
– The use of semaphores often imposes a more
significant amount of overheads.
– An OS often use interrupts disabling/ enabling to
protect critical sections.
• Once interrupts are disabled, neither context
switches nor any other ISR’s can occur.
5
Critical Sections
• Interrupt latency is vital to an OS!
– Interrupts should be disabled as short as
possible to improve the responsiveness.
– It must be accounted as a blocking time in the
schedulability analysis.
• Interrupt disabling must be used carefully:
– e.g., if OSTimeDly() is called with interrupt
disabled, the machine might hang!
OS_ENTER_CRITICAL();
/* Critical Section */
OS_EXIT_CRITICAL(); 6
Critical Sections
• The states of the processor must be carefully maintained
across multiple calls of OS_ENTER_CRITICAL() and
OS_EXIT_CRITICAL().
7
Critical Sections
• OS_CRITICAL_METHOD=1
– Interrupt enabling/disabling instructions.
– The simplest way! However, this approach does
not have the sense of “save” and “restore”.
– Interrupt statuses might not be consistent across
kernel services/function calls!!
{ {
. .
disable_interrupt(); disable_interrupt();
a_kernel_service(); critical section
. enable_interrupt();
. .
}
} Interrupts are now
implicitly re-enabled!
8
OS_CRITICAL_METHOD=1
ver 1.1
void F1() { void F2() {
/*…*/ /*…*/
disable_interrupt(); disable_interrupt();
/*…*/ /*…*/
F2(); enable_interrupt();
disable_interrupt(); /*…*/
/*…*/ }
enable_interrupt();
/*…*/
}
9
OS_CRITICAL_METHOD=1
ver 1.2
int counter; void F2() {
void F1() { /*…*/
/*…*/ disable_interrupt();
disable_interrupt(); counter++;
counter++; /*…*/
/*…*/ counter--;
F2(); if (counter == 0)
/*…*/ enable_interrupt();
counter--; /*…*/
if (counter == 0) }
enable_interrupt();
/*…*/
}
10
Critical Sections
• OS_CRITICAL_METHOD=2
• Processor Status Word (PSW) can be
saved/restored onto/from stacks.
– PSW’s of nested interrupt enable/disable
operations can be exactly recorded in stacks.
#define OS_ENTER_CRITICAL() \
asm(“PUSH PSW”) \
asm(“DI”) Some compilers might not be
smart enough to adjust the
stack pointer after the
#define OS_EXIT_CRITICAL() \ processing of in-line
asm(“POP PSW”) assembly.
11
Critical Sections
• OS_CRITICAL_METHOD=3
• The compiler and processor allow the PSW to
be saved/restored to/from a memory variable.
void foo(arguments)
{
OS_CPU_SR cpu_sr;
OS_ENTER_CRITICAL()
.
cpu_sr = get_processor_psw();
disable_interrupts();
.
/* critical section */
.
set_processor_psw(cpu_sr);
. OS_EXIT_CRITICAL()
}
12
Example: PC_DOSSaveReturn()
13
Tasks
• A task is an active entity which could do some
computations.
• Under real-time μC/OS-II systems, a task is
typically an infinite loop.
void YourTask (void *pdata) (1)
{
for (;;) { (2)
/* USER CODE */
Call one of μC/OS-II ’s services:
OSMboxPend();
OSQPend();
OSSemPend();
OSTaskDel(OS_PRIO_SELF);
Delay itself for the next
OSTaskSuspend(OS_PRIO_SELF); event/period, so that
OSTimeDly();
OSTimeDlyHMSM();
other tasks can run.
/* USER CODE */
}
} 14
Tasks
• μC/OS-II can have up to 64 priorities.
– Each task must be associated with an unique priority.
– 63 and 62 are reserved (idle, stat).
15
Tasks
• A task is created by OSTaskCreate() or
OSTaskCreateExt().
17
Task States
WAITING
OSMBoxPost() OSMBoxPend()
OSQPost() OSQPend()
OSQPostFront()
OSTaskDel() OSSemPost() OSSemPend()
OSTaskResume() OSTaskSuspend()
OSTimeDlyResume() OSTimeDly()
OSTimeTick() OSTimeDlyHMSM()
OSTaskCreate()
OSTaskCreateExt() OSStart()
OSIntExit() Interrupt
OS_TASK_SW()
DORMANT READY RUNNING ISR
OSIntExit()
OSTaskDel()
Task is Preempted
OSTaskDel()
OSintExit()
18
Task States
• A task can delay itself by calling OSTimeDly() or
OSTimeDlyHMSM().
– The task is placed in the waiting state.
– The task will be made ready by the execution of
OSTimeTick().
• It is the clock ISR! You don’t have to call it explicitly from your code.
19
Task States
• The running task could be preempted by an ISR unless
interrupts are disabled.
– ISR’s could make one or more tasks ready by signaling events.
– At the end of the outmost ISR execution, the scheduler will
check if rescheduling is needed.
20
Task Control Blocks (TCB)
21
Before starting to learn
the uC/OS’s TCB…
state CPU registers
Accounting memory
Open files
22
Process Control Block (PCB)
Information associated with each process/task
• Process state
• Program counter & general registers
• Scheduling information
• Memory-management information
• Accounting information
• I/O status information
• List of open files
• …
Definition:
Process control block
≈ Task control block
TCB’s free
uCOS_II.h list
.
.
.
.
.
.
24
25
Task Control Blocks (TCB)
26
Task Control Blocks (TCB)
27
Task Control Blocks (TCB)
Free Space
Space in use
28
Task Control Blocks (TCB)
29
Task Control Blocks (TCB)
30
Task Control Blocks (TCB)
31
Task Control Blocks (TCB)
32
Task Control Blocks (TCB)
33
Task Control Blocks (TCB)
34
Get a free TCB from
the free list
35
36
Ready List
• Ready list is a special bitmap to reflect which task is
currently in the ready state.
– Each task is identified by its unique priority in the bitmap.
• A primary design consideration of the ready list is
how to efficiently locate the highest-priority ready
task.
– The designer could trade some ROM space for an improved
performance.
• If a linear list is adopted, it takes O(n) to locate the
highest-priority ready task.
– It takes O(log n) if a heap is adopted.
– Under the design of ready list of μC/OS-II, it takes only O(1).
• Note that the space consumption is much more than other approaches,
and it also depends on the bus width.
37
OSRdyGrp Ready List
1 0 0 0 0 0 0 0 OSTCBPrioTbl[]
OSRdyTbl[] 0 [0]
0 [1]
0 [2]
0 0 0 0 0 0 0 0 0 [3]
0 [4]
0 0 0 0 0 0 0 0 0 [5]
0 [6]
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0
1 1 0 0 0 0 0 0 0
0
[OS_LOWEST_PRIO - 1]
[OS_LOWEST_PRIO]
OSTaskStat() OSTaskIdle()
OS_TCB OS_TCB
OSTCBStkPtr OSTCBStkPtr
OSTCBExtPtr = NULL OSTCBExtPtr = NULL
OSTCBStkBottom OSTCBStkBottom
OSTCBStkSize = stack size OSTCBStkSize = stack size
OSTCBId = OS_LOWEST_PRIO OSTCBId = OS_LOWEST_PRIO
OSTCBList OSTCBNext
OSTCBPrev
OSTCBNext
OSTCBPrev
OSTCBEventPtr = NULL OSTCBEventPtr = NULL
OSPrioCur = 0 OSTCBMsg = NULL OSTCBMsg = NULL
OSTCBDly = 0 OSTCBDly = 0
OSPrioHighRdy = 0 0 OSTCBStat = OS_STAT_RDY OSTCBStat = OS_STAT_RDY 0
OSTCBCur = NULL OSTCBPrio = OS_LOWEST_PRIO-1 OSTCBPrio = OS_LOWEST_PRIO
OSTCBHighRdy = NULL OSTCBX = 6 OSTCBX = 7
OSTCBY = 7 OSTCBY = 7
OSTime = 0L OSTCBBitX = 0x40 OSTCBBitX = 0x80
OSIntNesting = 0 OSTCBBitY = 0x80 OSTCBBitY = 0x80
OSTCBDelReq = FALSE OSTCBDelReq = FALSE
OSLockNesting = 0
OSCtxSwCtr = 0
OSTaskCtr = 2
OSRunning = FALSE
OSCPUUsage = 0
OSIdleCtrMax = 0L
OSIdleCtrRun = 0L
OSIdleCtr = 0L
Task Stack
OSStatRdy = FALSE Task Stack
38
OSRdyGrp
7 6 5 4 3 2 1 0 OSRdyTbl[OS_LOWEST_PRIO / 8 + 1]
Highest Priority Task
X
[0] 7 6 5 4 3 2 1 0
[1] 15 14 13 12 11 10 9 8
[2] 23 22 21 20 19 18 17 16
[3] 31 30 29 28 27 26 25 24
Y
[4] 39 38 37 36 35 34 33 32
[5] 47 46 45 44 43 42 41 40
[6] 55 54 53 52 51 50 49 48
[7] 63 62 61 60 59 58 57 56
Task Priority #
Task's Priority
Lowest Priority Task
(Idle Task)
0 0 Y Y Y X X X
39
OSMapTbl
Index Bit mask (Binary)
0 00000001
Bit 0 in OSRdyGrp is 1 when any bit in OSRdyTbl[0] is 1.
1 00000010 Bit 1 in OSRdyGrp is 1 when any bit in OSRdyTbl[1] is 1.
2 00000100 Bit 2 in OSRdyGrp is 1 when any bit in OSRdyTbl[2] is 1.
3 00001000 Bit 3 in OSRdyGrp is 1 when any bit in OSRdyTbl[3] is 1.
4 00010000 Bit 4 in OSRdyGrp is 1 when any bit in OSRdyTbl[4] is 1.
5 00100000
Bit 5 in OSRdyGrp is 1 when any bit in OSRdyTbl[5] is 1.
Bit 6 in OSRdyGrp is 1 when any bit in OSRdyTbl[6] is 1.
6 01000000
Bit 7 in OSRdyGrp is 1 when any bit in OSRdyTbl[7] is 1.
7 10000000
char x,y,mask;
1 1 1
1 1
1 1
44
Linux 2.6.18
linux/include/asm-generic/bitops/sched.h
45
ffs()
NAME
ffs - find first bit set in a word DESCRIPTION
The ffs() function returns the position
SYNOPSIS of the first (least significant) bit set in
#include <strings.h> the word i. The least significant bit is
position 1 and the most significant
position e.g. 32 or 64. The functions
int ffs(int i); ffsll() and ffsl() do the same but take
arguments of possibly different size.
#define _GNU_SOURCE
#include <string.h> RETURN VALUE
These functions return the position
int ffsl(long int i); of the first bit set, or 0 if no bits are set
in i.
int ffsll(long long int i);
46
Task Scheduling
• The scheduler always schedules the highest-priority
ready task to run.
• Task-level scheduling and ISR-level scheduling are
done by OS_Sched() and OSIntExit(), respectively.
– The difference is the saving/restoration of PSW (or
CPU flags).
• μC/OS-II scheduling time is a predictable amount of
time, i.e., a constant time.
– For example, the design of the ready list intends to
achieve this objective.
47
Task Scheduling
void OSSched (void)
{
INT8U y;
OS_ENTER_CRITICAL();
if ((OSLockNesting | OSIntNesting) == 0) { (1)
y = OSUnMapTbl[OSRdyGrp]; (2)
OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]); (2)
if (OSPrioHighRdy != OSPrioCur) { (3)
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; (4)
OSCtxSwCtr++; (5)
OS_TASK_SW(); (6)
}
}
OS_EXIT_CRITICAL();
}
50
Low Priority Task High Priority Task
OS_TCB OS_TCB
OSTCBCur OSTCBHighRdy
54
OSSchedLock()
55
OSSchedUnlock()
void OSSchedUnlock (void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
56
Idle Task
• The idle task is always
the lowest-priority void OS_TaskIdle (void *pdata)
task and can not be {
deleted or suspended #if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
by user-tasks. #endif
• To reduce power
dissipation, you can
pdata = pdata;
issue a HALT-like for (;;) {
instruction in the idle OS_ENTER_CRITICAL();
task. OSIdleCtr++;
– Suspend services in OS_EXIT_CRITICAL();
OSTaskIdleHook();
OSTaskIdleHook()!! }
}
57
Statistics Task
• It is created by μC/OS-II . It executes every second to
compute the percentage of the CPU usage.
– It is with the OS_LOWEST_PRIO – 1 priority.
• OSStatInit() must be called before the execution of
OS_TaskStat .
void main (void)
{
OSInit(); /* Initialize μC/OS-II (1)*/
/* Install μC/OS-II 's context switch vector */
/* Create your startup task (for sake of discussion, TaskStart()) (2)*/
OSStart(); /* Start multitasking (3)*/
}
void TaskStart (void *pdata)
{
/* Install and initialize µC/OS-II’s ticker (4)*/
OSStatInit(); /* Initialize statistics task (5)*/
/* Create your application task(s) */
for (;;) {
/* Code for TaskStart() goes here! */
}
}
58
Statistics Task
Highest Priority OS_LOWEST_PRIO - 1 OS_LOWEST_PRIO
main() TaskStart() OSTaskStat() OSTaskIdle()
{ { { {
OSInit(); (1)
Install context switch vector; (2)
Create TaskStart(); (3)
OSStart();
Scheduler
} Init uC/OS-II's ticker; (5)
(4) OSStatInit(): (6)
OSTimeDly(2); (7)
Scheduler while (OSStatRdy == FALSE) { (8)
OSTimeDly(2 seconds); (9)
2 ticks }
Scheduler for (;;) {
After 2 ticks OSIdleCtr++; (10)
(11) }
OSIdleCtr = 0; (12)
OSTimeDly(1 second); (13)
Scheduler for (;;) {
2 seconds OSIdleCtr++; (14)
1 second After 1 second }
59
OSStatInit
60
Statistics Task
(7) TaskStart: Delay for 2 ticks transfer CPU to the statistics
task to do some initialization.
(9) OS_TaskStat: Delay for 2 seconds Yield the CPU to the task
TaskStart and the idle task.
(13) TaskStart: Delay for 1 second Let the idle task count
OSIdleCtr for 1 second.
(15) TaskStart: When the timer expires in (13), OSIdleCtr contains
the value of OSIdleCtr can be reached in 1 second.
Notes:
– Since OSStatinit() assume that the idle task will count the OSOdleCtr at the full CPU
speed, you must not install an idle hook before calling OSStatInit()!!!
– After the statistics task is initialized, it is OK to install a CPU idle hook and perform
some power-conserving operations! Note that the idle task consumes the CPU
power just for the purpose of being idle.
61
Statistics Task
• With the invocation of OSStatInit(), we have known
how large the value of the idle counter can reach in 1
second (OSIdleCtrMax).
• The percentage of the CPU usage can be calculated
by the actual idle counter and the OSIdleCtrMax.
OSIdleCtr
OSCPUUsage(%) 100 1
OSIdleCtrM ax
This term is always 0
under an integer
operation
100 OSIdleCtr
OSCPUUsage(%) 100
OSIdleCtrMax
This term might overflow
100
OSIdleCtr
OSCPUUsage(%)
OSIdleCtrMax under fast processors!
(42,949,672)
100
62
Statistics Task
65
Interrupts under μC/OS-II
(8) Call OSIntExit(), which checks if we are in the inner-level of
nested interrupts. If not, the scheduler is called.
– A potential context-switch might occur.
– The Interrupt-nesting counter is decremented.
(9) On the return from this point, there might be several high-
priority tasks since μC/OS-II is a preemptive kernel.
(10) The CPU registers are restored from the stack, and the
control is returned to the interrupted task.
66
Time
Task Response
Interrupt Request (1)
µC/OS-IIor your application
has interrupts disabled.
(2)
Interrupt Recovery
TASK TASK
No New HPT or,
Vectoring OSLockNesting > 0 Return from interrupt
(3) (9)
Notify kernel:
OSIntEnter() or, Notify kernel: OSIntExit()
(7)
OSIntNesting++ User ISR code
(5)
(6)
Restore context
(11)
67
Interrupts under μC/OS-II
void OSIntExit (void)
{ If no scheduler locking and
OS_ENTER_CRITICAL(); no interrupt nesting
if ((--OSIntNesting | OSLockNesting) == 0) {
OSIntExitY = OSUnMapTbl[OSRdyGrp];
OSPrioHighRdy = (INT8U)((OSIntExitY << 3) +
OSUnMapTbl[OSRdyTbl[OSIntExitY]]); If there is another high-
if (OSPrioHighRdy != OSPrioCur) { priority task ready
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
OSCtxSwCtr++;
OSIntCtxSw();
} A context switch is
} executed.
OS_EXIT_CRITICAL();
} void OSIntEnter (void)
{
OS_ENTER_CRITICAL();
Note that OSIntCtxSw() is called, instead of OSIntNesting++;
OS_TASK_SW(), because the ISR already saves OS_EXIT_CRITICAL();
the CPU registers onto the stack. }
68
Clock Tick
• A time source is needed to keep track of time delays
and timeouts.
• You must enable ticker interrupts after multitasking
is started.
– In the TaskStart() task of the examples.
– Do not do this before OSStart().
• Clock ticks are serviced by calling OSTimeTick()
from a tick ISR.
• Clock tick ISR is always a port (of μC/OS-II ) of a CPU
since we have to access CPU registers in the tick ISR.
69
Clock Tick
void OSTickISR(void)
{
Save processor registers;
Call OSIntEnter() or increment OSIntNesting;
If(OSIntNesting == 1)
OSTCBCur->OSTCBStkPtr = SP;
Call OSTimeTick();
Clear interrupting device;
Re-enable interrupts (optional);
Call OSIntExit();
Restore processor registers;
Execute a return from interrupt instruction;
}
70
Clock Tick
void OSTimeTick (void)
{
OS_TCB *ptcb;
if (OSRunning == TRUE) {
ptcb = OSTCBList;
while (ptcb->OSTCBPrio != OS_IDLE_PRIO) {
OS_ENTER_CRITICAL();
Decrement delay-counter if needed
if (ptcb->OSTCBDly != 0) {
if (--ptcb->OSTCBDly == 0) {
if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) {
OSRdyGrp |= ptcb->OSTCBBitY;
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
} else {
ptcb->OSTCBDly = 1;
If the delay-counter reaches
}
zero, make the task ready. Or,
}
the task remains waiting.
}
ptcb = ptcb->OSTCBNext;
OS_EXIT_CRITICAL();
}
}
} 71
Clock Tick
• OSTimeTick() is a hardware-independent
routine to service the tick ISR.
72
μC/OS-II Initialization
OS_MAX_TASKS
OS_TCB OS_TCB OS_TCB OS_TCB
OSTCBStkPtr OSTCBStkPtr OSTCBStkPtr OSTCBStkPtr
OSTCBExtPtr OSTCBExtPtr OSTCBExtPtr OSTCBExtPtr
OSTCBStkBottom OSTCBStkBottom OSTCBStkBottom OSTCBStkBottom
OSTCBStkSize OSTCBStkSize OSTCBStkSize OSTCBStkSize
OSTCBId OSTCBId OSTCBId OSTCBId
OSTCBNext OSTCBNext OSTCBNext OSTCBNext
OSTCBFreeList OSTCBPrev OSTCBPrev OSTCBPrev OSTCBPrev 0
OSTCBEventPtr OSTCBEventPtr OSTCBEventPtr OSTCBEventPtr
OSTCBMsg OSTCBMsg OSTCBMsg OSTCBMsg
OSTCBDly OSTCBDly OSTCBDly OSTCBDly
OSTCBStat OSTCBStat OSTCBStat OSTCBStat
OSTCBPrio OSTCBPrio OSTCBPrio OSTCBPrio
OSTCBX OSTCBX OSTCBX OSTCBX
OSTCBY OSTCBY OSTCBY OSTCBY
OSTCBBitX OSTCBBitX OSTCBBitX OSTCBBitX
OSTCBBitY OSTCBBitY OSTCBBitY OSTCBBitY
OSTCBDelReq OSTCBDelReq OSTCBDelReq OSTCBDelReq
OS_MAX_EVENTS
OS_EVENT OS_EVENT OS_EVENT OS_EVENT
OSEventFreeList OSEventPtr
OSEventTbl[]
OSEventPtr
OSEventTbl[]
OSEventPtr
OSEventTbl[]
OSEventPtr
OSEventTbl[]
0
OSEventCnt OSEventCnt OSEventCnt OSEventCnt
OSEventType OSEventType OSEventType OSEventType
OSEventGrp OSEventGrp OSEventGrp OSEventGrp
OS_MAX_QS
OS_Q OS_Q OS_Q OS_Q
OSQPtr 0
OSQFreeList OSQStart
OSQPtr
OSQStart
OSQPtr
OSQStart
OSQPtr
OSQStart
OSQEnd OSQEnd OSQEnd OSQEnd
OSQIn OSQIn OSQIn OSQIn
OSQOut OSQOut OSQOut OSQOut
OSQSize OSQSize OSQSize OSQSize
OSQEntries OSQEntries OSQEntries OSQEntries
OS_MAX_MEM_PART
OS_MEM OS_MEM OS_MEM OS_MEM
73
OSRdyGrp Ready List
1 0 0 0 0 0 0 0 OSTCBPrioTbl[]
OSRdyTbl[] 0 [0]
0 [1]
0 [2]
0 0 0 0 0 0 0 0 0 [3]
0 [4]
0 0 0 0 0 0 0 0 0 [5]
0 [6]
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0
1 1 0 0 0 0 0 0 0
0
[OS_LOWEST_PRIO - 1]
[OS_LOWEST_PRIO]
OSTaskStat() OSTaskIdle()
OS_TCB OS_TCB
OSTCBStkPtr OSTCBStkPtr
OSTCBExtPtr = NULL OSTCBExtPtr = NULL
OSTCBStkBottom OSTCBStkBottom
OSTCBStkSize = stack size OSTCBStkSize = stack size
OSTCBId = OS_LOWEST_PRIO OSTCBId = OS_LOWEST_PRIO
OSTCBList OSTCBNext
OSTCBPrev
OSTCBNext
OSTCBPrev
OSTCBEventPtr = NULL OSTCBEventPtr = NULL
OSPrioCur = 0 OSTCBMsg = NULL OSTCBMsg = NULL
OSTCBDly = 0 OSTCBDly = 0
OSPrioHighRdy = 0 0 OSTCBStat = OS_STAT_RDY OSTCBStat = OS_STAT_RDY 0
OSTCBCur = NULL OSTCBPrio = OS_LOWEST_PRIO-1 OSTCBPrio = OS_LOWEST_PRIO
OSTCBHighRdy = NULL OSTCBX = 6 OSTCBX = 7
OSTCBY = 7 OSTCBY = 7
OSTime = 0L OSTCBBitX = 0x40 OSTCBBitX = 0x80
OSIntNesting = 0 OSTCBBitY = 0x80 OSTCBBitY = 0x80
OSTCBDelReq = FALSE OSTCBDelReq = FALSE
OSLockNesting = 0
OSCtxSwCtr = 0
OSTaskCtr = 2
OSRunning = FALSE
OSCPUUsage = 0
OSIdleCtrMax = 0L
OSIdleCtrRun = 0L
OSIdleCtr = 0L
Task Stack
OSStatRdy = FALSE Task Stack
74
Starting of μC/OS-II
• OSInit() initializes data structures for μC/OS-II
and creates OS_TaskIdle().
75
Starting of μC/OS-II
void main (void)
{
OSInit(); /* Initialize μC/OS-II */
.
Create at least 1 task using either OSTaskCreate() or OSTaskCreateExt();
.
OSStart(); /* Start multitasking! OSStart() will not return */
}
0
0
0
[OS_LOWEST_PRIO - 1]
[OS_LOWEST_PRIO]
OSTCBCur OSTCBStkPtr
OSTCBExtPtr = NULL
OSTCBStkPtr
OSTCBExtPtr = NULL
OSTCBStkPtr
OSTCBExtPtr = NULL
OSTCBHighRdy OSTCBStkBottom
OSTCBStkSize = stack size
OSTCBStkBottom
OSTCBStkSize = stack size
OSTCBStkBottom
OSTCBStkSize = stack size
OSTCBId = 6 OSTCBId = OS_LOWEST_PRIO OSTCBId = OS_LOWEST_PRIO
OSTCBList OSTCBNext
OSTCBPrev
OSTCBNext
OSTCBPrev
OSTCBNext
OSTCBPrev
OSTCBEventPtr = NULL OSTCBEventPtr = NULL OSTCBEventPtr = NULL
OSTCBMsg = NULL OSTCBMsg = NULL OSTCBMsg = NULL
OSTCBDly = 0 OSTCBDly = 0 OSTCBDly = 0
0 OSTCBStat = OS_STAT_RDY OSTCBStat = OS_STAT_RDY OSTCBStat = OS_STAT_RDY
0
OSTCBPrio = 6 OSTCBPrio = OS_LOWEST_PRIO-1 OSTCBPrio = OS_LOWEST_PRIO
OSTCBX = 6 OSTCBX = 6 OSTCBX = 7
OSTCBY = 0 OSTCBY = 7 OSTCBY = 7
OSTCBBitX = 0x40 OSTCBBitX = 0x40 OSTCBBitX = 0x80
OSTCBBitY = 0x01 OSTCBBitY = 0x80 OSTCBBitY = 0x80
OSTCBDelReq = FALSE OSTCBDelReq = FALSE OSTCBDelReq = FALSE
Task Stack
Task Stack
Task Stack 77
Summary
• The study of the μC/OS-II kernel structure, we learn
something:
– What a task is? How μC/OS-II manages a task and related
data structures.
– How the scheduler works, especially on detailed
operations done for context switching.
– The responsibility of the idle task and the statistics task!
How they works?
– How interrupts are serviced in μC/OS-II.
– The initialization and starting of μC/OS-II.
78