microc/os-ii structure -...

Post on 26-Mar-2018

234 Views

Category:

Documents

5 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Embedded System Lab. II

MicroCMicroC/OS/OS--II II Structure Structure

경희대학교 컴퓨터공학과

조 진 성

Embedded System Lab. II 1

ContentsContentsIntroductionKernel StructureTask ManagementTime ManagementEvent Control BlockSemaphore ManagementMutual Exclusive SemaphoreEvent Flags ManagementMessage Mail Box ManagementMessage Queue ManagementMemory ManagementMicroC/OS-II Porting

Embedded System Lab. II

IntroductionIntroduction

Embedded System Lab. II 3

MicroC/OS-II 개요1992년 Jean J. Labrosse가만든실시간운영체제학교나개인의교육과같은비상업적목적에한해자유로이사용가능한공개소스로서, 소스코드의수정및커널의내부구조를이해하기용이함.용도 : 각종장비개발이가능공식사이트: http://www.ucos-ii.com(소스다운로드가능)상업적인목적에사용될경우라이센스를따로얻어야함.

IntroductionIntroduction

Embedded System Lab. II 4

MicroC/OS-II는 Multitasking이가능한 Preemptive Real time KernelMicroC/OS-II는태스크를 64개까지관리할수있다.최상위,최하위 4개는예약된우선순위이므로 56개의 Task 사용가능엄격하게관리할수있다면 OS_LOWEST_PRIO를제외하고모든우선순위사용가능하다.

Portable이식성이높은 ANSI-C로작성되었고, 일부프로세서에의존적인부분만어셈블리어로작성됨.8Bit, 16Bit, 32Bit 및 64Bit, DSP로도 Porting할수있다.

Realiable안정-결정적인시스템에사용할수있을정도로강인하고안전한운영체제

FAA(Federal Aviation Administration)에서승인됨.(2000년 7월)

RomableScalable

Introduction (ContIntroduction (Cont’’d)d)

Embedded System Lab. II 5

임베디드운영체제로써대표적인비-상용공개형커널신뢰성과안정성을가진다.작은사이즈 –많은시스템에적용가능작은임베디드시스템에탑재가능하며임베디드시스템중에서도강력한네트워크가필요한곳과높은성능시스템에사용하는것이적합(TCP/IP 스택및 GUI환경라이센스판매)

프로젝트에따른소스코드의절약이가능

스택체크, 처리시간체크, Mailbox, Queue, Semaphore, Memory partition 등의시스템서비스제공

인터럽트관리

태스크의수행을일시중지하거나재개가가능하다.인터럽트중첩(up to 255 levels deep)

단점

초기개발투자와라이센스등의후처리문제로인해마음대로사용하거나배포에어려움이있음

Introduction (ContIntroduction (Cont’’d)d)

Embedded System Lab. II

Kernel StructureKernel Structure

Embedded System Lab. II 7

Kernel StructureKernel StructureuC/OS-II File Structure

Embedded System Lab. II 8

Kernel Structure (ContKernel Structure (Cont’’d)d)

OSVersion()

OS_SCHED_LOCK_ENOSSchedUnlock()

OS_SCHED_LOCK_ENOSSchedLock()

OSIntExit()

OSIntEnter()

OSStart()

OSInit()

OS_EXIT_CRITICAL()

OS_ENTER_CRITICAL()Enabled when set to 1 in OS_CFG.HuC/OS-II 핵심 서비스

Embedded System Lab. II 9

Kernel Structure (ContKernel Structure (Cont’’d)d)Critical Section, OS_ENTER_CRITICAL() & OS_EXIT_CRITICAL()

MicroC/OS-II는 OS_ENTER_CRITICAL()과 OS_EXIT_CRITICAL()라는매크로를 사용하여 Interrupt를 비활성화/활성화한다.OS_ENTER_CRITICAL()과 OS_EXIT_CRITICAL()은 Critical Section을감싸기 위해 항상 다음과 같이 쌍으로 사용한다.

OS_ENTER_CRITICAL()과 OS_EXIT_CRITICAL()은서로다른세가지방법으로구현된다.(OS_CPU.H에정의한 OS_CRITICAL_METHOD상수를통해사용)

1.OS_ENTER_CRITICAL()와 OS_EXIT_CRITICAL()에인터럽트를비활성화/활성화하는프로세서명령을정의하여사용

2.인터럽트비활성화/활성화상태를 Stack에저장하여사용3.프로세서상태워드의값을 C함수안의지역변수에저장하는기능을가진컴파일러를사용할경우

.OS_ENTER_CRITICAL();/* uC/OS-II critical code section */OS_EXIT_CRITICAL();.

Embedded System Lab. II 10

Task – Infinite loop functionMicroC/OS-II는 Task를 64개까지관리할수있다.MicroC/OS-II는 8개의예약된태스크중 Idle, CPU 사용률계산 Task를사용중작은숫자일수록더높은우선순위.(ex. 1 -> 최상위우선순위)Task 우선순위를통해 Task를식별한다.

Kernel Structure (ContKernel Structure (Cont’’d)d)

void YourTask (void *pdata){

for (;;){/* USER CODE */Call one of uC/OS-II’s services:OSFlagPend();OSMboxPend();OSMutexPend();OSQPend();OSSemPend();OSTaskDel(OS_PRIO_SELF);OSTaskSuspend(OS_PRIO_SELF);OSTimeDly();OSTimeDlyHMSM();/* USER CODE */

}}

Embedded System Lab. II 11

Kernel Structure (ContKernel Structure (Cont’’d)d)Task 상태

Embedded System Lab. II 12

Kernel Structure (ContKernel Structure (Cont’’d)d)Task Control Block

Task 생성시각 Task 별로 Task control block인 OS_TCB를할당받는다.OS_TCB는 RAM에상주하면서태스크의상태를관리한다.

주요변수설명

OSTCBStkPtr : Task의스택꼭대기를가리키는포인터.•어셈블리어코드의문맥전환코드부분에서접근하는유일한필드. •맨위에배치하는것이어셈블리언어에서접근하도록하는데좋음.

OSTCBStat : Task의상태, 이값들은 ucos.c에있음OSTCBDly : Task가지연될필요가있을때나일정한 timeout을두고이벤트

발생을기다릴때사용.OSTCBX, OSTCBY, OSTCBBitX, OSTCBBitY : Task가생성되거나우선순위가바뀔때사용

OSTCBNext, OSTCBPrev : OS_TCB를양방향으로링크하는데사용.OSTCBEventPtr : Event control block의포인터

Embedded System Lab. II 13

Task Control Block

Kernel Structure (ContKernel Structure (Cont’’d)d)

