RTOS Slides UCOS II
RTOS Slides UCOS II
1
Course flow
2
Session 1
• Startup code
• Is OS needed?
3
Motherboard block Diagram
4
© Copyright 2004, All Rights Reserved. OASIS Technologies
Runtime Memory Map
High Memory
stack End of RAM
heap
initialized data
Start of RAM
uninitialized data
End of ROM
text and RO
Low Memory
start of ROM
5
Application startup
6
CPU Vs Memory
Technology
7
OS : What is it Anyway?
• A program that acts as an intermediary
between a user of a computer and the
computer hardware.
• Operating system goals:
– Execute user programs and make
solving user problems easier.
– Make the computer system convenient
to use.
– Use the computer hardware in an
efficient manner.
8
© Copyright 2004, All Rights Reserved. OASIS Technologies
OS : Components
• Process Management
• Memory Management
• Secondary Storage Management
• I/O System
• File Management
• Protection System
• Networking
• Command Interpreter System
9
© Copyright 2004, All Rights Reserved. OASIS Technologies
OS Architecture
10
What OS provides?
• Kernel with Hardware • Hardware Abstraction
Abstraction Layer + I/O
Management – Application developers
need not know about
the underlying
hardware
• Application can
• Inter Process Communication communicate with each
other with ease
11
What is a Process
• Also called a Task
12
© Copyright 2004, All Rights Reserved. OASIS Technologies
Process Address Space
(Process Image)
0xFFFFFFFF
Stack
(dynamically allocated)
SP
Virtual Heap
address space (dynamically allocated)
static data
Code PC
0x00000000 (text)
13
© Copyright 2004, All Rights Reserved. OASIS Technologies
Process Context
• A process consists of :
– an address space – usually protected and
virtual – mapped into memory
– the code for the running program
– the data for the running program
– an execution stack and stack pointer (SP)
– the program counter (PC)
– a set of processor registers – general purpose
and status
– a set of system resources
14
© Copyright 2004, All Rights Reserved. OASIS Technologies
Process State Diagram
15
© Copyright 2004, All Rights Reserved. OASIS Technologies
Process State Diagram
16
END OF SESSION 1
(Thank God!!!)
17
Session 2
18
Embedded Systems
• An embedded system is a special-purpose system
in which the computer is completely encapsulated
by the device it controls.
• Some characteristics include :
– Customized hardware
– Customized software
– Predefined Tasks with specific requirements
– Small footprint
19
Embedded system examples
• Virtually all systems that have a digital interface --
watches, microwaves, VCRs, cars -- utilize
embedded systems.
• Artificial Satellites, Space Vehicles( Voyager, Mars
Polar Lander etc.)
• Automobiles, Telecommunication
20
Real Time System
“ A real-time system is one in which the correctness
of the computations not only depends on their
logical correctness, but also on the time at which
the result is produced ”
●
In other words, a late answer is a wrong answer.
Characteristics of a Embedded Real Time system:
●
Deadline driven
●
Process the events in a deterministic time.
●
Have limited resources.
21
Hard or Soft?
22
• Car engine control, ABS, car airbags, heart
pacemakers, Industrial control, nuclear power
stations.
23
How to process the events in embedded real
time system?
– Simplest approach: cyclic program
• loop
• do part of task 1
• do part of task 2
• do part of task 3
• end loop
24
Cyclic Programming of Real Time systems
25
Cyclic Programming of Real Time systems
System
initialization
Get Temperature()
Check if exceeds Threshold
If Yes turn ON Valve 1
Update Display
26
A Look at Cyclic Program
• Advantages
– Simple implementation
– Low overhead
– Very predictable
• Disadvantages
– Can’t handle sporadic events
– Everything must operate in lockstep
– Code must be scheduled manually
27
How to overcome limitations of cyclic loops ?
●
Using a mechanism through which critical
events can be processed by pre-empting the less
critical currently executing task.
●
Achieved by implementing in
software/firmware an algorithm which will
behave in the same way a hardware
interrupts and IRS
●
By wisely and judiciously utilising the CPU
utilization
●
By implementing a software/firmware that
controls the CPU allocation to various tasks
in the system
●
Both the above implementation will lead us to
the implementation of a software/firmware layer
which we can call as OS
28
OS in Embedded System:
29
What is an RTOS ?
Helps us in processing Real Time events
HOW
●
Providing Deterministic execution time of the
code...
●
Provides worst case guarantee for interrupts,
context switch & system call.
●
Performing Efficient Multitasking…
●
Ensures that events are timely processed.
●
Efficient use of resources.
●
Real Time applications can be designed and
scaled easily...
●
Simplifies the design process by splitting
application code in to separate tasks.
●
Functionality can be easily added without
significant changes to the application.
30
Multi-Tasking
• The ability to execute more than one task at the same time is
Multi Tasking.
31
Design constraints for an Embedded RTOS
●
Time Constraint
●
Small Footprint
●
Low Interrupt Latency
●
Robust
●
Efficient usage of Resource
32
Embedded RT System requirements
• Deadline driven:
– Hard real time systems:
• Failure to meet the deadline is considered to be a fatal
fault.
33
END OF SESSION 2
34
SESSION 3
• RTOS architecture
• RTOS terminologies
• Introduction to ucosII OS
35
Real Time OS Architecture
APPLICATION
Kernel
IPC ISR
HAL Scheduler
Hardware
36
Building Blocks of a Real Time OS
• Kernel
– Task Management
– Scheduling
– Context switching
– IPC mechanism
– Timer Handling
• Memory Management
• Device driver
• Protocol stack
37
Kernel Structure
Types of Kernel
– monolithic kernel that contains all services
– micro-kernel -- contain the minimal services to support
optional and cooperating processes
• small (10K bytes) and modular
• configurable
Services provided by kernel
– task management
– inter-task communication -- message queue, mailbox, and
shared memory
– synchronization & mutual exclusion -- semaphore and
signal
– interrupt support and error handling
– memory management
– time management and timer services
– multiprocessor support
38
Micro-kernel
MINIX 3, L4, QNX
Net Application
H
HW Kernel
A
L
39
Monolithic Kernel
Linux, Windows
Net
H
HW Proc
A Device Application
L Driver
Memory
Mgmt. File
System
40
Scheduler
Role?
• It is the part of the kernel responsible for determining
which task runs next.
What? An Algorithm
• The basis for the selection of the new task which will run is
based on the scheduling policy/algorithm.
When?
• Scheduling decisions are made at the task level and at the
interrupt level.
41
Round Robin Scheduling
42
Priority Base Preemptive Scheduling
43
Context switch
• Role: switch out one task and make the newly selected task
by the scheduler to run on the CPU
44
What are Threads?
45
What are Tasks?
– Code + data
• Functions/Subroutines
46
Important aspects of Threads
47
IPC mechanisms
• Pipes
• Shared memory
• semaphores
• Mailbox
• Message queues
48
RTOS Terminologies
• Re-entrant
• Critical section
• Atomicity
• Deadlock
49
Review RTOS
• Advantages:
• Better CPU utilization
• Better handling of time-critical code.
• Easier functionality expansion & hence shorter time-to-
market.
• Disadvantage:
• Purchase Cost – huge, license fees, royalty
• Size – ROM & RAM requirements, both
• Maintenance cost
50
Introduction to uC/OSII OS
• Features:
51
Sample Application code
int main() void t2(void)
{ {
while(1)
} {
print();
void t1(void)
{ wait();
while(1) …….
{ }
waitfordata(); }
getData();
….. int getData(void)
} {
}
void print(char *data_t)
{
}
}
52
A Simple Task Model
#define NO_TASKS 3
#define TASK_STK_SIZE 100
unsigned int TaskStk[NO_TASK][TASK_STK_SIZE]
void init_timer();
int main(void)
{
OSInit();
init_timer();
TaskCreate(task1, (void *) 0, “Task1”, 0);
TaskCreate(task2, (void *) 0, “Task2”, 1);
OSStart();
}
void task1(void *data) void task2(void *data)
{ {
while(1) while(1)
{ {
block…… block……
…… ……
} }
} } 53
A Simple Task Model
#define NO_TASKS 3
#define TASK_STK_SIZE 100
unsigned int TaskStk[NO_TASK][TASK_STK_SIZE]
void init_timer();
int main(void)
{
OSInit(); Task Priorities
init_timer();
TaskCreate(task1, (void *) 0, “Task1”, 0);
TaskCreate(task2, (void *) 0, “Task2”, 1);
OSStart();
}
void task2(void *data)
void task1(void *data)
{
{
while(1) while(1)
{ {
block…… block……
…… ……
} }
}
} 54
A Simple Task Model
#define NO_TASKS 3
#define TASK_STK_SIZE 100
unsigned int TaskStk[NO_TASK][TASK_STK_SIZE]
void init_timer();
int main(void)
{
OSInit();
init_timer(); After OSStart you
TaskCreate(task1, (void *) 0, “Task1”, 0); will not come here
TaskCreate(task2, (void *) 0, “Task2”, 1); but will go to highest
OSStart(); priority task code in
} this case task1
#define NO_TASKS 3
#define TASK_STK_SIZE 100
unsigned int TaskStk[NO_TASK][TASK_STK_SIZE]
void init_timer();
int main(void)
{
OSInit();
init_timer();
TaskCreate(task1, (void *) 0, “Task1”, 0);
TaskCreate(task2, (void *) 0, “Task2”, 1);
OSStart();
}
void task1(void *data) void task2(void *data)
{ {
while(1) while(1)
{ {
block…… block……
…… ……
} }
} } 60
Understanding ‘task create’ system call 1/4
#define NO_TASKS 3
#define TASK_STK_SIZE 100
unsigned int TaskStk[NO_TASK][TASK_STK_SIZE]
void init_timer();
int main(void)
{
OSInit();
init_timer();
TaskCreate(task1, (void *) 0, “Task1”, 0);
TaskCreate(task2, (void *) 0, “Task2”, 1);
OSStart();
}
readyQ 0 0 1 0 0 1 0 0 1 0 0
waitQ 1 0 0 1 1 0 1 1 0 1 1
66
Kernel data structure
readyQ 0 0 1 0 0 1 0 0 1 0 0
waitQ 1 0 0 1 1 0 1 1 0 1 1
67
PC PC
PC TaskCreate(): CPSR
CPSR CPSR
LR OSInit(): LR • Fill the TaskStk[taskprio] LR
R12 R12
R12 • Initialize kernel data R11
with the stack frame R11
R11 R10
R10 structures R10 • Initializes the R9
R9 R9
R8 • Create an Ideal task R8 TaskTCB[taskprio].stkptr R8
R7 R7
R7
R6 • Initializes the R6
R6 R5
R5 R5 tskstate.waitQ to
R4 R4
R4
R3 R3 waitQ[taskprio] R3
R2 R2
R2
R1
• Initializes the R1
R1
R0 R0 tskstate.readyQ to R0
readyQ[taskprio]
readyQ 0 0 1 0 0 1 0 0 1 0 0
waitQ 1 0 0 1 1 0 1 1 0 1 1
68
A Simple Task Model
#define NO_TASKS 3
#define TASK_STK_SIZE 100
unsigned int TaskStk[NO_TASK][TASK_STK_SIZE]
void init_timer();
int main(void)
{
OSInit();
init_timer();
TaskCreate(task1, (void *) 0, “Task1”, 0);
TaskCreate(task2, (void *) 0, “Task2”, 1);
OSStart();
}
OSStart:
• Find the Highest priority task High Priority Task’s Stack
• Load SP with TaskTCB[hiprio].stkptr
PC
• Load the context CPSR
LR
OSStart(): R12
current = taskTCB[hiprio] R11
R10
//SP = taskTCB[hiprio]->stkptr R9
ldr lr, = taskTCB[hiprio] R8
R7
ldr lr, [lr] R6
R5
ldr sp, [lr] R4
High Priority Task’sTCB
ldmia sp!, {r0-r12} R3
SP stkptr R2
ldmia sp!, {lr} taskprio R1
ldmia sp!, {lr} tskstate R0
tskevent
msr spsr, lr taskname
ldmia sp!, {lr} NEXT
movs pc, lr 70
OSStart 2/11
OSStart:
• Find the Highest priority task High Priority Task’s Stack
• Load SP with TaskTCB[hiprio].stkptr
PC
• Load the context CPSR
LR
OSStart(): R12
current = taskTCB[hiprio] R11
R10
//SP = taskTCB[hiprio]->stkptr R9
ldr lr, = taskTCB[hiprio] R8
R7
ldr lr, [lr] R6
R5
ldr sp, [lr] R4
High Priority Task’sTCB
ldmia sp!, {r0-r12} R3
SP stkptr R2
ldmia sp!, {lr} taskprio R1
ldmia sp!, {lr} tskstate R0
tskevent
msr spsr, lr taskname
ldmia sp!, {lr} NEXT
movs pc, lr 71
TCB stack pointer?
readyQ 0 0 1 0 0 1 0 0 1 0 0
waitQ 1 0 0 1 1 0 1 1 0 1 1
72
OSStart 3/11
OSStart:
• Find the Highest priority task High Priority Task’s Stack
• Load SP with TaskTCB[hiprio].stkptr
PC
• Load the context CPSR
LR
OSStart(): R12
current = taskTCB[hiprio] R11
R10
//SP = taskTCB[hiprio]->stkptr R9
ldr lr, = taskTCB[hiprio] R8
R7
ldr lr, [lr] R6
R5
ldr sp, [lr] R4
High Priority Task’sTCB
ldmia sp!, {r0-r12} R3
SP stkptr R2
ldmia sp!, {lr} taskprio R1
ldmia sp!, {lr} tskstate R0
tskevent
msr spsr, lr taskname
ldmia sp!, {lr} NEXT
movs pc, lr 73
OSStart 4/11
OSStart:
• Find the Highest priority task High Priority Task’s Stack
• Load SP with TaskTCB[hiprio].stkptr
PC
• Load the context CPSR
LR
OSStart(): R12
current = taskTCB[hiprio] R11
R10
//SP = taskTCB[hiprio]->stkptr R9
ldr lr, = taskTCB[hiprio] R8
R7
ldr lr, [lr] R6
R5
ldr sp, [lr] R4
High Priority Task’sTCB
ldmia sp!, {r0-r12} R3
SP stkptr R2
ldmia sp!, {lr} taskprio R1
ldmia sp!, {lr} tskstate R0
tskevent
msr spsr, lr taskname
ldmia sp!, {lr} NEXT
movs pc, lr 74
OSStart 5/11
OSStart:
• Find the Highest priority task High Priority Task’s Stack
• Load SP with TaskTCB[hiprio].stkptr
PC
• Load the context CPSR
LR
OSStart(): R12
current = taskTCB[hiprio] R11
R10
//SP = taskTCB[hiprio]->stkptr R9
ldr lr, = taskTCB[hiprio] R8
R7
ldr lr, [lr] R6
R5
ldr sp, [lr] R4
High Priority Task’sTCB
ldmia sp!, {r0-r12} R3
SP stkptr R2
ldmia sp!, {lr} taskprio R1
ldmia sp!, {lr} tskstate R0
tskevent
msr spsr, lr taskname
ldmia sp!, {lr} NEXT
movs pc, lr 75
OSStart 6/11
OSStart:
• Find the Highest priority task High Priority Task’s Stack
• Load SP with TaskTCB[hiprio].stkptr
PC
• Load the context CPSR
LR
OSStart(): R12
current = taskTCB[hiprio] R11
R10
//SP = taskTCB[hiprio]->stkptr R9
ldr lr, = taskTCB[hiprio] R8
R7
ldr lr, [lr] R6
R5
ldr sp, [lr] R4
High Priority Task’sTCB
ldmia sp!, {r0-r12} R3
SP stkptr R2
ldmia sp!, {lr} taskprio R1
ldmia sp!, {lr} tskstate R0
tskevent
msr spsr, lr taskname
ldmia sp!, {lr} NEXT
movs pc, lr 76
OSStart 7/11
OSStart:
• Find the Highest priority task High Priority Task’s Stack
• Load SP with TaskTCB[hiprio].stkptr
PC
• Load the context CPSR
LR
OSStart(): R12
current = taskTCB[hiprio] R11
R10
//SP = taskTCB[hiprio]->stkptr R9
ldr lr, = taskTCB[hiprio] R8
R7
ldr lr, [lr] R6
R5
ldr sp, [lr] R4
High Priority Task’sTCB
ldmia sp!, {r0-r12} R3
SP stkptr R2
ldmia sp!, {lr} taskprio R1
ldmia sp!, {lr} tskstate R0
tskevent
msr spsr, lr taskname
ldmia sp!, {lr} NEXT
movs pc, lr 77
OSStart 8/11
OSStart:
• Find the Highest priority task High Priority Task’s Stack
• Load SP with TaskTCB[hiprio].stkptr
PC
• Load the context CPSR
LR
OSStart(): R12
current = taskTCB[hiprio] R11
R10
//SP = taskTCB[hiprio]->stkptr R9
ldr lr, = taskTCB[hiprio] R8
R7
ldr lr, [lr] R6
R5
ldr sp, [lr] R4
High Priority Task’sTCB
ldmia sp!, {r0-r12} R3
SP stkptr R2
ldmia sp!, {lr} taskprio R1
ldmia sp!, {lr} tskstate R0
tskevent
msr spsr, lr taskname
ldmia sp!, {lr} NEXT
movs pc, lr 78
OSStart 9/11
OSStart:
• Find the Highest priority task High Priority Task’s Stack
• Load SP with TaskTCB[hiprio].stkptr
PC
• Load the context CPSR
LR
OSStart(): R12
current = taskTCB[hiprio] R11
R10
//SP = taskTCB[hiprio]->stkptr R9
ldr lr, = taskTCB[hiprio] R8
R7
ldr lr, [lr] R6
R5
ldr sp, [lr] R4
High Priority Task’sTCB
ldmia sp!, {r0-r12} R3
SP stkptr R2
ldmia sp!, {lr} taskprio R1
ldmia sp!, {lr} tskstate R0
tskevent
msr spsr, lr taskname
ldmia sp!, {lr} NEXT
movs pc, lr 79
OSStart 10/11
OSStart:
• Find the Highest priority task High Priority Task’s Stack
• Load SP with TaskTCB[hiprio].stkptr
PC
• Load the context CPSR
LR
OSStart(): R12
current = taskTCB[hiprio] R11
R10
//SP = taskTCB[hiprio]->stkptr R9
ldr lr, = taskTCB[hiprio] R8
R7
ldr lr, [lr] R6
R5
ldr sp, [lr] R4
High Priority Task’sTCB
ldmia sp!, {r0-r12} R3
SP stkptr R2
ldmia sp!, {lr} taskprio R1
ldmia sp!, {lr} tskstate R0
tskevent
msr spsr, lr taskname
ldmia sp!, {lr} NEXT
movs pc, lr 80
OSStart 11/11
OSStart:
• Find the Highest priority task High Priority Task’s Stack
• Load SP with TaskTCB[hiprio].stkptr
PC
• Load the context CPSR
LR
OSStart(): R12
current = taskTCB[hiprio] R11
R10
//SP = taskTCB[hiprio]->stkptr R9
ldr lr, = taskTCB[hiprio] R8
R7
ldr lr, [lr] R6
R5
ldr sp, [lr] R4
High Priority Task’sTCB
ldmia sp!, {r0-r12} R3
SP stkptr R2
ldmia sp!, {lr} taskprio R1
ldmia sp!, {lr} tskstate R0
tskevent
msr spsr, lr taskname
ldmia sp!, {lr} NEXT
movs pc, lr 81
Entry from OSStart
#define NO_TASKS 3
#define TASK_STK_SIZE 100
unsigned int TaskStk[NO_TASK][TASK_STK_SIZE]
void init_timer();
int main(void)
{
OSInit();
init_timer();
TaskCreate(task1, (void *) 0, “Task1”, 0);
TaskCreate(task2, (void *) 0, “Task2”, 1);
OSStart();
}
#define NO_TASKS 3
#define TASK_STK_SIZE 100
unsigned int TaskStk[NO_TASK][TASK_STK_SIZE]
int main(void)
{
OSInit();
TaskCreate(task1, (void *) 0, “Task1”, 0);
TaskCreate(task2, (void *) 0, “Task2”, 1);
OSStart
}
Blockingcall(void) UnBlockingcall(void)
{ {
//Check if called from ISR //Check Task TCB to find
the // task blocked on this
current->taskstate->waitQ=1;
event
//Update current->tskevent
taskTCB.taskstate->waitQ=0;
Sched();
taskTCB.taskstate->readtQ=1;
}
//Update current->tskevent
Sched();
}
85
Blocking / Unblocking call 3/11
Blockingcall(void) UnBlockingcall(void)
{ {
//Check if called from ISR //Check Task TCB to find
the // task blocked on this
current->taskstate->waitQ=1;
event
//Update current->tskevent
taskTCB.taskstate->waitQ=0;
Sched();
taskTCB.taskstate->readtQ=1;
}
//Update current->tskevent
Sched();
}
86
Entry into the wait queue 4/11
PC PC
PC TaskCreate(): CPSR
CPSR CPSR
LR OSInit(): LR • Fill the TaskStk[taskprio] LR
R12 R12
R12 • Initialize kernel data R11
with the stack frame R11
R11 R10
R10 structures R10 • Initializes the R9
R9 R9
R8 • Create an Idle task R8 TaskTCB[taskprio].stkptr R8
R7 R7
R7
R6 • Initializes the R6
R6 R5
R5 R5 tskstate.waitQ to
R4 R4
R4
R3 R3 waitQ[taskprio] R3
R2 R2
R2
R1
• Initializes the R1
R1
R0 R0 tskstate.readyQ to R0
readyQ[taskprio]
readyQ 0 0 1 0 0 1 0 0 1 0 0
waitQ 1 0 0 1 1 0 1 1 0 1 1
87
Update task event 5/11
Blockingcall(void) UnBlockingcall(void)
{ {
//Check if called from ISR //Check Task TCB to find
the // task blocked on this
current->taskstate->waitQ=1;
event
//Update current->tskevent
taskTCB.taskstate->waitQ=0;
Sched();
taskTCB.taskstate->readtQ=1;
}
//Update current->tskevent
Sched();
}
88
Invoke scheduler 6/11
Blockingcall(void) UnBlockingcall(void)
{ {
//Check if called from ISR //Check Task TCB to find
the // task blocked on this
current->taskstate->waitQ=1;
event
//Update current->tskevent
taskTCB.taskstate->waitQ=0;
Sched();
taskTCB.taskstate->readtQ=1;
}
//Update current->tskevent
Sched();
}
89
Scheduler-code eg 7/11
Sched(void)
{
while(taskTCB.next != NULL)
{
if(taskTCB.tskstate.readyQ == 1)
{
if (currentTCB.Taskprio < taskTCB[prio] .taskprio
{
next = taskTCB[prio]
ContextSW();
}
}
}
}
90
Scheduler-check for H.P. ready 8/11
Sched(void)
{
while(taskTCB.next != NULL)
{
if(taskTCB.tskstate.readyQ == 1)
{
if (currentTCB.Taskprio < taskTCB[prio] .taskprio
{
next = taskTCB[prio]
ContextSW();
}
}
}
}
91
Scheduler-check for priority 9/11
Sched(void)
{
while(taskTCB.next != NULL)
{
if(taskTCB.tskstate.readyQ == 1)
{
if (currentTCB.Taskprio < taskTCB[prio] .taskprio
{
next = taskTCB[prio]
ContextSW();
}
}
}
}
92
Scheduler-load next task to run 10/11
Sched(void)
{
while(taskTCB.next != NULL)
{
if(taskTCB.tskstate.readyQ == 1)
{
if (currentTCB.Taskprio < taskTCB[prio] .taskprio
{
next = taskTCB[prio]
ContextSW();
}
}
}
}
93
Scheduler- calls context switch 11/11
Sched(void)
{
while(taskTCB.next != NULL)
{
if(taskTCB.tskstate.readyQ == 1)
{
if (currentTCB.Taskprio < taskTCB[prio] .taskprio
{
next = taskTCB[prio]
ContextSW();
}
}
}
}
94
Context SW Handler
Context Save Context Load
Save Context:
stmdb sp!, {lr}
mrs lr, cpsr
stmdb sp!, {lr} PC PC
stmdb sp!, {r0-r12} CPSR CPSR
LR LR
current.stkptr=SP R12 R12
R11 R11
R10 R10
Load Context: R9 R9
current = next R8 R8
R7 R7
SP = next.stkptr R6 R6
R5 R5
ldmia sp!, {r0-r12} R4 R4
ldmia sp!, {lr} R3 R3
R2 R2
ldmia sp!, {lr} R1 R1
msr spsr, lr R0 R0
current->stkptr
ldmia sp!, {lr} SP
movs pc, lr next 95
Context SW Handler
#define NO_TASKS 3
#define TASK_STK_SIZE 100
unsigned int TaskStk[NO_TASK][TASK_STK_SIZE]
int main(void)
{
OSInit();
TaskCreate(task1, (void *) 0, “Task1”, 0);
TaskCreate(task2, (void *) 0, “Task2”, 1);
OSStart
}
101
Task State Transition
Task
Task Blocked
Dormant
Un Blocking call
Blocking call
TaskCreate
102
A Simple Task Model
#define NO_TASKS 3
#define TASK_STK_SIZE 100
unsigned int TaskStk[NO_TASK][TASK_STK_SIZE]
int main(void)
{
OSInit();
TaskCreate(task1, (void *) 0, “Task1”, 0);
TaskCreate(task2, (void *) 0, “Task2”, 1);
OSStart
}
#define NO_TASKS 3
#define TASK_STK_SIZE 100
unsigned int TaskStk[NO_TASK][TASK_STK_SIZE]
int main(void)
{
OSInit();
TaskCreate(task1, (void *) 0, “Task1”, 0);
TaskCreate(task2, (void *) 0, “Task2”, 1);
OSStart
}
Task
Task Blocked
Dormant
Un Blocking call
Blocking call
TaskCreate
105
Deleting a Task
#define NO_TASKS 3
#define TASK_STK_SIZE 100
unsigned int TaskStk[NO_TASK][TASK_STK_SIZE]
int main(void)
{
OSInit();
TaskCreate(task1, (void *) 0, “Task1”, 0);
TaskCreate(task2, (void *) 0, “Task2”, 1);
OSStart
}
Event HW ISR
latency
void task1 (void *data) Scheduler
{
while(1) Context SW
{ Dispatch Time/Response Time
blockonEvent1();
……..
…….. Execution Time
……..
}
} Dispatch Time + Execution Time = Release Time < Dead Line
Event HW ISR
latency
void task1 (void *data) Scheduler
{
while(1) Context SW
{ Dispatch Time/Response Time
blockonEvent1();
……..
…….. Execution Time
……..
}
} Dispatch Time + Execution Time = Release Time < Dead Line
Event HW ISR
latency
void task1 (void *data) Scheduler
{
while(1) Context SW
{ Dispatch Time/Response Time
blockonEvent1();
……..
…….. Execution Time
……..
}
} Dispatch Time + Execution Time = Release Time < Dead Line
Event HW ISR
latency
void task1 (void *data) Scheduler
{
while(1) Context SW
{ Dispatch Time/Response Time
blockonEvent1();
……..
…….. Execution Time
……..
}
} Dispatch Time + Execution Time = Release Time < Dead Line
Event HW ISR
latency
void task1 (void *data) Scheduler
{
while(1) Context SW
{ Dispatch Time/Response Time
blockonEvent1();
……..
…….. Execution Time
……..
}
} Dispatch Time + Execution Time = Release Time < Dead Line
Event HW ISR
latency
void task1 (void *data) Scheduler
{
while(1) Context SW
{ Dispatch Time/Response Time
blockonEvent1();
……..
…….. Execution Time
……..
}
} Dispatch Time + Execution Time = Release Time < Dead Line
Event HW ISR
latency
void task1 (void *data) Scheduler
{
while(1) Context SW
{ Dispatch Time/Response Time
blockonEvent1();
……..
…….. Execution Time
……..
}
} Dispatch Time + Execution Time = Release Time < Dead Line
Event HW ISR
latency
void task1 (void *data) Scheduler
{
while(1) Dispatch Time/Response Time
Context SW
{
blockonEvent1();
……..
…….. Execution Time
……..
}
} Dispatch Time + Execution Time = Release Time < Dead Line
Event HW ISR
latency
void task1 (void *data) Scheduler
{
while(1) Context SW
{ Dispatch Time/Response Time
blockonEvent1();
……..
…….. Execution Time
……..
}
} Dispatch Time + Execution Time = Release Time < Dead Line
Event HW ISR
latency
void task1 (void *data) Scheduler
{
while(1) Context SW
{ Dispatch Time/Response Time
blockonEvent1();
……..
…….. Execution Time
……..
}
} Dispatch Time + Execution Time = Release Time < Dead Line
Event HW ISR
latency
void task1 (void *data) Scheduler
{
while(1) Context SW
{ Dispatch Time/Response Time
blockonEvent1();
……..
…….. Execution Time
……..
}
} Dispatch Time + Execution Time = Release Time < Dead Line
Interrupt Response
Interrupt Recovery
118
For a Foreground/background system
TIME
119
For a non-preemptive scheduler
TIME
120
For a Preemptive scheduler
TIME
121
RTOS Tasks: Code Sharing Issues
122
Achieving atomicity
• Disable interrupts
• Use of semaphores
123
Use Flags for atomicity
124
Use Semaphore for atomicity
int main()
{
sem = OSSemCreate();
} void task2()
{
void taskl()
OSSemPend();
{
OSSemPend(); countErr(9);
countErr(9); OSSemPost();
OSSemPost(); …..
….. }
}
125
How by Semaphores?
OSSemPend(sem) OSSemPost(sem)
{ {
if(flag == 1) if(flag == 0)
{ {
flag = 0; flag = 1;
} // check the waitQ for
else // the task blocked on
{ // sem
// Add the task in waitQ // If found then
sched(); // Remove it from waitQ
} // and add in to ReadyQ
} sched()
}
} 126
uCOS-II Semaphores usage
127
Shared Resource problems
128
Practical Problem 1
129
130
Problem 2
131
132
Solution for priority inversion
• Priority Inheritance:
– Priority of Low level task raised to that of the
high priority task .
– Avoids preemption of low priority task by
medium priority task.
• Priority Ceiling
– Mutex or Semaphore initialized to a level known
as the ceiling
– Priority of task that acquires the semaphore
raised to the ceiling
– Priority raised above all other tasks desiring the
semaphore.
133
Mutex System Calls
OS_EVENT *OSMutexCreate(INT8U prio,INT8U *err);
void OSMutexPend(OS_EVENT *pevent, INT16U timeout, INT8U *err);
INT8U OSMutexPost(OS_EVENT *pevent);
134
Mailbox
Task m unblocks by
Task n blocks posting
135
Mailbox Systems Calls
136
Message queue
137
M.Q. System Calls
OS_EVENT *OSQCreate(void **start, INT16U size);
138
We are Done
Questions??
139