Embed
Email

RTOS eng

Document Sample
RTOS eng
Shared by: HC11112920590
Categories
Tags
Stats
views:
0
posted:
11/29/2011
language:
English
pages:
66
Real Time Operating Systems







Johan Dams

Email: jd@puv.fi

INTRODUCTION

 RTOS ???

– Real Time Operating System

 Where used?

– Satellite systems

– Measuring equipment

– GSM (antennas and devices)

– Cars (e.g. ABS)

– Cameras

– Medical instruments

– Motor control

– Network adapters

– Robots

– Fax machines, copiers

– Printers, terminals, scanners, modems

– Switches and routers

– Flight systems, weapon systems

– Micro-wave systems, dishwashers, thermostats

– ...

MicroC/OS-II (Jean J Labrosse)



 Free for educational use

 Easy as entry level

 Can handle 64 tasks (-8 for system)

 64 priority levels

 Price: $60 book+disk

 Implementations exist for:

– Win95/98

– 68HC11

– 80x86

– M16C (!)

– …

Foreground/Background systems

 Foreground

– = "Interrupt level"

– based on Interrupt Service Routines (ISR)



 Background

– = "Task level"

– Most used

Real-Time Systems Concept

Definitions

 "Critical Section of Code": has to be treated uninterrupted

 Resource (printer, keyboard, …but also variable, structure...)

 Shared Resource: can be used by more then one task. Mutual

Exclusion !!!

 Multitasking: process in which CPU-time is divided under multiple tasks

 Task or thread :

– Thinks it has got the CPU for itself.

– Has a priority

 Five conditions in which a task can be:

– DORMANT

• exists in memory

• not yet offered to the multitasking kernel

– READY

• can be executed

• has lower priority then running tasks

– RUNNING

• if the task has control of the CPU

Definitions



– WAITING

• waits for an event (e.g. I/O)

• waits for resource to be available

• wait till certain time elapses

– ISR (Interrupt Service Routine)

• if there is an interrupt

 Context switch

• Context ? See fig.

• Task Control Block gets

exchanged by OS with Registers

• More CPU registers => more

overhead

Definitions

 Kernel

– Piece of a multitasking system that controls tasks

– Primary task = context switching

– Extra ROM and RAM needed -> problem for single-chip processors

– RAM gets eaten

– Extra CPU-time needed (2 tot 5%)

 Scheduler (or: dispatcher)

– controls which task will run

– Mostly priority based

– Priority-based kernel = gives highest priority task that is ready to run

control of the CPU

Preemptive and non-preemptive

kernels

 non-preemptive kernel

– also: "cooperative multitasking"

– A task has to give up the CPU itself

– releasing the CPU has to be done fast

– small interrupt latency

– every task can run completely

before the CPU is released

– less danger for corruption

(non-reentrant functions)

– bad response on high-priority

tasks

– crash of a task, or endless

loop --> ??

Preemptive and non-preemptive

kernels

 Preemptive kernel

– Used when response time important

– eg. microC/OS-II

– Highest priority task ALWAYS gets control

– Highest priority tasks gets

immediate control

– response time very short

– Non-reentrant functions

cannot be used!

– After execution of task

continue with highest priority

task (not interrupted task)

Reentrant functions

 Can be used by multiple tasks at the same time

 Examples:

int Temp;

void swap(int *x, int *y)

{

Temp = *x;

*x = *y;

*y = Temp;

}





void strcpy(char *dest, char *src)

{

while(*dest++ = *src++) {

*dest = NULL;

}

}

Round-Robin scheduling





 When: if 2 or more tasks have the same priority

 Every task gets fixed amount of time: a quantum

 = time slicing

 Alternative: Task priority. Highest priority gets CPU

Static and Dynamic priorities





 Static: priority does not change

 Dynamic : priority changes during execution

 Dynamic is needed to prevent priority inversions

Priority inversions

 One of the problems when using real time kernels

 Situation: 3 tasks with different priority (H-M-L)

 Task 1 (High priority) needs a semaphore (resource),