typedef struct os_tcb {OS_STK *OSTCBStkPtr; /* Pointer to current top of stack */

#if OS_TASK_CREATE_EXT_EN > 0void *OSTCBExtPtr; /* Pointer to user definable data for TCB */OS_STK *OSTCBStkBottom; /* Pointer to bottom of stack */INT32U OSTCBStkSize; /* Size of task stack (in number of stack) */INT16U OSTCBOpt; /* Task options as passed by OSTaskCreateExt() */INT16U OSTCBId; /* Task ID (0..65535) */

#endif

struct os_tcb *OSTCBNext; /* Pointer to next TCB in the TCB list */ struct os_tcb *OSTCBPrev; /* Pointer to previous TCB in the TCB list */

#if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0) || (OS_SEM_EN > 0) || (OS_MUTEX_EN > 0)

OS_EVENT *OSTCBEventPtr; /* Pointer to event control block */#endif

#if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0)void *OSTCBMsg; /* Message received from OSMboxPost() or OSQPost()

#endif

Embedded System Lab. II 14

Task Control Block

Kernel Structure (ContKernel Structure (Cont’’d)d)

#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)#if OS_TASK_DEL_EN > 0

OS_FLAG_NODE *OSTCBFlagNode; /* Pointer to event flag node */#endif

OS_FLAGS OSTCBFlagsRdy; /* Event flags that made task ready to run */#endif

INT16U OSTCBDly; /* Nbr ticks to delay task or, timeout waiting for eventINT8U OSTCBStat; /* Task status */ INT8U OSTCBPrio; /* Task priority (0 == highest, 63 == lowest)*/

INT8U OSTCBX; /* Bit position in group corresponding to task priority (0..7) */ INT8U OSTCBY; /* Index into ready table corresponding to task priority */INT8U OSTCBBitX; /*Bit mask to access bit position in ready table */INT8U OSTCBBitY; /*Bit mask to access bit position in ready group */

#if OS_TASK_DEL_EN > 0BOOLEAN OSTCBDelReq; /* Indicates whether a task needs to delete */

#endif} OS_TCB;

Embedded System Lab. II 15

Kernel Structure (ContKernel Structure (Cont’’d) d) Task Control Block

OSTCBNext OSTCBNext OSTCBNext

OSTCBList

0[1] 0[2] 0[3]

0[61]

[62]

[63]

.

.

OS_TCB OS_TCB OS_TCB

[0]

OSTCBNext OSTCBNext OSTCBNext

OSTCBFreeListOS_TCB OS_TCB OS_TCB

OSTCBPrev OSTCBPrev OSTCBPrev0

OSTCBCurOSTCBHighRdy가장 높은 우선 순위

현재 실행 중인 타스크

자유 리스트

ptcb지역 변수

OSTCBNextOSTCBNextOSTCBNextOSTCBNext

OSTCBNextOSTCBNextOSTCBNext

Embedded System Lab. II 16

Kernel Structure (ContKernel Structure (Cont’’d)d)Ready List두개의변수 OSRdyGrp과 OSRdyTbl[ ]로 Ready 상태의 Task를관리

현재 ready 상태인 Task를효율적을검색

OSRdyGrpTask의우선순위에의해그룹화한그룹당 8개의우선순위(Task ID)를가짐OSRdyGrp내의각비트는해당그룹의 Ready 여부를표시

OSRdyTbl[ ]지정된우선순위의각태스크가 Ready 인지여부를표시

Embedded System Lab. II 17

Kernel Structure (ContKernel Structure (Cont’’d)d)Ready List

Embedded System Lab. II 18

태스크를준비상태로만들기

준비리스트에서태스크삭제

준비리스트에서최상위우선순위찾기

Kernel Structure (ContKernel Structure (Cont’’d)d)

OSRdyGrp |= OSMapTbl[prio >> 3];OSRdyTbl[prio >> 3] |= OSMapTbl[prio & 0x07];

if((OSRdyTbl[prio>>3] &= ~OSMapTbl[prio & 0x07]) == 0)OSRdyGrp &= ~OSMapTbl[prio >> 3];

y = OSUnMapTbl[OSRdyGrp];x = OSUnMapTbl[OSRdyTbl[y]];prio = (y<<3) + x;

Embedded System Lab. II 19

Kernel Structure (ContKernel Structure (Cont’’d)d)Ready List에서최상위우선순위태스크찾기

Embedded System Lab. II 20

Task SchedulingMicroC/OS-II는준비상태의 Task중항상가장높은우선순위의태스크를실행Task 수준의 Scheduling은 OS_Sched() 함수에의해이뤄진다.ISR 수준의 Scheduling은 OSIntExit() 함수에의해이뤄진다.

Kernel Structure (ContKernel Structure (Cont’’d)d)

void OS_Sched (void){#if OS_CRITICAL_METHOD == 3

OS_CPU_SR cpu_sr;#endif

INT8U y;

OS_ENTER_CRITICAL();if ((OSIntNesting == 0) && (OSLockNesting == 0)) {

y = OSUnMapTbl[OSRdyGrp]; OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);if (OSPrioHighRdy != OSPrioCur) {

OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; OSCtxSwCtr++; OS_TASK_SW();

}}OS_EXIT_CRITICAL();

}

Embedded System Lab. II 21

Kernel Structure (ContKernel Structure (Cont’’d)d)

OS_TASK_SW() 호출할때

Task 레벨 Context Switching

현재 Task 문맥저장

Embedded System Lab. II 22

Kernel Structure (ContKernel Structure (Cont’’d)d)

void OSCtxSw (void){

PUSH R1, R2, R3 and R4 onto the current stack; OSTCBCur->OSTCBStkPtr = SP; OSTCBCur = OSTCBHighRdy;SP = OSTCBHighRdy->OSTCBStkPtr; POP R4, R3, R2 and R1 from the new stack; Execute a return from interrupt instruction;

}

현재 Task 재실행

Embedded System Lab. II 23

Scheduler 잠그기/풀기OSSchedLock()과 OSSchedUnlock()함수를이용하여 Scheduler를잠그고푼다.MicroC/OS-II는 255단계까지 Scheduling 잠금을지원한다.OSLockNesting이 0이될때 Scheduler가풀린다.

Kernel Structure (ContKernel Structure (Cont’’d)d)

void OSSchedLock (void){#if OS_CRITICAL_METHOD == 3

OS_CPU_SR cpu_sr;#endif

if (OSRunning == TRUE) { OS_ENTER_CRITICAL();if (OSLockNesting < 255) {

OSLockNesting++;}OS_EXIT_CRITICAL();

}}

Embedded System Lab. II 24

Scheduler 잠그기/풀기

Kernel Structure (ContKernel Structure (Cont’’d)d)

void OSSchedUnlock (void){#if OS_CRITICAL_METHOD == 3

OS_CPU_SR cpu_sr;#endif

if (OSRunning == TRUE) { OS_ENTER_CRITICAL();if (OSLockNesting > 0) {

OSLockNesting--; if ((OSLockNesting == 0) && (OSIntNesting == 0)) {

OS_EXIT_CRITICAL();OS_Sched();

} else {OS_EXIT_CRITICAL();

}} else {

OS_EXIT_CRITICAL();}

}}

Embedded System Lab. II 25

Idle Task / OS_TaskIdle() MicroC/OS-II는항상 Idle Task를생성한다.Idle Task는다른 Task가실행하지않을때실행한다.Idle Task는항상최하위우선순위(OS_LOWEST_PRIO)가배정된다.응용프로그램이 Idle Task를삭제할수없다.

Kernel Structure (ContKernel Structure (Cont’’d)d)

void OS_TaskIdle (void *pdata){#if OS_CRITICAL_METHOD == 3

OS_CPU_SR cpu_sr;#endif

pdata = pdata; for (;;) {

OS_ENTER_CRITICAL();OSIdleCtr++; OS_EXIT_CRITICAL();OSTaskIdleHook();

}}

Embedded System Lab. II 26

통계 Task / OS_TaskStat() MicroC/OS-II는실행통계를내주는태스크를포함하고있다.OS_CFG.H에있는 OS_TASK_STAT_EN 설정상수를 1로설정하면 Task가생성통계 Task는 CPU 사용률을 1초마다 %로계산한다.통계 Task를사용한다면시스템초기화시처음으로생성된 Task에서통계 Task를호출하도록해야한다.

Kernel Structure (ContKernel Structure (Cont’’d)d)

void main (void){

OSInit(); /* Initialize uC/OS-II *//* Install uC/OS-II's context switch vector *//* Create your startup task (for sake of discussion, TaskStart()) */OSStart(); /* Start multitasking */

}

void TaskStart (void *pdata){

/* Install and initialize uC/OS-II’s ticker */OSStatInit(); /* Initialize statistics task *//* Create your application task(s) */for (;;) {

/* Code for TaskStart() goes here! */}

}

Embedded System Lab. II 27

통계 Task

Kernel Structure (ContKernel Structure (Cont’’d)d)

Embedded System Lab. II 28

통계 Task 초기화 / OSStatInit() OSStatInit()은 Idle Task외에아무태스크도실행되지않는상태에서Idle 카운터(OSIdleCtr) 값을얼마나증가할수있는지알아내는일을한다.

Kernel Structure (ContKernel Structure (Cont’’d)d)

void OSStatInit (void){#if OS_CRITICAL_METHOD == 3

OS_CPU_SR cpu_sr;#endif

OSTimeDly(2); OS_ENTER_CRITICAL();OSIdleCtr = 0L; OS_EXIT_CRITICAL();OSTimeDly(OS_TICKS_PER_SEC); OS_ENTER_CRITICAL();OSIdleCtrMax = OSIdleCtr; OSStatRdy = TRUE;OS_EXIT_CRITICAL();

}

Embedded System Lab. II 29

통계 Task

Kernel Structure (ContKernel Structure (Cont’’d)d)

void OS_TaskStat (void *pdata){#if OS_CRITICAL_METHOD == 3

OS_CPU_SR cpu_sr;#endif

INT32U run;INT32U max;INT8S usage;

pdata = pdata; while (OSStatRdy == FALSE){

OSTimeDly(2 * OS_TICKS_PER_SEC);

}max = OSIdleCtrMax / 100L;

for (;;) {OS_ENTER_CRITICAL();OSIdleCtrRun = OSIdleCtr; run = OSIdleCtr;OSIdleCtr = 0L; OS_EXIT_CRITICAL();if (max > 0L) {

usage = (INT8S)(100L - run / max); if (usage >= 0) {

OSCPUUsage = usage;} else {

OSCPUUsage = 0;}

} else {OSCPUUsage = 0;max = OSIdleCtrMax / 100L;

}OSTaskStatHook(); OSTimeDly(OS_TICKS_PER_SEC);

}}

