OS_TCBInit()함수는 태스크생 성시 OS_TCB 즉, 태스크컨트롤 블록을 초기화하며, Task생성함수 OSTaskCreate() 또는
OSTaskCreateExt() 함수에서 호출한다. OSTCBInit()함수는 다음과같이 7개의 인자를 전달받는다.
1. prio : 태스크 우선순위
2. ptos : CPU.C 파일에 OSTaskStkInit()함수가 초기화한 스택의 시작위치를 가리키는 포인터, 이값은 Task 컨트롤 블럭의
OSTCBStkPtr 필드에 저장된다.
3. pbos : 스택의 끝부분을 가리키는 포인터 이 값은 Task 컨트롤 블럭의 OSTCBStkBottom 필드에 저장된다.
4. id : 태스크의 ID(식별자), Task 컨트롤 블럭의 OSTCBId 필드에 저장된다.
5. stk_size : 스택의 전체크기. Task 컨트롤 블럭의 OSTCBStkSize 필드에 저장됨
6. pext : Task 컨트롤 블럭의 OSTCBExtPtr 필드에 두기위한 포인터.
7. opt : 선택사항을 알려주는 값 Task 컨트롤 블럭의 OSTCBOpt 필드에 저장됨
다음은 OTCBInit()함수의 소스코드와 이를 분석한 자료이다.
/*----------------------------------------------------------------------------------------------*/
INT8U OS_TCBInit(INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id,
INT32U stk_size, void *pext, INT_16U opt)
{
#if OS_CRITICAL_METHOD == 3 // CPU.H 파일에서 이값이 3으로 정의되있으면
OS_CPU_SR cpu_sr //OS_CPU_SR 형 변수 cpu_sr을 선언하고
#endif
OS_TCB *ptcb; // Task 컨트롤 블럭구조체의 포인터 변수를 하나 선언
OS_ENTER_CRITICAL(); //이영역이후는 크리티컬섹션(임계영역)이므로 인터럽트 Disable과
//현상태에 상태레지스터(CPSR)을 저장하는 역할을 함
//크리티컬 섹션(=임계영역)
ptcb=OSTCBFreeList; ---------------------------------------(1)
if(ptcb != (OS_TCB *)0){ -----------------------------------(2)
OSTCBFreeList = ptcb->OSTCBNext;
OS_EXIT_CRITICAL();
ptcb->OSTCBStkPtr = ptos;-----------------------------(3)
ptcb->OSTCBPrio = (INT8U)prio;
ptcb->OSTCBStat = OS_STAT_RDY;
ptcb->OSTCBDly = 0;
#if OS_TASK_CREATE_EXT_EN > 0
ptcb->OSTCBExtptr = pext;---------------------------------(4)
ptcb->OSTCBStkSize = stk_size;
ptcb->OSTCBStkBottom = pbos;
ptcb->OSTCBOpt = opt;
ptcb->OSTCBId = id;
#else
pext = pext;
stk_size = stk_size;
pbos = pbos;
opt = opt;
id = id;
#endif
#if OS_TASK_DEL_EN > 0
ptcb->OSTCBDelReq = OS_NO_ERR;;--------------------------------(5)
#endif
ptcb->OSTCBY = prio >> 3; ;-------------------------------------(6)
ptcb->OSTCBBitY = OSMapTbl[ptcb->OSTCBY];
ptcb->OSTCBX = prio & 0x07;
ptcb->OSTCBBitX = OSMAPTbl[ptcb->OSTCBX];
#if OS_EVENT_EN > 0
ptcb->OSTCBEventPtr = (OS_EVENT *)0;-------------------------------(7)
#endif
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) && (OS_TASK_DEN_EN > 0)
ptcb->OSTCBFlagNode = (OS_FLAG_NODE *)0;-------------------------(8)
#endif
#if OS_VERSION >= 204
OSTCBInitHook(ptcb);--------------------------------------------------(9)
#endif
OSTaskCreateHook(ptcb);----------------------------------------------(10)
OS_ENTER_CRITICAL();------------------------------------------------(11)
OSTCBPrioTbl[prio] = ptcb;-------------------------------------------(12)
ptcb->OSTCBNext = OSTCBList;
ptcb->OSTCBPrev = (OS_TCB *)0;
if(OSTCBList != (OS_TCB *)0){
OSTCBList->OSTDBPrev = ptcb;
}
OSTCBList = ptcb;
OSRdyGrp |= ptcb->OSTCBBitY;-----------------------------------(13)
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
OS_EXIT_CRITICAL();
return (OS_NO_ERR);---------------------------------------------------(14)
}
OS_EXIT_CRITICAL();
return (OS_NO_MORE_TCB);
}
(1) OS_TDBInit()함수는 자유리스트에서 Task컨트블록을 우선 1개 할당받는다.
(2)(3) 자유리스트에서 사용할수있는 Task컨트를 블록이 존재할경우 이를 초기화함 Task컨트를 블록이 일단 할당되면
OS_TCBInit()함수를 호출 한 태스크가 완전히 소유한것이고 다른곳에서 태스크를 생성해도 할당된 블록은 손상될
염려가 없으므로 인터럽트를 활성한 상태에서 컨트롤 블록의 몇몇 필드를 초기화 할 수 있다.
(4) OSTaskCreateExt()함수로 태스크를 생성하겠다고 OS_CFG.H의 OS_TASK_CREATE_EXT_EN 값을 1로 설정했다면
Task 컨트를 블록의 추가 필드도 함께 초기화함
(5) 태스크를 삭제할 일이없으면 OS_CFG.H의 OS_TASK_DEL_EN값을 비활성화하여 Task컨트를 블록의 저장영역을 절약
할 수 있다.
(6) 스케쥴링시 시간을 절약하기위해 OS_TCBInit()함수에서 몇몇 필드를 계산해 둔다. 저장영역은 커지지만 시간은 절약됨.
(7) 세마포어, 뮤텍스, 메시지 메일박스, 메시지큐를 사용하지 않을경우 Task컨트를블록의 OSTCBEventPtr필드를 둘필요없음.
(8) OS_CFG.H의 OS_FLAGS_EN == 1 즉 , 이벤트 플래그를 활성화 했으면 이벤트 플래그 노드를 가리키는 포인터는 아무것도
가리키지않도록 초기화한다.
(9) ucos버전이 2.04이상이면 OSTCBInitHook()함수를 호출한다. 이함수는 부동소수레지스터, MMU 레지스터의 내용, 태스크와
관계있는 어떤것도 초기화하고 저장이 가능하다. OS_TCBInit()함수가 OSTCBInitHook()함수를 호출한땐
인터럽트는 활성화 상태이다.
(10) 이 함수는 OSTaskCreate() 또는 OSTaskCreateExt()함수의 기능을 확장하는 사용자 정의함수이다.
(9)(10)번함수를 모드 호출하는 이유는 각함수와 관련된 Task컨트를 블록의 필드를 쉽게 그룹화 할수 있기 떄문이다.
(11)(12) OS_TCBInit()함수는 새로생성한 Task 컨트를 블록을 이중연결리스트애 삽입할때 인터럽트를 비활성화 함
리스트는 OSTCBList에서 시작하며 새 Task의 컨트를 블록은 항상 리스트 앞에 삽입됨.
(13)(14) 마지막으로 태스크는 실행준비상태가 된다. 그리고 OS_TCBInit()함수는 OS_TCB를 할당해 초기화했다는 값을
가지고 호출자(OSTaskCreate() 또는 OSTaskCreateExt())로 리턴한다.