occupied by task 3

 problem: task 1 (H)

has to wait too long

to start running

Priority inversions

 Solution: give task 3 a very high priority For as long as it

occupies the resource

 Needed: a kernel

that can change the

priority itself

Assigning priorities to tasks

 SOFT real-time system: tasks don’t have to be completed

within a certain time

 HARD real-time system: tasks have to be completed

correctly within time

 Method: RMS (Rate Monotonic Scheduling)

– Most executed tasks -> highest priority

– Demands:

• tasks occur regularly

• tasks don’t exchange anything

• preemptive scheduling needed

– real-time deadlines are met when

Ei

 ----  n 2 1 / n – 1 

Ti

-

i

– Ei maximum time needed for task i

– Ti time between i and i+1

– n = number of tasks

Assigning task priorities



– Conclusion

NUMBER OF TASKS n 2 1 /n – 1 

1 1.000

2 0.828

3 0.779

4 0.756

5 0.743

... ...

 0.693

– Thus: never use more then 60% to 70% CPU time

Mutual Exclusion

 Demand: exclusive use of a resource

 How?

– Disable interrupts

• Used on critical sections of code

• For very short time only

– Test-and-set operations

• For important sections

• Needs more time

• Principle:

disable interrupt

test test-and-set variable

Set test-and-set variable to 1

enable interrupt

Access resource

disable interrupt

Set test-and-set variable to 0

enable interrupt

Mutual Exclusion



– Disable scheduling

• Normal: after interrupt, processing goes to highest priority task

• Now: after interrupt, processing goes back to interrupted task

– Use of semaphores

• Better method than disabling scheduling

• Invented mid 1960

• Principle

– Access control on shared resource

– Event gets clearly flagged

– Two tasks can synchronise

• = key you need in order to continue processing

• If semaphore in use, keep WAITING until it gets available

• ”Give me the key. If it is in use, I’ll keep waiting."

Mutual Exclusion

• Binary semaphore: two conditions, used or not

• Counting semaphore:from 0 tot 2^8, 2^16 of 2^32

– => semaphore counts downwards (!)

Three semaphore operations

 INITIALIZE (or CREATE)

– initial waiting list is empty

 WAIT (or PEND)

– a task requests a resource

– If semaphore = 0,

• next task goes in WAIT

• next task is put on waitinglist

– If semaphore > 0,

• tasks begins execution

• semaphore gets decremented

 SIGNAL (or POST)

– a task releases the semaphore

– no task waiting: semaphore incremented

– task waiting: key is given to new task

– new task is

• first task that asked for semaphore (FIFO)

• highest priority task

Three semaphore operations

 Example

Encapsulated semaphores

 Principle:

– task does not have to control semaphore

– Resource controls the semaphore

 Typical: driver of the resource solves semaphores

 Release of a semaphore is done through a timeout

 eg. Network card, serial port, ...









 Advantages:

– tasks just use the driver

– programmer does not have to deal with the semaphores

Deadlocks (Deadly embrace)

 What ?

– Two tasks waiting for each others semaphore

 Solutions

– acquire all resources before proceeding

– always acquire resources in the same order and

– always release in reverse order

– use of time-outs on semaphores

Synchronisation

 What ?

– Synchronisation between tasks

– Synchronisation between tasks and ISR

 How ?

– Use of semaphores

– "unilateral rendezvous"

– semaphore signals an event (flag, NOT a key)

Synchronisation



– counting semaphores for accumulation of events not processed yet

– More than one task can be waiting for event:

• highest task first

• first task first (FIFO)

– "bilateral rendezvous"

• synchronising two tasks (not task + ISR) with two semaphores

Event Flags

 When ?

– A task has to synchronise with multiple events

 Disjunctive synchronisation

– logical OR

– synchronisation if one of the events occurred

 Conjunctive synchronisation

– logical AND

– synchronisation if all

events occurred

Inter task communication

 What ?

– ISR or task sends information to other task

 How ?

– Global variables

– sending messages

 Global variables