Embedded System Lab. II 30

MicroC/OS-II의 InterruptMicroC/OS-II에서는어셈블리로 Interrupt Service Routine (ISR)을작성해야하나 C컴파일러가 Inline 어셈블러를지원한다면 C소스코드에 ISR을작성해도된다.Interrupt 관련함수

OSIntEnter(), OSIntExit(), OSIntCtxSW()

Kernel Structure (ContKernel Structure (Cont’’d)d)

YourISR:Save all CPU registers; Call OSIntEnter() or, increment OSIntNesting directly; if (OSIntNesting == 1) {

OSTCBCur->OSTCBStkPtr = SP; }Clear interrupting device; Re-enable interrupts (optional) Execute user code to service ISR; Call OSIntExit(); Restore all CPU registers; Execute a return from interrupt instruction;

의사코드

Embedded System Lab. II 31

MicroC/OS-II의 Interrupt

Kernel Structure (ContKernel Structure (Cont’’d)d)

Embedded System Lab. II 32

Clock Tick / OSTimeTick() MicroC/OS-II에서타임아웃기능과시간지연기능등을위해 Clock Tick을사용Multitasking을시작한뒤즉반드시 OSStart()를호출한뒤에 Clock Tick Interrupt를활성화해야한다.Clock Tick 관련함수

OSTimeTick(), OSTickISR()

Kernel Structure (ContKernel Structure (Cont’’d)d)

void OSTickISR(void){

Save processor registers;Call OSIntEnter() or increment OSIntNesting;if (OSIntNesting == 1) {

OSTCBCur->OSTCBStkPtr = SP;}

Post a 'dummy' message (e.g. (void *)1) to the tick mailbox;

Call OSIntExit();Restore processor registers;Execute a return from interrupt instruction;

}

Embedded System Lab. II 33

MicroC/OS-II 초기화MicroC/OS-II의시스템서비스를사용하기위해서는가장먼저 OSInit()를호출다음장의그림은 OSInit()을호출해서초기화한 MicroC/OS-II의모든변수와자료구조를나타내고있고 OS_CFG.H에있는 #define상수를다음과같이설정했다고가정한다.

OS_TASK_STAT_EN을 1로설정OS_FLAG_EN을 1로설정OS_LOWEST_PRIO를 63으로설정OS_MAX_TASKS를 62로설정

Kernel Structure (ContKernel Structure (Cont’’d)d)

Embedded System Lab. II 34

MicroC/OS-II 초기화

Kernel Structure (ContKernel Structure (Cont’’d)d)

Embedded System Lab. II 35

MicroC/OS-II 초기화

Kernel Structure (ContKernel Structure (Cont’’d)d)

Embedded System Lab. II 36

MicroC/OS-II 시작

Kernel Structure (ContKernel Structure (Cont’’d)d)

void main (void){

OSInit(); /* Initialize uC/OS-II */..Create at least 1 task using either OSTaskCreate() or OSTaskCreateExt();..OSStart(); /* Start multitasking! OSStart() will not return */

}

void OSStart (void){

INT8U y;INT8U x;if (OSRunning == FALSE) {

y = OSUnMapTbl[OSRdyGrp];x = OSUnMapTbl[OSRdyTbl[y]];OSPrioHighRdy = (INT8U)((y << 3) + x);OSPrioCur = OSPrioHighRdy;OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; OSTCBCur = OSTCBHighRdy;OSStartHighRdy();

}}

Embedded System Lab. II 37

MicroC/OS-II 시작

Kernel Structure (ContKernel Structure (Cont’’d)d)

Embedded System Lab. II

Task ManagementTask Management

Embedded System Lab. II 39

Task ManagementTask ManagementTask Management

Task는일반적으로그형태가무한루프함수이거나작업이끝나면스스로를삭제하는형태를갖는함수이다. 이때, 태스크의코드를메모리에서삭제하는것은아니다.

void YourTask (void *pdata) {

for (;;) { /* USER CODE */ Call one of uC/OS-II's services:

OSFlagPend();OSMboxPend();OSMutexPend();OSQPend();OSSemPend();

OSTaskSuspend(OS_PRIO_SELF); OSTimeDly();OSTimeDlyHMSM();

/* USER CODE */}

}

void YourTask (void *pdata){

/* USER CODE */ OSTaskDel(OS_PRIO_SELF);

}

Embedded System Lab. II 40

Task Management (ContTask Management (Cont’’d)d)Task 생성 / OSTaskCreate() or OSTaskCreateExt()

Task는 Multitasking을시작하기전에초기화코드에서생성하거나,Multitasking을시작한뒤실행중인다른태스크가생성할수도있다.Multitasking을시작하기전 (OSStart() 호출이전), 최소한하나이상의Task를생성해야만한다.참고) Interrupt Service Routine내에서는 Task를생성할수없다.OSTaskCreate( void (*task) (void *pd), void *pdata, OS_STK *ptos, INT8U prio )첫번째전달인자: 생성하고자하는 Task의시작번지두번째전달인자: 생성하려는 Task로넘겨줄전달인자세번째전달인자: 생성하고자하는 Task에할당한 Stack사용시작번지네번째전달인자: Task의우선순위

OSTaskCreateExt() 함수는전달인자가 9개이며, 이는참고서적을통해서확인해보기바란다.

Embedded System Lab. II 41

Task Management (ContTask Management (Cont’’d)d)Task 생성 / OSTaskCreate() or OSTaskCreateExt()

INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio){#if OS_CRITICAL_METHOD == 3

OS_CPU_SR cpu_sr;#endif

void *psp;INT8U err;

#if OS_ARG_CHK_EN > 0if (prio > OS_LOWEST_PRIO) {

return (OS_PRIO_INVALID);}

#endif

OS_ENTER_CRITICAL();if (OSTCBPrioTbl[prio] == (OS_TCB *)0) {

OSTCBPrioTbl[prio] = (OS_TCB *)1; OS_EXIT_CRITICAL(); psp = (void *)OSTaskStkInit(task, pdata, ptos, 0); err = OS_TCBInit(prio, psp, (void *)0, 0, 0, (void *)0, 0); if (err == OS_NO_ERR) {

OS_ENTER_CRITICAL();OSTaskCtr++; OS_EXIT_CRITICAL();if (OSRunning == TRUE) {

OS_Sched(); }

} else {OS_ENTER_CRITICAL();OSTCBPrioTbl[prio] = (OS_TCB *)0; OS_EXIT_CRITICAL();

}return (err);

}OS_EXIT_CRITICAL();return (OS_PRIO_EXIST);

}

Embedded System Lab. II 42

Task Management (ContTask Management (Cont’’d)d)Task Stack각 Task는고유한 Stack공간이있어야하며, 이는 OS_STK타입으로정의하며연속된메모리공간을확보해야한다.Stack을위한공간은정적으로(컴파일할때) 할당하거나동적으로 (실행시)할당할수있다.

static OS_STK MyTaskStack[stack_size];OS_STK MyTaskStack[stack_size];

OS_STK *pstk;pstk = (OS_STK *)malloc(stack_size);if (pstk != (OS_STK *)0) { /* Make sure malloc() has enough space */

Create the task;}

Static Stack

Using malloc() to allocate stack space for a task

Embedded System Lab. II 43

Task Management (ContTask Management (Cont’’d)d)Task Stack

Stack을위한공간은 C컴파일러의 malloc()함수를사용해서동적으로할당할수있지만메모리단편화(Fragmentation)현상이발생할수있음으로유의

Free heap

(3Kb)

A (1Kb)

B (1Kb)

C (1Kb)

Free(1Kb)

B (1Kb)

Free(1Kb)

할당전 할당후 A, C 반환후(단편화발생)

Embedded System Lab. II 44

Task Management (ContTask Management (Cont’’d)d)Task Stack 사용방향

스택을하위메모리서상위매모리순서로쓸경우(OS_STK_GROWTH = 0)OS_STK TaskStk[TASK_STK_SIZE];OSTaskCreate(task, pdata, &TaskStk[0], prio);

