Professional Documents
Culture Documents
1
(Kernel mode) 0G~
2
Task (thread)
μC/OS-II
Device driver
Task (thread)
kernel
Task (thread)
Introduction
Task (thread)
Task (process)
Device driver
Task (process)
kernel
Linux Task (process)
Task (process)
User mode (0-3G) (Kernel mode) 3G-4G
Introduction
• μC/OS-II
– Micro-Controller Operating Systems, Version 2
– A very small real-time kernel.
• Memory footprint is about 20KB for a fully
functional kernel.
• Source code is about 5,500 lines, mostly in ANSI C.
• It’s source is open but not free for commercial
usages.
3
Introduction
• μC/OS-II
– Preemptible priority-driven real-time scheduling.
• 64 priority levels (max 64 tasks)
• 8 (/1/2) reserved for μC/OS-II
• Each task is an infinite loop.
– Deterministic execution times for most μC/OS-II
functions and services.
– Nested interrupts could go up to 256 levels.
4
Introduction
• μC/OS-II
– Supports of various 8-bit to 64-bit platforms: x86,
68x, MIPS, 8051, etc
– Easy for development: Borland C++ compiler and
DOS (optional).
• However, μC/OS-II still lacks of the following
features:
– Resource synchronization protocols.
– Sporadic task support.
– Soft-real-time support.
5
Introduction
• Getting started with μC/OS-II!
– See how a μC/OS-II program looks like.
– Learn how to write a skeleton program for
μC/OS-II.
• How to initialize μC/OS-II?
• How to create tasks?
• How to use inter-task communication
mechanisms?
• How to catch system events?
6
7
牡羊座本日運勢
心情指數
:
牡羊座
心 情 寫程式錢應該先好好沈澱一下,但不
: 容易如願。
愛 情 幫同學解釋一些 OS 上的盲點可能會
: 有意想不到的收穫。
財 運 有一筆錢入帳,讓手頭鬆了不少 ( 先
: 拿去買教科書 ?) 。
工 作 為人辛苦為人忙,看什麼都不順眼。
: 寫共筆前試著先到 sandbox 寫一些文
章出出氣。
8
Getting started with μC/OS-II
• Example 1: Multitasking
• Example 2: Stack Checking
• Example 3: Extension of μC/OS-II
• Example 4: Portability
9
Example 1: Multitasking
10
main
OSInit
OSSemCreate
OSTaskCreate DOS
OSStart
TaskStart
Multiprogramming
install tick ISR
longmp
11
Example 1: Multitasking
• 13 tasks run concurrently.
– 2 internal tasks:
The idle task and the statistic task.
– 11 user tasks:
Randomly print numbers onto the screen.
12
Example 1: Multitasking
• Files
– The main program (test.c)
– The big include file (includes.h)
– The configuration of μC/OS-II (os_cfg.h) for each
application
• Tools needed:
– Borland C++ compiler (V3.1+)
13
The μC/OS-II File Structure
CPU Timer
14
includes.h
15
OS_CFG.H
.
.
.
.
16
test.c
A semaphore Stacks
(explain later) (explain later)
17
test.c: main()
18
main
OSInit
OSSemCreate
OSTaskCreate DOS
OSStart
TaskStart
Multiprogramming
install tick ISR
longmp
19
OSInit()
• Internal structures of μC/OS-II.
– Task ready list.
– Priority table.
• a mapping table.
• give a priority/pid; return @TCB)
– Task control blocks (TCB).
– Free pools.
• Create housekeeping tasks.
– The idle task.
– The statistic task.
20
OSinit()
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
OSTCBStkSiz e = 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
OSPrioHighRdy = 0 0 OSTCBDly = 0
OSTCBStat = OS_STAT_RDY
OSTCBDly = 0
OSTCBStat = OS_STAT_RDY 0
OSTCBCur = NULL OSTCBPrio = OS_LOWEST_PRIO-1
OSTCBX = 6
OSTCBPrio = OS_LOWEST_PRIO
OSTCBX = 7
OSTCBHighRdy = NULL OSTCBY = 7 OSTCBY = 7
OSTime = 0L OSTCBBitX = 0x40
OSTCBBitY = 0x80
OSTCBBitX = 0x80
OSTCBBitY = 0x80
OSIntNesting = 0 OSTCBDelReq = FALSE OSTCBDelReq = FALSE
OSLockNesting = 0
OSCtxSwCtr = 0
OSTaskCtr = 2
OSRunning = FALSE
OSCPUUsage = 0
OSIdleCtrMax = 0L
OSIdleCtrRun = 0L
OSIdleCtr = 0L Task Stack 21
OSStatRdy = FALSE Task Stack
OSinit()
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
OSQFreeList OSQStart
OSQPtr
OSQStart
OSQPtr
OSQStart
OSQPtr
OSQStart
0
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
22
The PC IVT
• Interrupt vector table (IVT)
Before (DOS only) After (μC/OS-II installed)
23
PC_DOSSaveReturn()
• Save the current status of DOS for the future
restoration.
– Interrupt vectors and the RTC tick rate.
• Set a global returning point by calling setjmp().
– μC/OS-II can come back here when it
terminates.
– PC_DOSReturn()
24
PC_DOSSaveReturn()
25
setjmp
27
PC_VectSet()
• PC_VectSet(uCOS, OSCtxSw)
– Install the context switch handler (OSCtxSw).
– Interrupt 0x80 (uCOS) under 80x86 family.
• Invoked by INT instruction.
Disable interrupt
Enable interrupt
28
OSSemCreate()
• Create a semaphore for resource synchronization.
– To protect non-reentrant codes.
29
OSTaskCreate()
• Functionality
– Create tasks with the given arguments.
– Tasks become “ready” after they are created.
• Task
– An active entity which could do some computations.
– Priority, CPU registers, stack, text, housekeeping status.
• The μC/OS-II picks up the highest-priority task to run
on context-switching.
– Tightly coupled with ISR.
30
OSTaskCreate()
Entry point of the task (a
pointer to function)
• OSTaskCreate(
User-specified
TaskStart, data
(void *)0,
&TaskStartStk[TASK_STK_SIZE - 1],
0 Top of Stack
Priority
); (0=hightest)
31
OSStart()
• OSStart()
– Start multitasking of μC/OS-II .
– It never returns to main().
– μC/OS-II is terminated if PC_DOSReturn() is
called.
32
main
OSInit
OSSemCreate
OSTaskCreate DOS
OSStart
TaskStart
Multiprogramming
install tick ISR
longmp
33
OSTaskCreate(
TaskStart,
(void *)0,
for (i=0 to 9) {
OSTaskCeate
}
35
TaskStartCreateTasks()
36
Task()
Semaphore
operations.
37
main
OSInit
OSSemCreate
OSTaskCreate DOS
OSStart
TaskStart
Multiprogramming
install tick ISR
longmp
38
Semaphores
• A semaphore consists of a wait list and an integer
counter.
– OSSemPend():
• Counter--
• If the value of the semaphore < 0, then the task is blocked and
moved to the wait list immediately.
• A time-out value can be specified.
– OSSemPost():
• Counter++
• If the value of the semaphore ≧ 0, then a task in the wait list is
removed from the wait list.
• Reschedule if needed.
39
Example 1: Multitasking
• Summary:
– μC/OS-II is initialized and started by calling OSInit()
and OSStart(), respectively.
– Before μC/OS-II is started,
• The DOS status is saved by calling PC_DOSSaveReturn().
• A context switch handler is installed by calling PC_VectSet().
• One user task must be created first!
– Shared resources can be protected by semaphores.
• OSSemPend(), OSSemPost().
40
Example 2
41
main
OSInit
OSTaskStkInit_FPE_X86 DOS
& OSTaskCreateExt
OSStart
TaskStart
Multiprogramming
install tick ISR
OSMboxPost
Update the display OSTaskStkChk &OSMobxPend OSMboxPost
42
Example 2: Stack Checking
45
OSTaskStkInit_FPE_x86()
同學:加油, size
快下課了!
pbos
46
OSCreateTaskExt()
• OSTaskCreatExt(
TaskStart,
(void *)0,
ptos,
TASK_START_PRIO,
TASK_START_ID,
pbos,
size, User supplied data which can be used to extend TCB
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR
); options
47
TaskStart()
Create 2
mailboxes
48
Task1()
49
Task2 and Task3
50
Task4 and Task5
???
OSTimeDlyHMSM(0, 0, 1, 0);
51
MailBox
• A mailbox is for data exchanging between tasks.
– A mailbox consists of a data pointer and a wait-list.
• OSMboxPend():
– The message in the mailbox is retrieved.
– If the mailbox is empty, the task is immediately blocked and moved to the
wait-list.
– A time-out value can be specified.
• OSMboxPost():
– A message is posted in the mailbox.
– If there is already a message in the mailbox, then an error is returned (not
overwritten).
– If tasks are waiting for a message from the mailbox, then the task with the
highest priority is removed from the wait-list and scheduled to run.
52
OSTaskStkCheck()
• Check for stack overflow.
– bos < (tos – stack length)
– Local variables, arguments for procedure calls, temporary
storage for ISR’s.
– μC/OS-II can check for stack overflow on the creation of
tasks and when OSTaskStkCheck() is called.
– μC/OS-II does not automatically check stacks.
53
(Linux 2.6)
stack
User mode
Kernel mode
(kernel service routines)
stack stack
54
(Linux 2.4)
stack
User mode
Kernel mode
(kernel service routines)
stack stack
Kernel mode
(interrupt service routines)
55
μC/OS-II
Kernel mode
Kernel mode
(kernel service routines)
stack
Kernel mode
(interrupt service routines)
56
Example2: Stack Checking
• Summary:
– Local variable, function calls, and ISR’s will utilize
the stack space of user tasks.
– ISR will use the stack of the interrupted task.
– If floating-point operations are needed, then some
stack space should be reserved.
– Mailboxes can be used to synchronize the work of
tasks.
57
Example 3: Extension of μC/OS-II
58
Example 3
59
User-defined
data structure
to pass to tasks
60
61
.
.
.
62
63
Task 2, 3, 4 are
functionally
identical.
64
Message Queues
• A message queue consists of an array of elements and a wait-
list.
• Different from a mailbox, a message queue can hold many
data elements (in a FIFO basis).
• As same as mailboxes, there can be multiple tasks pend/post
to a message queue.
• OSQPost(): a message is appended to the queue. The highest-
priority task (in the wait-list) receives the message and is
scheduled to run, if any.
• OSQPend(): a message is removed from the array of elements.
If no message can be retrieved, the task is moved to the wait-
list and becomes blocked.
65
Hooks
• A hook function will be called by μC/OS-II when the
corresponding event occurs.
– Event handlers could be in user programs.
– For example, OSTaskSwHook () is called every time when
context switch occurs.
• The hooks are specified in the compiling time in μC/OS-
II :
– μC/OS-II is an embedded OS.
• OS_CFG.H (OS_CPU_HOOKS_EN = 0)
– Many OS’s can register and un-register hooks.
66
User Customizable Hooks for μC/OS-II
67
OSTaskStatHook()
68
OSTaskSwHook()
69
Example 3: Extension of μC/OS-II
• Summary:
– Message queues can be used to synchronize among tasks.
• Multiple messages can be held in a queue.
• Multiple tasks can “pend”/“post” to message queues
simultaneously.
– Hooks can be used to do some user-specific computations
on certain OS events occurs.
• They are specified in the compiling time.
• A Pointer to from the TCB of each task to a user-provided data
structure
70
Getting Started with μC/OS-II?
Getting Started with μC/OS-II :
– How the control flows among procedures?
– How tasks are created?
– How tasks are synchronized by semaphore,
mailbox, and message queues?
– How the space of a stack is utilized?
– How to capture system events?
– How to write a dummy μC/OS-II program?
71