– Make sure you have exclusive access

• by disabling and enabling interrupts

• by use of semaphores

– Alterations are passed on by

• use of semaphores

• polling of the results





– Better methods: "message mailbox" and "message queues"

Message mailboxes

 Principle:

– interchanging messages through the kernel

– typical pointer size variable

– Kernel provides a mailbox service

– Task or ISR drops a message (pointer) in the mailbox

– pointer can point to any data

– transmitter and receiver know what data the pointer holds

 Waiting list

– every mailbox can have a waiting list

– used if more tasks are waiting the arrival of a message in one mailbox

 Task asking message from empty mailbox

– goes in SUSPEND (WAIT)

– goes active as soon a message is present

• highest priority first

• first task first serve (FIFO)

– in general: timeout is specified

– after timeout: error code

Message mailboxes







– I-beam = message box

– hourglass "10" = number of clock ticks before time-out

 Typical operations on a mailbox

– init of mailbox, can have a message initially

– deposit message in mailbox (POST)

– get message from mailbox, wait if no available (PEND)

– get message from mailbox, don't wait if no available (ACCEPT)

Message Queues

 Principle

– used to send one or more messages to a task

– typical an array of mailboxes

– a task or ISR can deliver a message (pointer) in hte message queue

– one or more tasks can receive messages from the queue through the

kernel

– sender and receiver know what kind of data is behind the pointer

 typical FIFO, also LIFO and highest priority possible

 Also here:

– task can go in WAIT if queue is empty

– task can specify time out









– square = queue - "10" = max number of messages in queue - "0" =

time-out

Interrupts

 What?

– hardware mechanism for asynchronous event

 If interrupt is recognised

– CPU saves (part of) local variables (CPU-Registers)

– CPU jumps to special part of memory (ISR)

 At the end of the interrupt, the program continues with:

– the background (foreground/background system)

– the interrupted task (non-preemptive kernel)

– the highest priority task ready to run (preemptive kernel)

 Allow to run process events when they happen

 no POLLING needed

 Disabling interrupts

– possible, but highly not recommended

– in real-time systems, as short as possible

– interrupts are NOT Queued

• interrupts can be missed

Interrupt Latency

 Important RTOS specification:

– Amount of time interrupts are disabled

– Disabling is needed for critical sections

– During disabling: interrupt latency

 Interrupt latency?

– Interrupt latency = maximum amount of time interrupts are disabled +

Time to start executing the first instruction of the ISR

 Interrupt response time

– = time between the reception of an interrupt and the start of user

code that handles the interrupt.

– For foreground/background systems AND non-preemptive kernels

• = interrupt latency + time needed to save CPU context

– For preemptive kernels

• = interrupt latency + time needed to save CPU context

+ execution time of the kernel ISR entry function

Interrupt Latency

 Interrupt Recovery

– For foreground/background systems AND non-preemptive kernels

• = time to put CPU context back + time for RTI instruction

– For preemptive kernels

• = Time to determine if a higher priority task is ready

+ time to put CPU context back

+ time for RTI instruction

 Non-maskable interrupts

– Cannot be disabled

– Mostly in hardware

– Only for important tasks

– Eg. To save data during power-down.

Clock tick

 = special interrupt

– Periodical

 = RTOS heartbeat

 Typical 1 tot 200 ms

 Higher clock tick leads to more overhead









 Delaying a task: “n” clock ticks

Memory usage of a RTOS



 Foreground-background systems

– Only dependant on application size

 RTOS

– Extra room needed for kernel

– for mControllers: 1 tot 100 KBytes for the RTOS

– MicroC-OS/II : 3KB

– Extra RAM needed for ISR and context switching of tasks

ad- and disadvantages of RTOS

 Advantages:

– Real time applicaties are easier to expand

– Timecritical applications are dealt with more efficiently

– Important services

• semaforen

• mailboxes

• queues

• fixed time delays

• time-out handling

 Disadvantages:

– More CPU-time (2 to 5%), RAM and ROM needed