스택을상위메모리서하위메모리순서로쓸경우(OS_STK_GROWTH = 1)OS_STK TaskStk[TASK_STK_SIZE];OSTaskCreate(task, pdata, &TaskStk[TASK_STK_SIZE-1], prio);

상, 하향방식스택을모두지원하는코드OS_STK TaskStk[TASK_STK_SIZE];#if OS_STK_GROWTH == 0

OSTaskCreate(task, pdata, &TaskStk[0], prio);#else

OSTaskCreate(task, pdata, &TaskStk[TASK_STK_SIZE-1], prio);#endif

Embedded System Lab. II 45

Task Management (ContTask Management (Cont’’d)d)Stack 점검 / OSTaskStkChk()

Task에서실제로얼마만큼의 Stack공간을사용하는지검사검사결과를바탕으로 Stack공간에필요이상의메모리를할당하는것을방지전달인자

prio : 태스크우선순위pdata : OS_STK_DATA 타입의구조체를가리키는포인터.

스택에서사용한바이트수, 사용하지않는바이트수(uCOS_II.H참조)

Embedded System Lab. II 46

Task Management (ContTask Management (Cont’’d)d)Stack 점검 / OSTaskStkChk()

Embedded System Lab. II 47

Task Management (ContTask Management (Cont’’d)d)Task 삭제요청 / OSTaskDelReq()공유자원을소유하고있는 Task로하여금자원을반환하고, 스스로를삭제하도록알려주는방식의함수

Task 삭제를요청하는함수와삭제되는함수양쪽에서모두 OSTaskDelReq()함수를호출해야한다.전달인자

prio : 삭제요구를하기위한우선순위void RequestorTask (void *pdata){

INT8U err;pdata = pdata;for (;;) {

/* Application code */if ('TaskToBeDeleted()' needs to be deleted) {

while (OSTaskDelReq(TASK_TO_DEL_PRIO) != OS_TASK_NOT_EXIST) { OSTimeDly(1);

}}/* Application code */

}}

Task를스스로삭제하도록요청하는코드

Embedded System Lab. II 48

Task Management (ContTask Management (Cont’’d)d)Task 삭제요청 / OSTaskDelReq()

OSTaskDel() 실행과정조건검사 : Idle Task 삭제시도여부, 삭제태스크의존재여부OS_TCB 삭제

• Ready list 로부터삭제• MailBox, Queue, Semaphore에대기중인 OS_TCB 삭제

지연카운트를 0으로설정 : Task가인터럽트재개시까지 tick ISR이준비되지않게하기위해

OSTCBStat플래그를 OS_STAT_RDY로설정사용자정의확장 TCB를반납 OSTaskDelHook()Task 카운터감소OS_TCB 삭제

•우선순위테이블에서삭제• OSTCBList에서시작하는 OS_TCB리스트에서삭제• free OS_TCB list로 OS_TCB 반환

스케줄러를호출 : OSTaskDel() 실행중 ISR에의해생성된높은우선순위의태스크가있을시

Embedded System Lab. II 49

Task Management (ContTask Management (Cont’’d)d)Task 삭제요청 / OSTaskDelReq()

자신을삭제하도록요청하는 Task

void TaskToBeDeleted (void *pdata){

INT8U err;pdata = pdata;for (;;) {

/* Application code */if (OSTaskDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ) {

Release any owned resources; De-allocate any dynamic memory;OSTaskDel(OS_PRIO_SELF);

} else {/* Application code */

}}

}

Embedded System Lab. II 50

Task Management (ContTask Management (Cont’’d)d)Task 우선순위변경 / OSTaskChangePrio()우선순위를 Run Time시에이함수를이용하여동적으로변경할수있다.주의) 새로 지정한 우선순위를 이미 사용하고 있지 않아야 한다.

전달인자Oldprio: 이전 우선순위Newprio: 새로 지정하는 우선순위

우선순위변화과정

Task가실행준비가되면 ready list에서제거되고 Task가새우선순위를할당받으면 ready list에놓여진다.Task가실행준비가되지않으면태스크는새우선순위에서실행될준비가되지않는다.Task가이벤트발생을기다리면태스크는 event waiting list에서제거되고새우선순위의 waiting list에놓여진다.Task가 OS_TCB 체인에서제거되어새우선순위를받는동안 OSTimeTick()에의하여태스크가실행준비가되는것을방지한다.인터럽트가 enabled면 OS_TCB의 OSTCBX, OSTCBBitX, OSTCBY, OSTCBBitY가재계산된다.

Embedded System Lab. II 51

Task Management (ContTask Management (Cont’’d)d)Task 일시중단 / OSTaskSuspend()태스크를 일시 중단하는 함수.

주의) 이 함수에 의해 중단된 태스크는 OSTaskResume 함수를 통해서만중단상태에서 빠져 나올 수 있다.

주의) 이벤트(메시지, 세마포어, 큐 등)를 대기중인 태스크에 대해 이 함수를호출하면 이벤트가 발생했을 경우 처리할 수 없을 것이다.

전달인자prio: 중단하려는 태스크의 우선순위.

OSTaskSuspend() 실행과정해당 Task가 Idle 상태인지검사해당 Task의 priority가유효한지검사해당 Task가존재하면실행 Ready List에서삭제OS_TCB의 OS_STAT_SUSPEND 플래그를설정한다.스케줄러를호출한다.

Embedded System Lab. II 52

Task Management (ContTask Management (Cont’’d)d)Task 일시중단 / OSTaskResume()일시 중단한 태스크를 재실행시킨다.

주의) 일시 중단한 태스크를 재실행할 수 있는 유일한 함수(OSTaskSuspend)

전달인자prio: 재실행하고자하는 태스크의 우선순위.

OSTaskResume() 실행과정해당 Task가 Idle 상태인지검사OSTCBStat필드(OS_TCB)의 OS_STAT_SUSPEND를해제OSTCBDly를 0으로설정 : 시간종료를기다리고있지않은 Task이므로재개된Task가현재 Task보다더높은우선순위를가지면스케줄러를호출한다.

Embedded System Lab. II 53

Task Management (ContTask Management (Cont’’d)d)Task 정보알아내기 / OSTaskQuery()자기 자신이나 다른 응용 Task에 대한 정보를 알아낼 수 있다.해당 태스크의 TCB 사본을 얻어온다.

주의) 복사본의 정보를 사용할 때, 특히 OSTCBNext, OSTCBPrev 같은태스크 컨트롤 블록 내의 링크 포인터가 가르키는 블록을 주의한다.

전달인자prio: 상태를 얻고자 하는 태스크의 우선순위Pdata: 태스크에 대한 상태를 저장할 태스크 구조체

void MyTask (void *pdata){

OS_TCB MyTaskData;

pdata = pdata;for (;;) {

/* User code */err = OSTaskQuery(10, &MyTaskData);/* Examine error code .. *//* User code */

}}

Embedded System Lab. II

Time ManagementTime Management

Embedded System Lab. II 55

Time Management Time Management Time Management

OS_TIME_GET_SET_ENOSTimeSet()

OS_TIME_GET_SET_ENOSTimeGet()

OS_TIME_DLY_RESUME_ENOSTimeDlyResume()

OS_TIME_DLY_HMSM_ENOSTimeDlyHMSM()

OSTimeDly()

Enabled when set to 1 in OS_CFG.HuC/OS-II Time Management Service

Time management configuration constants in OS_CFG.H.

Embedded System Lab. II 56

Time Management (ContTime Management (Cont’’d)d)Task 지연 / OSTimeDly()사용자가지정한 Clock tick(1~65535) 동안태스크를지연할수있는기능을제공한다.실행중이던태스크다음으로우선순위가높은태스크를실행

지정시간이끝나거나 OSTimeDlyResume()함수가호출시준비상태가된다.전달인자

Ticks: 지연 Clock tick

Embedded System Lab. II 57

Time Management (ContTime Management (Cont’’d)d)Task 지연 / OSTimeDly()

Embedded System Lab. II 58

Time Management (ContTime Management (Cont’’d)d)Task 지연 / OSTimeDlyHMSM()시간을틱단위가아닌시(H), 분(M), 초(S), 그리고밀리초(m) 단위로지정할수있다.uC/OS-II에서는최대 256시간까지지연이가능. OS_TIME_DLY_HMSM_EN == 1 일경우사용가능. (OS_CFG.H)전달인자

Hours: 지연할시간Minutes: 지연할분Seconds: 지연할초Milli: 지연할밀리초

Embedded System Lab. II 59

