Het uC/OS-II RTOS
description
Transcript of Het uC/OS-II RTOS
1
Het uC/OS-II RTOS
2
Embedded systeem
3
Programma voorgrond/achtergrond systeem
4
De meeste toepassingen (in het bijzonder 8-bit systemen) bestaan uit slechts een programma, en daarom geen behoefte aan een "traditionele" besturingssysteem. ROM monitoren vervangen door het besturingssysteem.
Operating systeem nodig ?
Meer complexe systemen van vandaag vereisen meer complexe besturing en daarom behoefte aan een besturingssysteem van een soort.
5
Type operating systemen
• monolithische kernel
• microkernel
Desktop (windows,linux,…)
QNX, minix, symbian OS
• kleine real-time OSKernel in de vorm van een API.
6
Het microCOS-II operating systeem
7
Plaats van het operating systeem
8
MicroC/OS-II
Kenmerken:
• portable
• Deterministisch
• Multitasking (max. 64 taken)
• Preemptive
•ROMable, scalable
• Prioriteit
9
• Services : Mailboxes, Queues, Semaphores, fixedsizedmemory partitions, time-related functions
MicroC/OS-II
Kenmerken:
• Interrupt Management: geneste Interrupt
• Robuust en betrouwbaar
Tekortkomingen:
• Elke taak heeft een unieke prioriteit.
• Geen priority inherintance
10
MicroC/OS-II architectuur
11
Taken:• Kan 64 taken managen (2 taken voor eigen
gebruik)
• De 4 hoogste en de 4 laagste prioriteiten zijn voor eigen gebruik
• 56 applicatie taken
• Hoe lager de waarde van de prioriteit hoe hoger de prioriteit.
• De taak prioriteit nummer dient ook als de taak identifier
12
L ow P rio rity T ask
H igh P rio rity T ask
IS R
IS R m akes the h ighprio rity tas k ready
L ow prio rity tas kre linquis hes the C P U
T ime
(1) (2)
(3)
(4)
(5)
(6)
(7)
Non –preemptive taak scheduling
13
L ow P rio rity T ask
H igh P rio rity T ask
IS R
IS R m akes the h ighprio rity tas k ready T im e
PreemptiveTaak scheduling
14
Voorbeeld taken.
void taak2(void* pdata){ while(1) print b;}
void taak1(void* pdata){ while(1) print a;}
int main(){ initialiseer; creëer taak1; creëer taak2; start scheduling;}
15
Task context switch
16
RU NNINGRE ADY
O S TaskC reate()O S TaskC reateE xt()
Task is P reempted
O S MB oxP end()O S Q P end()
O S S emP end()O S TaskS uspend()O S Tim eDly()O S Tim eDlyHMS M()
O S MB oxP ost()O S Q P ost()O S Q P ostFront()O S S emP ost()O S TaskR esum e()O S Tim eDlyR esum e()O S Tim eTick()
O S TaskDel()
DORMANT
WAIT ING
O S S tart()O S IntE xit()
O S _ TA S K _ S W ()
O S TaskDel()
O S TaskDel()
Interrupt
O S IntE xit()
ISR
Task context switch
17
Datastructuur van de ready-list
18
Datastructuur van de ready-list
Nadeel:
Voordeel:
• Taken kunnen niet dezelfde prioriteit hebben’• Aantal taken is gelimiteerd.
• store/load in constante tijd.
19
Datastructuur na de initialisatie2 taken(Stat en Idle) die door het OS gebruikt worden
20
Suspended van een taak
Bit wordtgecleared
Link blijft bestaan
21
Running(2)Zoek hoogste prioriteit in groep
(3)Zet state op running
(1)Zoek hoogste prioriteit groep
22
• Wanneer een taak wordt gemaakt, wordt er een Task Control Block aangewezen, OS_TCB
• OS_TCB is een data structuur die wordt gebruikt door UC/OS-II de state van een taak bij te behouden wanneer het preempted wordt
• Alle OS_TCB staan in het RAM
• Een OS_TCB wordt geïnitialiseerd wanneer een taak wordt gemaakt
Beheer van de taken
23
S P
C P U R eg is ters
S P
T as k C o ntro l B lo c k
Priority
C o ntext
Stac k Stac k Stac k
C PU
MEMORY
T ASK #1 T ASK #2 T ASK #n
S P
T as k C o ntro l B lo c k
Priority
S P
T as k C o ntro l B lo c k
Priority
Status Status Status
Task context switch
24
Task context switch
Elke taak heeft een stack waar de bijbehorende informatie wordt opgeslagen.
Om ervoor te zorgen dat de taak die gedwongen wordt de CPU op te geven, verder kan gaan zonder verlies van alle vitale informatie of gegevens
Doel contex switch
25
Task context switch
26
Task context switch
27
Task context switchvoor een taak wisseling
return adres
Lokale variabele
taak 1
Stack pointer
return adres
CPU registers bij het switchen
Taak 2 lokale variabele bij het switchen
Taak 2 code adres bij het switchen
Taak 2 wordt runningis ready
Taak 1 is running
stacktaak 2stack
taak 1
28
Return adres
Lokale variabele
Return adres
CPU registers bij het switchen
Taak 2 lokale variabele bij het switchen
Taak 2 code adres bij het switchen
Taak 2 stackTaak 1 stack
huidige stackpointer
Huidige
CPU
registers
Huidige
program
counterStack pointer
Taak 1 TCB
Stack pointer
Taak 1 TCB
Task context switchtijdens een taak wisseling
29
return adres
CPU registers bij het switchen
Taak 1 lokale variabele bij het switchen
Taak 1 code adres bij het switchen
Taak 1 wordt running
is ready
Loacale variabele
taak 2
Stack pointer
Return adres
Taak 2 running
Task context switchna een taak wisseling
30
Task context switch
Interrupt (hardware of software) van de context switchPush return adresPush FLAGS register
ISR (context switch routine)• Push alle registers• Sla SP op in TCB (task control block)• Select de ready taak met de hoogste prioriteit (Scheduler)• Restore de SP van de TCB van de geselecteerde taak• Pop alle registers• iret (return interrupt, pop FLAGS en return adres)
Switch to new task
31
Memory management
32
• Dynamic memory allocation kan verkregen worden door gebruik te maken van malloc() en de free() functies
• Gebruik van malloc() en de free() in een embedded real-time system is gevaarlijk
• Eventueel kan fragmentation plaatsvinden• Execution time van malloc() en free() zijn nondeterministic.
Het aanvragen van geheugen.
Het uC/OS-II kent geheugen blokken met een vaste grootte toe.
• Geheugenblokken zijn afkomstig van een partitie die in het geheugen gedeclareerd is.
• Het alloceren en dealloceren van geheugen gebeurt hierdoor in een continue tijd.
• Geheugenblokken kunnen verschillende grootte hebben.
33
Partition
Block
Start address
Partition #1 Partition #2 Partition #3 Partition #4memory partition
multiple memory partitions
Het aanvragen van geheugen. geheugenblokken
34
OSMemAddr
OSMemFreeList
OSMemBlkSize
OSMemNBlks
OSMemNFree
OSMemAddr
OSMemFreeList
OSMemBlkSize
OSMemNBlks
OSMemNFree
OSMemAddr
OSMemFreeList
OSMemBlkSize
OSMemNBlks
OSMemNFree
0OSMemFreeList
OS_MAX_MEM_PART
Het aanvragen van geheugen. Memory Control Block
• Het uC/OS-II houdt het geheugen bij d.m.v een Memory Control Block (MCB)
• Elke partitie heeft zijn eigen MCB.• Initialisatie wordt gedaan door de functie OS_MemInit() die de gelinkte lijst creeerd.
35
Memory control block.
typedef struct { void *OSMemAddr; //A void *OSMemFreeList; //B INT32U OSMemBlkSize; //C INT32U OSMemNBlks; //D INT32U OSMemNFree; //E} OS_MEM;
A. Is een pointer naar het begin van de geheugenpartitie.B. Is een pointer naar het eerst volgende vrije geheugen
ruimte.C. Is de grootte van elke geheugenblok in de partitie.D. Is het totaal aan geheugenblokken per partitie.E. Hoeveel geheugenblokken beschikbaar zijn.
36
OS_MEM *CommTxBuf;INT8U CommTxPart[100][32];void main (void){ INT8U err; OSInit(); . . CommTxBuf = OSMemCreate(CommTxPart, 100, 32, &err); . . OSStart();}
Creëren van een partitie OSMemCreate()
Vier argumenten zijn vereist• Begin addres van de memory partition.• Het aantal blocken dat gealloceerd wordt van de partition.• De grootte (in bytes) van elk block.• Een pointer naar de variabele die de error code bevat.
37
0
OSMemAddr = addr
OSMemFreeList= addr
OSMemBlkSize = blksize
OSMemNBlks = nblks
OSMemNFree = nblks
Contiguous memory
pmem
OSMemCreate() arguments
Data structuur na een geslaagde OSMemCreate()
38
Aanmaken van taken
INT8U OSTaskCreate ( ){
}
int8U prio => prioriteit
OS_STK *ptos =>pointer naar de top van de stack
void *pdata pointer naar de argumenten van de taak
void (*task)(void *pd) pointer naar de taak
, INT8U prioOS_STK *ptos
void *pdata,void (*task)(void *pd),
39
Bewerken van taken
OSTaskResume()
OSTaskDelReq()
OSTaskSuspend()
OSTaskDel()
http://sigpromu.org/brett/elec3730/quickref.htmlQuick reference:
40
Interproces communicatiemessage box
Task
ISR
Task
OSMboxPend()OSMboxAccept()OSMboxQuery()
OSMboxPost()
OSMboxPost()OSMboxAccept()
OSMboxCreate()
MailboxMessage
41
Task
ISR
Task
OSQPend()OSQAccept()OSQQuery()
OSQPost()OSQPostFront()OSQFlush()
OSQPost()OSQPostFront()OSQFlush()OSQAccept()
OSQCreate()
QueueMessage
N
Interproces communicatiemessage queue
42
Message Queue Management
43
Een Message Queue als een circulare buffer van pointers
#define RIJGROOTTE 5
OS_EVENT *postrijev;
void* postrij[RIJGROOTTE];
C code
Het creeeren van een message queue.
postrijev=OSQCreate(postrij,RIJGROOTTE);
OS_EVENT *OSQCreate(void **start, INT8U size);
OS_EVENT *postrijev;
C code
Het schrijven in een message queue.
typedef struct {
char c;
int i;
}dubbel;
INT8U OSQPost(OS_EVENT *pevent, void *msg);
rt=OSQPost(postrijev,&boodschap);
if(rt==OS_NO_ERR)
INT8U rt;
dubbel boodschap={1,’i’}
OS_EVENT *postrijev;
C code
Het lezen uit een message queue.
void *OSQPend(OS_EVENT *pevent, INT16U timeout, INT8U *err);
typedef struct {
char c;
int i;
}dubbel;
p_ontv= OSQPend( );
dubbel *p_ontv
INT8U fout;
p_ontv=(dubbel*)OSQPend(postrijev,0,&fout);
47
Porting uC/OS-II
48
Een processor kan uC / OS-II draaien, indien aan de volgende eisen voldaan wordt
Er moet een C compiler voor de microcontroller zijn.
Interrupts moeten in C gedisabled en ge-enabled kunnen worden.
De processor moet interrupt ondersteunen en ondersteunt intervallen tussen de 10 en de 100 Hz.
De processor moet instructies hebben voor het laden en opslaan van de stack pointer en andere CPU-registers, hetzij op de stack of in het geheugen.
49
OS_CFG.HINCLUDES.H
µC/OS-II(Processor Independent Code)
µC/OS-II Port(Processor Specific Code)
µC/OS-II Configuration(Application Specific)
Application Software
OS_CORE.COS_MBOX.COS_MEM.COS_Q.COS_SEM.COS_TASK.COS_TIME.C
uCOS_II.CuCOS_II.H
OS_CPU.HOS_CPU_A.ASM
OS_CPU_C.C
CPU Timer
Software
Hardware
Setting the value of 2 #define constants (OS_CPU.H)Declaring 11 data types (OS_CPU.H)Declaring 2 #define macros (OS_CPU.H)Writing 10 simple functions in C (OS_CPU_C.C)Writing 4 assembly language functions (OS_CPU_A.ASM)
50
51
#ifdef OS_CPU_GLOBALS#define OS_CPU_EXT#else#define OS_CPU_EXT extern#endif/*********************************************************************************************************** DATA TYPES* (Compiler Specific)**********************************************************************************************************/typedef unsigned char BOOLEAN;typedef unsigned char INT8U; /* Unsigned 8 bit quantity */ (1)typedef signed char INT8S; /* Signed 8 bit quantity */typedef unsigned int INT16U; /* Unsigned 16 bit quantity */typedef signed int INT16S; /* Signed 16 bit quantity */typedef unsigned long INT32U; /* Unsigned 32 bit quantity */typedef signed long INT32S; /* Signed 32 bit quantity */typedef float FP32; /* Single precision floating point */ (2)typedef double FP64; /* Double precision floating point */typedef unsigned int OS_STK; /* Each stack entry is 16-bit wide *//*********************************************************************************************************** Processor Specifics**********************************************************************************************************/#define OS_ENTER_CRITICAL() ??? /* Disable interrupts */ (3)#define OS_EXIT_CRITICAL() ??? /* Enable interrupts */
#define OS_STK_GROWTH 1 /* Define stack growth: 1 = Down, 0 = Up */ (4) 1 #define#define OS_TASK_SW() ??? (5)
OS_CPU.H
52
OS_Enter_Critical() and OS_Exit_Critical()
Macros voor enable en disable interrupt
Os_Enter_Critcal();
//uC/OS-II kritische code sectie
Os_Exit_Critcal();
#define Os_Enter_Critcal() \asm(“ PUSH PSW”); \asm(“DI”);
#define Os_Exit_Critcal() DIasm(“ POP PSW”); \asm(“EI”);
#define Os_Enter_Critcal() DI#define Os_Exit_Critcal() SEI
53
Voor een uC/OS-II port zullen een aantal eenvoudige C functies moeten worden herschreven
OSTaskStkInit()
Deze functie wordt aangeroepen door o.a. OSTaskCreate() om de stack van een taak te initialiseren.
OS_STK *OSTaskStkInit() (void (*task)(void *pd),void *pdata, OS_STK *ptos, INIT16U opt);
{1. simulate call to function with
an argument(i.e. pdata);2. Simulate ISR vector;3. Setup stack frame to contain desired
initial values of all registers;4. Return new top-of-stack pointer
to caller;
}
void MyTask (void *pdata){ /* Do something with argument pdata’ */ for (;;) { /* Task code */ }}
54
OSTaskStkInit()
Processor Status Word
Interrupt Return Address
LOW MEMORY
HIGH MEMORY
Stack Growth
Saved Processor Registers
'pdata'
Task start address
Stack Pointer
(1)
(2)
(3)
(4)
OS_STK *OSTaskStkInit() (void (*task)(void *pd), void *pdata,
OS_STK *ptos, INIT16U opt);
{simulate call to function with an argument (i.e. pdata);Simulate ISR vector;Setup stack frame to contain desired initial values of all registers;Return new top-of-stack pointer to caller; }
55
Processor Status Word
Interrupt Return Address
LOW MEMORY
HIGH MEMORY
Stack Growth
Saved Processor Registers
'pdata'
Task start address
Stack Pointer
(1)
(2)
(3)
(4)
Stackframe geinitialiseerd met pdata.
56
Context Switch
• Om een ready task running te maken moeten alle processor registers van de task’s stack terug gezet worden en een “return from interrupt” terug gezet worden.
• OS_TASk_SW(): is een macro welke altijd wordt aangeroepen van task-level code. De OS_TASK_SW() moet een interrupt simuleren.Het maakt een software interrupt (in assembler code) en zet de interrupt vector naar de OSCtxSw() (assembler programma)
• OSIntExit() wordt gebruikt bij een context switch wanneer bij een ISR die een taak met een hogere prioriteit laat uitvoeren.
57
Context Switch
OS_CPU_A.ASM•OSStartHighRdy()•OSCtxSw()•OSIntCtxSw()•OSTickISR()
OSStartHighRdy() wordt aangeroepen door OSStart() om de taak met de hoogste prioriteit te laten starten.
Voordat OSStart() aangeroepen kan worden moet minimaal 1 taak gecreëerd zijn.
58
OSTickISR()
uC/OS-II eist een periodieke tijd voor het bijhouden van delays en time-outs
Een ”ticker interrupts” moet geenabled worden nadat de multitasking is gestart, dat gebeurd na het aanroepen van OSStart().
Wanneer de ticker interrupt wordt geenabled voor de aanroeping van OSStart(), kan het systeem crashen.
void main(void){ . OSInit(); /* Initialize µC/OS-II */ . /* Application initialization code ... */ /* ... Create at least on task by calling OSTaskCreate() */ . . Enable TICKER interrupts; /* DO NOT DO THIS HERE!!! */ . . OSStart(); /* Start multitasking */}
59
Pseudocode for tick ISR
void OSTickISR(void){
Save processor registers;Call OSIntEnter() or increment OSIntNesting;if (OSIntNexting == 1){
OSTCBCur->OSTCBStkPtr = Stack Pointer;}clear interrupting device;Call OSTimeTick();Call OSIntExit();Restore processor registers;Execute a return from interrupt instruction;
}
Aangeven dat je in een interrupt zit
Verantwoordelijk voor de interne timers
Save sp in
huidige taak