– Extra cost for the RTOS

MicroC/OS II

Kernel structure: critical sections

 Critical sections

– During critical moments : disable interrupts

– Usercode can also indicate critical sections

• OS_ENTER_CRITICAL()

• OS_EXIT_CRITICAL()

– These macros are in OS_CPU.H



Kernel structuur: Tasks

 Tasks

– Result = void

– Structure

• void JustAnotherTask(void *pdata)

{

User Code;

System Call;

User Code;

}

Kernel structure: Tasks

 Example of an infinite task

void JustAnotherTask(void *pdata)

{

for (;;)

{

User Code;



OSMboxPend(); of

OSQPend(); of

OSSemPend(); of

OSTaskDel(OS_PRIO_SELF); of

OSTaskSuspend(OS_PRIO_SELF); of

OSTimeDly(); of

OSTimeDlyHMSM();



User Code;

}

}

Kernel structure: Tasks

 Example of a temporary task

void MyTask(void *pdata)

{

User Code;

OsTaskDel(OS_PRIO_SELF);

}

 Function of void *pdata

– “void” can be any kind of data

– pdata is given to the task during startup

– eg. Number of a serial port

•  1 task can handle all serial ports

Kernel structure: priorities

 Priorities

– Max 64 priority levels

– 8 levels reserved for OS

– 56 for user

• from 0 tot OS_LOWEST_PRIO-2

– Low number = high priority

– Highest priority is dealt with first

 Creation of tasks

– Task must be offered to Kernel

• Memory address and parameters are given

• OSTaskCreate() or OSTaskCreateExt()

Kernel structure: states of a task

 States of a task

– DORMANT

• Not yet offered to kernel

– READY

• Task offered with OSTaskCreate() or OSTaskCreateExt()

• Back to dormant by OSTaskDel()

– RUNNING

• After multitasking has been started (see also further)

• Highest priority first

– WAITING

• A task can delay itself with OSTimeDly()or OSTimeDlyHMSM()

• A task can also be waiting for an event, like

– OSSemPend(); OSMboxPend(), OSQPend()

– ISR state

• When interrupt has occurred

Kernel structure: states of the kernel

 States of the kernel

– Multitasking is started with OSStart()

– A WAITING task gets back activated with OSTimeTick()

– If all tasks are waiting for an event: idle task OSTaskIdle()

Kernel structure: Task Control Blocks

 Task Control Blocks (OS_TCBs)

– A task that has been created, gets an OS_TCB

typedef struct os_tcb {

OS_STK *OSTCBStkPtr;

void *OSTCBExtPtr;

OS_STK *osTCBStkBottom;

INT32U OSTCBStkSize;

INT16U OSTCBOpt;

INT16U OSTCBId;



struct os_tcb *OSTCBNext;

struct os_tcb *OSTCBPrev;

OS_EVENT *oSTCBEventPtr;



void *OSTCBMsg;

INT16U OSTCBDly;

INT8U OSTCBStat;

INT8U OSTCBPrio;

INT8U OSTCBX;

INT8U OSTCBY;

INT8U OSTCBBitX;

INT8U OSTCBBitY;



BOOLEAN OSTCBDelReq;

} OS_TCB;

Kernel structure: Task Control Blocks

 Explanations

– OSTCBStkPtr

• Every task has its own stack

– OSTCBExtPtr

• Pointer to own part of TCB

– OSTCBStkBottom

• Points to the end of the TCB

– OSTCBDly

• Number of clock ticks the task needs to be delayed

– OSTCBStat

• Contains current task status

• 0 = READY, see uCOS_II.H file

– OSTCBPrio

• Contains task priority, low number = high priority

– OSTCBDelReq

• Request to be deleted

Kernel structure: Task Control Blocks

 Some constants

– OS_MAX_TASKS

• Max number of tasks available

• Can be reduced  less memory needed

• Reduce to the actual number used

– List of OS_TCBs is made in advance

• Notice list structure









– OS_LOWEST_PRIO

• Lowest applicable priority