Time Management (ContTime Management (Cont’’d)d)지연된 Task의재개 / OSTimeDlyResume()지연하고있는 Task를재개하는기능을제공지정된지연시간이만료되는것말고, 다른 Task가시간지연을취소해서지연중인 Task를다시준비상태로만든다. 이함수는 65,535틱이상의시간지연을재개할수없다. 지연시간이끝나기를기다려야한다.OS_TIME_DLY_RESUME_EN == 1 일때사용가능전달인자

prio: 재개할 Taks의우선순위

Embedded System Lab. II 60

Time Management (ContTime Management (Cont’’d)d)시스템시간 / OSTimeGet(), OSTimeSet()

MicroC/OS-II는 Clock Tick Interrupt가발생할때마다 32bit 카운터값을증가카운터값은처음 OSStart()함수를호출해서멀티캐스팅을시작할때 0으로초기화되어증가하기시작하고, 4,294,967,295 Tick이후에다시 0이된다.OSTimeGet(): 카운터의현재값을가져온다. OSTimeSet(): 카운터의값을바꾼다.

Embedded System Lab. II

Event Control BlockEvent Control Block

Embedded System Lab. II 62

Event Control BlockEvent Control BlockEvent Control Block

Task 와 ISR은 Event Control Block(ECB) 이라는 Kernel Object를사용해서Task로신호를보낸다.

Embedded System Lab. II 63

Event Control Block (ContEvent Control Block (Cont’’d)d)

typedef struct {INT8U OSEventType; /* Event type */INT8U OSEventGrp; /* Group for wait list */INT16U OSEventCnt; /* Count (when event is a semaphore) */void *OSEventPtr; /* Ptr to message or queue structure */INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; /* Wait list for event to occur */

} OS_EVENT;

Event Control Block Structure

Embedded System Lab. II 64

Event Control Block (ContEvent Control Block (Cont’’d)d)Wait List

Embedded System Lab. II 65

Event Control Block (ContEvent Control Block (Cont’’d)d)Wait List Operation

pevent->OSEventGrp |= OSMapTbl[prio >> 3];pevent->OSEventTbl[prio >> 3] |= OSMapTbl[prio & 0x07];

Making a task wait for an event.

if ((pevent->OSEventTbl[prio >> 3] &= ~OSMapTbl[prio & 0x07]) == 0) {pevent->OSEventGrp &= ~OSMapTbl[prio >> 3];

}

Removing a task from a wait list.

y = OSUnMapTbl[pevent->OSEventGrp]; x = OSUnMapTbl[pevent->OSEventTbl[y]]; prio = (y << 3) + x;

Finding the highest priority task waiting for the event.

Embedded System Lab. II 66

Event Control Block (ContEvent Control Block (Cont’’d)d)Wait List Example

Embedded System Lab. II 67

Event Control Block (ContEvent Control Block (Cont’’d)d)List of Free ECBs

Embedded System Lab. II 68

Event Control Block (ContEvent Control Block (Cont’’d)d)Event Control Block 초기화 / OS_EventWaitListInit()

Semaphore, Mutex, Mailbox, Message Queue를생성할때공통적으로호출하는함수이다.이함수는해당 Event Control Block에대기하고있는 Task가하나도없도록해준다.

void OS_EventWaitListInit (OS_EVENT *pevent){

INT8U *ptbl;

pevent->OSEventGrp = 0x00;ptbl = &pevent->OSEventTbl[0];

#if OS_EVENT_TBL_SIZE > 0*ptbl++ = 0x00;

#endif#if OS_EVENT_TBL_SIZE > 1

*ptbl++ = 0x00;#endif#if OS_EVENT_TBL_SIZE > 2

*ptbl++ = 0x00;#endif

#if OS_EVENT_TBL_SIZE > 3*ptbl++ = 0x00;

#endif#if OS_EVENT_TBL_SIZE > 4

*ptbl++ = 0x00;#endif#if OS_EVENT_TBL_SIZE > 5

*ptbl++ = 0x00;#endif#if OS_EVENT_TBL_SIZE > 6

*ptbl++ = 0x00;#endif#if OS_EVENT_TBL_SIZE > 7

*ptbl = 0x00;#endif}

Embedded System Lab. II 69

Event Control Block (ContEvent Control Block (Cont’’d)d)Task를준비상태로만들기 / OS_EventTaskRdy()이함수는 Event Control Block에대기중인 Task 중에서가장우선순위가높은 Task를준비상태로만드는것이다.

Task를이벤트대기상태로만들기 / OS_EventTaskWait()이함수는현재 Task를 MicroC/OS-II의준비리스트에서삭제하고, 해당Event Control Block의대기리스트에삽입한다.

타임아웃으로 Task를준비상태로만들기 / OS_EventTO()지정된시간안에이벤트를받지못한경우에호출하는것이다.OSTimeTick()이 Task를준비상태로만들경우, OSSemPend(), OSMboxPend(), OSQPend() 함수에서호출한다.

Embedded System Lab. II

Semaphore ManagementSemaphore Management

Embedded System Lab. II 71

Semaphore Management Semaphore Management Semaphore Management

OS_SEM_QUERY_ENOSSemQuery()

OSSemPost()

OSSemPend()

OS_SEM_DEL_ENOSSemDel()

OSSemCreate()

OS_SEM_ACCEPT_ENOSSemAccept()

Enabled when set to 1 in OS_CFG.HuC/OS-II Semaphore Service

Semaphore configuration constants in OS_CFG.H

Embedded System Lab. II 72

Semaphore Management (ContSemaphore Management (Cont’’d)d)Task, ISR, Semaphore의관계

Embedded System Lab. II 73

Semaphore Management (ContSemaphore Management (Cont’’d)d)Semaphore 생성 / OSSemCreate()이함수를사용하여 Semaphore를생성할수있는데, 생성시 0 ~ 65535사이의 Semaphore 초기값을지정해야한다.이벤트가발생한것을알려주는목적으로 Semaphore를사용할경우Semaphore의초기값을 0을지정한다.공유자원에대한액세스를제어할목적으로사용할경우 Semaphore 의초기값을 1을준다.전달인자

cnt: Semaphore를사용하기위해초기화할값

Embedded System Lab. II 74

Semaphore Management (ContSemaphore Management (Cont’’d)d)OSSemCreate()이리턴하기직전의 ECB

Embedded System Lab. II 75

Semaphore Management (ContSemaphore Management (Cont’’d)d)Semaphore 삭제 / OSSemDel()

Semaphore를삭제하려면그 Semaphore를액세스할수있는모든 Task를먼저삭제해야할것이다.

Semaphore 대기 / OSSemPend()Semaphore를기다리는함수이다.전달인자

Pevent: 해당 Semaphore의 ECB을가리키는포인터.Timeout: 옵션타임아웃기간(Clock Tick 단위). Err: 에러코드를저장할메모리를가리키는포인터.

Embedded System Lab. II 76

Semaphore Management (ContSemaphore Management (Cont’’d)d)Semaphore 반환 / OSSemPost()

Semaphore를반환하는함수이다.전달인자

Pevent: 해당 Semaphore의 ECB을가리키는포인터.

대기없이 Semaphore 얻기 / OSSemAccept()Semaphore가가용하지않을경우 Task를대기하지않도록하면서Semaphore를얻을수있도록하는함수전달인자

Pevent: 해당 Semaphore의 ECB을가리키는포인터

Embedded System Lab. II 77

Semaphore Management (ContSemaphore Management (Cont’’d)d)Semaphore 상태얻기 / OSSemQuery()

Semaphore로사용하는 ECB의현재상태를얻을수있도록한다.전달인자

Pevent: 해당 Semaphore의 ECB을가리키는포인터Pdata: Semaphore에대한정보를저장할구조체를가리키는포인터

Embedded System Lab. II

Mutual Exclusive SemaphoreMutual Exclusive Semaphore

Embedded System Lab. II 79

Mutual Exclusive SemaphoreMutual Exclusive SemaphoreMutual Exclusive Semaphore

Task가자원에대한독점적인액세스를얻고자할때사용한다.Mutex는 MicroC/OS-II가일반적으로제공하는 Semaphore 메커니즘에부가적인기능을추가한 Binary Semaphore이다.우선순위전도문제를줄이기위해사용

OS_MUTEX_QUERY_ENOSMutexQuery()

OSMutexPost()

OSMutexPend()

OS_MUTEX_DEL_ENOSMutexDel()

OSMutexCreate()

OS_MUTEX_ACCEPT_ENOSMutexAccept()

Enabled when set to 1 in OS_CFG.HuC/OS-II Mutex Service

Mutex configuration constants in OS_CFG.H

Embedded System Lab. II

Event Flags ManagementEvent Flags Management

Embedded System Lab. II 81

Event Flags ManagementEvent Flags ManagementEvent Flags Management

Event Flags는 2 가지요소로구성된다.그룹의현재이벤트상태를나타내는비트열

이벤트상태를나타내는비트가켜지거나꺼지기를기다리는 Task들의리스트Event Flags는 Task를여러개의이벤트발생에대해동기화할필요가있을때사용

OS_FLAG_QUERY_ENOSFlagQuery()

OSFlagPost()

OSFlagPend()

OS_FLAG_DEL_ENOSFlagDel()

OSFlagCreate()

OS_FLAG_ACCEPT_ENOSFlagAccept()

Enabled when set to 1 in OS_CFG.HuC/OS-II Event Flags Service

Event Flags configuration constants in OS_CFG.H

Embedded System Lab. II 82

Event Flags Management (ContEvent Flags Management (Cont’’d)d)Event Flags Service

태스크

ISR

태스크

ISR

OSFlagCreat( )OSFlagDel( )OSFlagPost( )

OSFlagAccept( )OSFlagPend( )OSFlagQuery( )

OSFlagPost( ) OSFlagAccept( )OSFlagQuery( )

Embedded System Lab. II 83

Event Flags Management (ContEvent Flags Management (Cont’’d)d)Event Flags의내부

typedef struct { /* Event Flag Group */INT8U OSFlagType; /* Should be set to OS_EVENT_TYPE_FLAG */void *OSFlagWaitList; /* Pointer to first NODE of task waiting on event flag*/OS_FLAGS OSFlagFlags; /* 8, 16 or 32 bit flags */

} OS_FLAG_GRP;

Event Flags Group Structure

typedef struct { /* Event Flag Wait List Node */void *OSFlagNodeNext; /* Pointer to next NODE in wait list */void *OSFlagNodePrev; /* Pointer to previous NODE in wait list */void *OSFlagNodeTCB; /* Pointer to TCB of waiting task */ void *OSFlagNodeFlagGrp; /* Pointer to Event Flag Group */ OS_FLAGS OSFlagNodeFlags; /* Event flag to wait on */ INT8U OSFlagNodeWaitType; /* Type of wait: */

} OS_FLAG_NODE;

Event Flags Group Node Structure

Embedded System Lab. II 84

Event Flags Management (ContEvent Flags Management (Cont’’d)d)Event Flags Group, Event Flags Node, TCB 사이의관계

OS_EVENT_TYPE_FLAG

AND 또는 OR

NULL

AND 또는 OR

NULL

OS_FLAG_NODEOS_FLAG_GRP

Embedded System Lab. II 85

Event Flags Management (ContEvent Flags Management (Cont’’d)d)Event Flags Group 생성 / OSFlagsCreate()

Event Flags Group을생성한다.

Event Flags Group 삭제 / OSFlagsDel()Event Flags Group을삭제한다.

Event 대기 / OSFlagPend()Event Flags Group에서특정이벤트를기다린다.

Event Flags Group에있는이벤트켜고끄기 / OSFlagPost()Event Flags Group에있는비트를켜고끈다.

Event Flags Group 정보얻기 / OSFlagQuery()Event Flags Group의현재값을얻을수있다.

Embedded System Lab. II

Message MailboxMessage Mailbox

Embedded System Lab. II 87

Message Mailbox ManagementMessage Mailbox ManagementMessage Mailbox

Message Mailbox는 MicroC/OS-II에서제공하는 Kernel Object로써, Task또는 ISR에서다른 Task로포인터변수를전송하는역할을한다.

OS_MBOX_QUERY_ENOSMboxQuery()

OS_MBOX_POST_OPT_ENOSMboxPostOpt()

OS_MBOX_POST_ENOSMboxPost()

OSMboxPend()

OS_MBOX_DEL_ENOSMboxDel()

OSMboxCreate()

OS_MBOX_ACCEPT_ENOSMboxAccept()

Enabled when set to 1 in OS_CFG.HMicroC/OS-II Mail Box Service

Mailbox configuration constants in OS_CFG.H

Embedded System Lab. II 88

Message Mailbox Management (ContMessage Mailbox Management (Cont’’d)d)Task, ISR, Mailbox 사이의관계

Embedded System Lab. II 89

Message Mailbox Management (ContMessage Mailbox Management (Cont’’d)d)Mailbox 생성 / OSMboxCreate()이벤트의발생을알리는목적으로 Mailbox를사용할경우, Mailbox를NULL 포인터로초기화해야한다.공유자원액세스제어의목적으로사용하고자할때는 NULL이아닌값으로Mailbox를초기화한다.전달인자

Msg: Mailbox에송부하고자하는메시지에대한포인터

Embedded System Lab. II 90

Message Mailbox Management (ContMessage Mailbox Management (Cont’’d)d)OSMboxCreate()이리턴하기직전의 ECB

Embedded System Lab. II 91

Message Mailbox Management (ContMessage Mailbox Management (Cont’’d)d)Mailbox 삭제 / OSMboxDel()

Mailbox를삭제하려면그 Mailbox를액세스할수있는모든 Task를먼저삭제해야할것이다.

Mailbox에서메시지대기 / OSMboxPend()Mailbox에메시지가도착하기를기다린다.전달인자

Pevent: 해당 Mailbox의 ECB에대한포인터Timeout: 옵션타임아웃값(Clock Tick 단위)err: 에러코드를저장할메모리를가리키는포인터

Embedded System Lab. II 92

Message Mailbox Management (ContMessage Mailbox Management (Cont’’d)d)Mailbox로메시지보내기 / OSMboxPost()

Mailbox로메시지를전송한다.전달인자

Pevent: 해당 Mailbox의 ECB에대한포인터Msg: 보내려는메시지에대한포인터

Mailbox로메시지보내기 / OSMboxPostOpt()Mailbox에대기중인모든 Task에게메시지를 Broadcast할수있는기능추가전달인자

Pevent: 해당 Mailbox의 ECB에대한포인터Timeout: 옵션타임아웃값(Clock Tick 단위)

Embedded System Lab. II 93

Message Mailbox Management (ContMessage Mailbox Management (Cont’’d)d)대기없이메시지얻기 / OSMboxAccept()호출 Task를대기상태로만들지않고메시지를받을수있다.전달인자

Pevent: 해당 Mailbox의 ECB에대한포인터

Mailbox의상태얻기 / OSMboxQuery()Mailbox로사용하는 ECB의현재상태를얻을수있다.전달인자

Pevent: 해당 Mailbox의 ECB에대한포인터Pdata: Message Mailbox에대한정보를저장할구조체를가리키는포인터

Embedded System Lab. II

Message Queue MailboxMessage Queue Mailbox

Embedded System Lab. II 95

Message Queue ManagementMessage Queue ManagementMessage Queue

Message Queue는포인터크기의변수를 Task나 ISR에서다른 Task로전달할수있도록하는 Kernel Object이다.이때, 사용하는포인터는일반적으로응용프로그램에서정의하는 ‘메시지’자료형을가르킨다.

OS_Q_QUERY_ENOSQQuery()

OS_Q_POST_OPT_ENOSQPostOpt()

OS_Q_POST_FRONT_ENOSQPostFront()

OS_Q_POST_ENOSQPost()

OSQPend()

OS_Q_FLUSH_ENOSQFlush()

OS_Q_DEL_ENOSQDel()

OSQCreate()

OS_Q_ACCEPT_ENOSQAccept()

Enabled when set to 1 in OS_CFG.HuC/OS-II Event Flag Service

Message queue configuration constants in OS_CFG.H.

Embedded System Lab. II 96

Message Queue Management (ContMessage Queue Management (Cont’’d)d)Task, ISR, Message Queue의관계

Embedded System Lab. II 97

Message Queue Management (ContMessage Queue Management (Cont’’d)d)Message Queue Structure

Embedded System Lab. II 98

Message Queue Management (ContMessage Queue Management (Cont’’d)d)List of free queue control blocks

Embedded System Lab. II 99

Message Queue Management (ContMessage Queue Management (Cont’’d)d)A message queue as a circular buffer of pointers

Embedded System Lab. II 100

Message Queue Management (ContMessage Queue Management (Cont’’d)d)Message Queue 생성 / OSQCreate()

Message Queue를생성할경우, 먼저 Message Queue가메시지를보관하는데사용할메모리를할당한뒤 OSQCreate()함수에넘겨줘야한다.전달인자

Start: 큐에서메시지저장영역의기준어드레스를가리키는포인터저장영역은다음과같이 void형포인터의배열로선언해야한다.void *MessageStorage[size]

Size: 저장영역의요소수

Message Queue 삭제 / OSQDel ()Message Queue를삭제할경우, 그 Message Queue를액세스할수있는모든 Task를먼저삭제해야할것이다.

Embedded System Lab. II 101

Message Queue Management (ContMessage Queue Management (Cont’’d)d)Message Queue 대기 / OSQPend()

Message Queue에메시지가도착하기를기다린다.전달인자

Pevent: 해당큐의 ECB을가리키는포인터Timeout: 옵션타임아웃기간(Clock Tick 단위)Err: 에러코드를저장할메모리를가리키는포인터

FIFO방식으로큐에메시지보내기 / OSQPost()FIFO방식으로 Message Queue에메시지를넣는다.전달인자

Pevent: 해당큐의 ECB을가리키는포인터Msg: 전송할메시지를가리키는포인터. NULL을지정하면안된다.

Embedded System Lab. II 102

Message Queue Management (ContMessage Queue Management (Cont’’d)d)LIFO방식으로큐에메시지보내기 / OSQPostFront()

LIFO방식으로 Message Queue에메시지를넣는다.전달인자

Pevent: 해당큐의 ECB을가리키는포인터Msg: 전송할메시지를가리키는포인터. NULL을지정하면안된다.

FIFO 또는 LIFO방식으로큐에메시지보내기 / OSQPostOpt()OSQPostOpt()는 OSQPost() 와 OSQPostFront() 를하나로대치할수있는함수이다.이함수는큐에대기중인모든 Task로메시지를 Broadcast할수있다.

Embedded System Lab. II 103

Message Queue Management (ContMessage Queue Management (Cont’’d)d)대기없이큐에서메시지얻기 / OSQAccept()큐에서메시지를받을수있다.OSQPend()와큐가비어있는경우라도 Task를대기상태로만들지않는것이다르다.전달인자

Pevent: 해당큐의 ECB을가리키는포인터

Message Queue 비우기 / OSQFlush()Message Queue안의메시지를모두버리고, 막생성된큐상태로만든다.

Message Queue의상태얻기 / OSQQuery()Message Queue의현재상태를가져올수있도록한다.전달인자

Pevent: 해당큐의 ECB을가리키는포인터Pdata: Message Queue에대한정보를저장할구조체를가리키는포인터

Embedded System Lab. II 104

Message Queue Management (ContMessage Queue Management (Cont’’d)d)아날로그입력을읽기위해 Message Queue 사용

Embedded System Lab. II

Memory ManagementMemory Management

Embedded System Lab. II 106

Memory ManagementMemory ManagementMemory Management응용프로그램에서동적으로메모리를할당하고해제하는데 malloc()과free()함수를사용할수있다.그러나이는메모리단편화현상을초래한다.MicroC/OS-II에서는 malloc()과 free()함수대신연속된메모리공간으로구성된파티션에서고정크기의메모리블록을할당할수있는다른방법을제공한다.

OS_MEM_QUERY_ENOSMemQuery()

OSMemPut()

OSMemGet()

OSMemCreate()

Enabled when set to 1 in OS_CFG.HuC/OS-II Memory Service

Memory management configuration constants in OS_CFG.H

Embedded System Lab. II 107

Memory Queue Management (ContMemory Queue Management (Cont’’d)d)Memory Control Block

Typedef struct {void *OSMemAddr; // 메모리파티션의처음을가르키는포인터void *OSMemFreeList; // 자유메모리블록리스트를가르키는포인터INT32U OSMemBlkSize; // 각메모리블록의바이트단위크기INT32U OSMemNBlks; // 이파티션에서의총메모리바이트수INT32U OSMemNFree; // 이파티션에서남아있는자유메모리블록수

} OS_MEM;

Memory Control Block Data Structure

Embedded System Lab. II 108

Memory Queue Management (ContMemory Queue Management (Cont’’d)d)Memory Partition

Memory Partition 여러개의 Memory Partition

Embedded System Lab. II 109

Memory Queue Management (ContMemory Queue Management (Cont’’d)d)

Free Memory Control Block List

Embedded System Lab. II 110

Memory Queue Management (ContMemory Queue Management (Cont’’d)d)파티션생성 / OSMemCreate()메모리파티션을생성하는함수

밑의소스는 32바이트블록이 100개있는메모리파티션을생성하는예

OS_MEM *CommTxBuf;INT8U CommTxPart[100][32];void main (void){

INT8U err;OSInit();..CommTxBuf = OSMemCreate(CommTxPart, 100, 32, &err);..OSStart();

}

Embedded System Lab. II 111

Memory Queue Management (ContMemory Queue Management (Cont’’d)d)OSMemCreate()으로생성한메모리파티션

Embedded System Lab. II 112

Memory Queue Management (ContMemory Queue Management (Cont’’d)d)메모리블록할당 / OSMemGet()생성된메모리파티션으로부터메모리블록을할당받는다.전달인자

Pmem: 메모리파티션컨트롤블록을가리키는포인터Err: 에러코드를저장할메모리를가리키는포인터

메모리블록의반환 / OSMemPut()응용프로그램에서메모리블록의사용을마치면처음할당받은파티션으로해당블록을반환해야한다.전달인자

Pmem: 메모리파티션컨트롤블록을가리키는포인터Pblk: 해제하려는메모리블록을가리키는포인터

Embedded System Lab. II 113

Memory Queue Management (ContMemory Queue Management (Cont’’d)d)메모리파티션의상태얻기 / OSMemQuery()메모리파티션에서사용한메모리블록수와자유메모리블록수를알아낸다.

전달인자Pmem: 메모리파티션컨트롤블록을가리키는포인터Pdata: 메모리파티션에대한정보를저장할구조체를가리키는포인터

Embedded System Lab. II 114

Memory Queue Management (ContMemory Queue Management (Cont’’d)d)메모리파티션의사용

Embedded System Lab. II

MicroCMicroC/OS/OS--II PortingII Porting

Embedded System Lab. II 116

MicroCMicroC/OS/OS--II PortingII PortingPorting

Real Time kernel을마이크로프로세서나마이크로컨트롤러에서사용할수있도록하는작업을말한다.즉, MicroC/OS-II를다른프로세서에서사용하기위한일반적인작업임.

Porting 관점에서의 MicroC/OS-II 대부분의 MicroC/OS-II의코드는이식성을고려하여 C언어로작성되어있음.일부는프로세서의존적인 C코드와어셈블리어로작성되어있음.

MicroC/OS-II를사용할수있는프로세서의사항재진입을지원하는코드를생성할수있는 C컴파일러C언어에서인터럽트비활성화, 활성화지원인터럽트지원및일정한주기로발생하는타이밍인터럽트를제공

프로세서수준에서지원하는적정크기의하드웨어스택기능

스택포인터또는레지스터의내용을스택이나메모리로저장하고가져올수있는프로세서명령어

Embedded System Lab. II 117

MicroCMicroC/OS/OS--II Porting (ContII Porting (Cont’’d)d)uC/OS-II File Structure

Embedded System Lab. II 118

MicroCMicroC/OS/OS--II Porting (ContII Porting (Cont’’d)d)

프로세서에의존적이면서 C언어로작성할수있는함수나매크로를작성하는C 소스파일

OS_CPU_C.C

프로세서에의존적이면서 C언어로는작성할수없는저수준(Low-Level)함수나매크로를작성하는어셈블리파일이파일을수정하기위해서는해당프로세서와어셈블리에대한지식이있어야한다.

OS_CPU_A.ASM

프로세서의존적인혹은구현방법에의존적인 #define문과매크로, 형정의OS_CPU.H

설명파일명

프로세서 의존적인 파일

모든 C소스에서사용하는마스터헤더파일로써, 필요한모든헤더파일은모두이파일에포함되어있으므로어떤헤더파일을포함할지신경쓸필요가없다.

INCLUDES.H

MicroC/OS-II의모든기능을응용프로그램에따라설정하는파일OS_CFG.H

설명파일명

응용 프로그램 의존적인 파일

Embedded System Lab. II 119

MicroCMicroC/OS/OS--II Porting (ContII Porting (Cont’’d)d)OS_CPU.H프로세서, 컴파일러의종류에따라 C언어에서사용하는변수타입의크기가다르므로이식성을보장해주는변수타입을정의한다.

Ex) 16비트프로세서의경우, Integer타입의변수는 16비트크기이지만 32비트프로세서의경우, Integer타입의변수는 32비트크기이다.