• Note! Number of priorities can be higher than number of tasks

Kernel structure: Locking

 Scheduler

– Will let highest priority task run

– Lower priority task gets interrupted

 Locking the scheduler

– Using OSSchedLock() allows scheduler to be stopped

– Low priority tasks keeps in control

– Stays like that until OSSchedUnlock() gets called

 When?

– Normally: never

– Exceptions, eg. If a task has to post a lot of messages

• multiple mailboxes, queues, semaphores

• messages have to be dealt with simultaneous  synchronisation

Kernel structure: Statistics

 What?

– Keeps the amount (% ) of CPU in use

– Resolution = 1%

 How?

– Call in the beginning OSStatInit()

• Set a variablein configuration file: OS_TASK_STAT_EN

– Every second, the task OSTaskStat() will be started.

 Result is kept in variable OSCPUUsage

 OSIdleCtr 

OSCPUUsage  100 1  

 OSIdleCtrM ax 



– with: OSIdleCtr : gets +1 if OSTaskIdle() gets called

OSIdleCtrMax : calculated once during Init

Kernel structure: starting program

 How?

– A program in C starts with

void main(void)

{

/* own code */

}

– In this routine the following has to happen:

• Initialisation of the RTOS : OSInit()

• Creation of a task by OSTaskCreate() or OSTaskCreateExt()

• Starting of the RTOS : OSStart()

– Example:

void main(void) {

OSInit()

OSTaskCreate(TaskStart,(void *) 0,(void *)

&TaskStartStk[TASK_STK_SIZE-1],0);

OSStart();

}

Kernel structure: starting program

 Structure of TaskStart()

– Is the actual program

– General structure:

void TaskStart(void *pdata) {

 Install and Init OS Ticker

OSStatInit(); // initialises statistics Task

 Install tasks that comprise your program

for (;;) {

your own code

OSTimeDlyHMSM(0,0,1,0);

}

Kernel structure: OS Ticker

 Remember

– OS Ticker is the 1..200ms heartbeat





 BAD way of starting

void main (void) {

OSInit()

InitTick();

OSStart()

}

 Reason:

– Tick interrupt can start before your first task

• Enabling of TICKER is done before OSStart()

– Program can crash

Kernel structure: OS Ticker

 GOOD way of starting

void TaskStart (void *pdata) {

OS_ENTER_CRITICAL()

InitTick();

OS_EXIT_CRITICAL()



Start other tasks



FOR (;;) {

other stuff

}

}

Task Management

 General form of your program

– TASK = 1) Infinite loop, or

2) Task that deletes itself

– C program

– Return value = void

void My_Task(void *pdata) void My_Task(void *pdata)

{ {

for (;;) { /* own code here */

/* own code here */ OSTaskDel(OS_PRIO_SELF);

one of following calls: }

OSMBoxPend();

OSQPend();

OSSemPend();

OSTaskDel(OS_PRIO_SELF);

OSTaskSuspend(OS_PRIO_SELF);

OSTimeDly();

OSTimDlyHMSM();

}

}

Creation of a Task

 Task is offeres to the kernel

– OSTaskCreate()

– OSTaskCreateExt(): has extra options

• Stack checking: if stack should get too big

• User-defined data area

• User-defined checks on data

 At least one task needed before OSStart()can run

 Every task has its own STACK space

– Can be expanded dynamically with malloc()

/* other code */

pstk = (OS_STK *) malloc(stack_size);

if (pstk != (OS_STK *)0) ; see if enough memory

{

/* create task */

}

/* Other code */

– Problem: fragmentation of memory

Deleting a Task

 Done by OSTaskDel()

– Code still exists

– Goes back to DORMANT state

– = “hard” delete

 Request to delete: OSTaskDelReq()

– = “soft” delete

– Task gets chance to clear semaphores and memory

– Task has to check for OSTaskDelReq !

/* other code */

if (OSTaskDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ) }

/* Release all resources */

/* De-allocate memory */

OSTaskDel(OS_PRIO_SELF);

}