typedef unsigned char BOOLEAN;typedef unsigned char INT8U; /* 무부호 8비트데이터 */typedef signed char INT8S; /* 부호있는 8비트데이터 */typedef unsigned int INT16U; /* 무부호 16비트데이터 */typedef signed int INT16S; /* 부호있는 16비트데이터 */typedef unsigned long INT32U; /* 무부호 32비트데이터 */typedef signed long INT32S; /* 부호있는 32비트데이터 */typedef float FP32; /* 단정도부동소수데이터 */typedef double FP64; /* 배정도부동소수데이터 */

typedef unsigned int OS_STK; /* 각스택요소는 16비트크기임 */

Embedded System Lab. II 120

MicroCMicroC/OS/OS--II Porting (ContII Porting (Cont’’d)d)OS_CPU.H

OS_ENTER_CRITICAL() 과 OS_EXIT_CRITICAL()MicroC/OS-II는 Critical Section에들어가기전에인터럽트를비활성화하고코드수행을마친뒤다시활성화하는방법을사용

OS_CPU.H 에는 OS_ENTER_CRITICAL()과 OS_EXIT_CRITICAL()을구현하는세가지방법이포함되어있지만이들중한가지만선택해서사용하면된다.

{.OS_ENTER_CRITICAL();/* MicroC/OS-II Critical Section Code */OS_EXIT_CRITICAL();.

}

Embedded System Lab. II 121

MicroCMicroC/OS/OS--II Porting (ContII Porting (Cont’’d)d)OS_ENTER_CRITICAL() 과 OS_EXIT_CRITICAL()

OS_CRITICAL_METHOD == 1OS_ENTER_CRITICAL(): 프로세서의인터럽트비활성화명령수행OS_EXIT_CRITICA(): 프로세서의인터럽트활성화명령수행문제점: 인터럽트가비활성화된상태에서 MicroC/OS-II함수를호출할경우함수가종료해서리턴할때인터럽트는활성화상태가된다.

OS_CRITICAL_METHOD == 2OS_ENTER_CRITICAL(): 인터럽트비활성화상태를스택에저장OS_EXIT_CRITICAL(): 스택에서꺼내이전상태로복귀하도록처리

#define OS_ENTER_CRITICAL() disable_int() /* 인터럽트비활성화 */#define OS_EXIT_CRITICAL() enable_int() /* 인터럽트활성화 */

#define OS_ENTER_CRITICAL() \asm(“ PUSH PSW”); \asm(“ DI”);

#define OS_EXIT_CRITICAL() \asm(“POP PSW”);

Embedded System Lab. II 122

MicroCMicroC/OS/OS--II Porting (ContII Porting (Cont’’d)d)OS_ENTER_CRITICAL() 과 OS_EXIT_CRITICAL()

OS_CRITICAL_METHOD == 3몇몇컴파일러는현재 PSW의값을읽어서 C함수에서선언한지역변수에저장할수있는확장기능을제공한다.

#define OS_ENTER_CRITICAL() \cpu_sr = get_processor_psw();disalble_interrupts();

#define OS_EXIT_CRITICAL() \set_processor_psw(cpu_sr);

Embedded System Lab. II 123

MicroCMicroC/OS/OS--II Porting (ContII Porting (Cont’’d)d)OS_CPU_C.C프로세서에의존적이지만 C언어로작성하는것이가능한함수나매크로를작성하는파일로써, 아래의 10개의간단한 C함수를작성해야하지만필수함수는 OSTaskStkInit() 뿐이다.

OSTaskStkInit()OSTaskCreateHook()OSTaskDelHook()OSTaskSwHook()OSTaskIdleHook()OSTaskStatHook()OSTimeTickHook()OSInitHookBegin()OSInitHookEnd()OSTCBInitHook()

Embedded System Lab. II 124

MicroCMicroC/OS/OS--II Porting (ContII Porting (Cont’’d)d)OSTaskStkInit()

OSTaskStkInit() 함수는 OSTaskCreate() 함수나 OSTaskCreateExt()함수에서생성하고자하는태스크의스택프레임을인터럽트가발생했을때처럼초기화하기위해호출한다.

OS_STK *OSTaskStkInit ( void (*task) (void *pd), void *pdata, OS_STK *ptos, INT16U opt ){

(1) 전달인자(pdata)와함께함수를호출한것처럼만들어준다(2) ISR 벡터모사;(3) 모든레지스터의내용을스택에저장한것처럼만들어준다.(4) 마지막으로스택포인터가가리키고있는위치를리턴한다.

}

OSTaskStkInit() 함수의사코드

Embedded System Lab. II 125

MicroCMicroC/OS/OS--II Porting (ContII Porting (Cont’’d)d)OS_CPU_A.ASM프로세서에의존적이면서저수준의함수나매크로가정의되어있는어셈블리파일로써, 아래의 4개의간단한어셈블리함수를포함한다.컴파일러가인라인어셈블리기능을지원한다면, 이 4개의함수들을별도의어셈블리파일이아닌 C소스파일로작성할수도있다.

OSStartHighRdy()OSCtxSw()OSIntCtxSw()OSTickISR()

Embedded System Lab. II 126

MicroCMicroC/OS/OS--II Porting (ContII Porting (Cont’’d)d)OSStartHighRdy()

OSStartHighRdy() 함수는 OSStart()에서현재우선순위가가장높은Task를수행하기위해호출하는함수이다.아래의의사코드는실제해당프로세서의어셈블리어로작성되어야한다.

void OSStartHighRdy(){

(1) 사용자정의함수 OSTaskSwHook()을호출한다;(2) OSRunning = TRUE;(3) 재실행할 Task의스택포인터를얻어온다:

Stack pointer = OSTCBHighRdy->OSTCBStkPtr;(4) 새 Task의스택으로부터모든레지스터를복구한다;(5) 인터럽트복귀명령을실행한다;

}

Embedded System Lab. II 127

MicroCMicroC/OS/OS--II Porting (ContII Porting (Cont’’d)d)OSCtxSw()

Task 수준문맥전환작업은소프트웨어인터럽트명령이나프로세서에따라서는 TRAP명령어로수행한다. 이때 ISR, TRAP 핸들러혹은예외핸들러가 OSCtxSw()를실행하도록설정해야한다.OSCtxSw()함수는수행중인 Task에서더높은우선순위의 Task를실행가능한상태로만드는 MicroC/OS-II서비스함수를호출한경우에호출된다.Void OSCtxSw(void){

(1) 프로세서레지스터저장;(2) 현재 Task의스택포인터를현재 Task의 TCB에저장

OSTCBCur->OSTCBStkPtr = 스택포인터;(3) OSTaskSwHook();(4) OSTCBCur = OSTCBHighRdy;(5) OSPrioCur = OSPrioHighRdy;(6) 재실행할 Task의스택포인터복구:

스택포인터 = OSTCBHighRdy->OSTCBStkPtr;(7) 재실행할 Task의스택으로부터프로세서레지스터복구;(8) 인터럽트복귀명령스택;

}

Embedded System Lab. II 128

MicroCMicroC/OS/OS--II Porting (ContII Porting (Cont’’d)d)OSTickISR()

MicroC/OS-II은시간지연기능과타임아웃기능구현을위해일정한주기의타이머를사용한다.

Void OSTickISR(void){

(1) 프로세서레지스터저장;(2) OSIntEnter() 호출또는 OSIntNesting값을 1 증가;(3) if( OSIntNesting == 1) {

OSTCBCur->OSTCBStkPtr = 스택포인터;}

(4) 타이머인터럽트발생장치클리어;(5) 인터럽트재활성화( 선택사항);(6) OSTimeTick(); (7) OSIntExit();(8) 프로세서레지스터복구;(9) 인터럽트복귀명령실행;

}

Embedded System Lab. II 129

MicroCMicroC/OS/OS--II Porting (ContII Porting (Cont’’d)d)OSIntCtxSw()

OSIntCtxSw()함수는 OSIntExit()함수에서 ISR종료시문맥전환을위해호출

Void OSIntCtxSw(void){

(1) 사용자정의함수 OSTaskSwHook()을호출한다;(2) OSTCBCur = OSTCBHighRdy();(3) OSPrioCur = OSPrioHighRdy();(4) 재실행할 Task의스택포인터복구:

스택포인터 = OSTCBHighRdy->OSTCBStkPtr;(5) 재실행할 Task의스택으로부터프로세서레지스터복구;(6) 인터럽트복귀명령실행

}

top related