else {

/* Other code */

}

Other operations on tasks

 Changing the priority

– OSTaskChangePrio()

 Suspend

– Starts after OSTaskSuspend()

– Can only be undone by OSTaskResume()

Time Management

 Delaying a task using OSTimeDly()

– OSTimeDly(ticks)

– creates context switch

– Delay of 1 to 65535 system Ticks

 Delaying a task using OSTimeDlyHMSM()

– OSTimeDlyHMSM(hours,minutes,seconds,milli)

– HMSM = Hours – Minutes – Seconds – Milliseconds

– Can go till 256 hours (around 11 days)

 Resuming a delayed task with OSTimeDlyResume()

 Requesting time with OSTimeGet()

– Result in Ticks

– Size = INT32U

Communication and synchronisation

 Use of ECB’s (Event Control Blocks)

 2 forms of communication

– a) Task or ISR gives flag to a Task

– b) A Task Waits for an event

• only Tasks can wait

• !! An ISR cannot wait

 Time-out possible

 A ECB can be

– a semaphore

• Task keeps wachten, or

• Task can be flagged

– a message mailbox

– a message queue

Use of semaphores

 Link between a Task, ISR en semaphore:









– Creation of the semaphore with OSSemCreate()

– A flag passed to a semaphore: OSSemPost()

– Waiting for a semaphore: OSSemPend()

– Accepting a semaphore without waiting: OSSemAccept()

– Requesting status of a semaphore: OSSemQuery()

Use of Message Mailboxes

 Link between een Task, ISR en Message Mailbox:









– Creation of a mailbox with OSMboxCreate()

– Posting a message in a mailbox: OSMboxPost()

– Waiting for a message in a mailbox: OSMboxPend()

– Getting a mailbox without waiting: OSMboxAccept()

– Request status of a mailbox: OSMboxQuery()

Use of Message Queues

 Queue is comprised of Queue Control Blocks

Use of Message Queues

 A Message Queue is a circular buffer

Use of Message Queues

 Link between Task, ISR en Message Queue:









– Creation of the Message Queue using OSQCreate()

– Posting a message in the queue (FIFO): OSQPost()

– Posting a message in the queue (LIFO): OSQPostFront()

– Waiting for a message in the queue: OSQPend()

– Requesting a queue without waiting: OSQAccept()

– Requesting status of a queue: OSQQuery()

Memory Management

 How does C work ?

– malloc() Function for requesting memory

– free() Function for releasing memory

 Problems

– In RTOS danger for fragmentation

– Quick shortage of continues memory blocks

 RTOS solution

– Use of memory blocks with fixed size

– All blocks same size

– Size of blocks is configurable

Memory Management

 Creation of memorypartition by use of OSMemCreate()

– Has to be done in advance

– eg. creation of 100 blocks of 32 bytes each



OS_MEM *CommTxBuf; // create pointer to buffer

INT8U CommTxPart[100][32]; // allocate memory



void main(void)

{

/* Other code */



CommTxBuf = OSMemCreate(CommTxPart,100,32,&err);

/* Check for errors using err */



/* Other code */

OSStart();

}

Memory Management

 Requesting a memory block OSMemGet()

 releasing a memory block OSMemPut()

 Bigger blocks get linked


Related docs
Other docs by HC11112920590
BACKGROUND AND HISTORY OF VENDOR
Views: 0  |  Downloads: 0
Biology of Seaweeds
Views: 5  |  Downloads: 0
Flora Brasiliensis Revisitada
Views: 0  |  Downloads: 0
WILLIAM HEGARTY SCHOLARSHIP
Views: 0  |  Downloads: 0
ERM - The Next Big Thing
Views: 0  |  Downloads: 0
www
Views: 1  |  Downloads: 0
Mock Election PR Kit bill
Views: 8  |  Downloads: 0
Presentaci�n de PowerPoint
Views: 0  |  Downloads: 0
By registering with docstoc.com you agree to our
privacy policy

You are almost ready to download!

You are almost ready to download!