티스토리 뷰

운영체제

[MicroC/OS-II] OSTaskQuery

머어하지 2017. 4. 21. 22:06

  Task에 관련된 함수들은 다음에서 확인해 보실 수 있습니다.

[MicroC/OS-II] Task에 관련된 함수들


  앞서 MicroC/OS-II에서 TCB에 관한 내용을 살펴보았습니다.

[MicroC/OS-II] TCB Management


  이제 TCB와 관련된 함수들을 살펴보겠습니다. 먼져 OSTaskQuery에 대해서 살펴보겠습니다. TCB Management에서 각각의 Task는 서로 다른 Priority를 가지고 있다고 알아보았습니다. 사용자가 어떠한 작업을 하는경우 해당 Priority가 있는지 없는지 즉, 해당 Task가 있는지 없는지 판단을 한 상태에서 작업을 수행하여야 할 것입니다. 그렇지 않으면 오류가 나겠지요!!! OSTaskQuery는 해당 Priority에 해당하는 TCB를 복사하는 역활도 하지만 해당 Priority가 존재 하는지에 대한것도 검사를 해줍니다. 그렇다면 OSTaskQuery는 어떻게 그 Priority에 해당하는 Task 즉, TCB가 있는지 알 수 있을까요? 여기엔 2가지의 방법이 있습니다.


OSTaskQuery는 어떻게 해당 Priority의 TCB를 찾을까?

  1. OSTCBList를 전부 확인 하는 방법입니다.


  TCB에는 Priority에 관한 정보도 있으므로 OSTCBList를 앞에서부터 하나 씩 확인을 하면 언젠가 해당 Priority가 나오게 될 것입니다. 하지만 이 방법은 실제 MicroC/OS-II에서는 사용하고 있지 않습니다. 하나씩 확인하는 자체가 불필요한 작업을 많이 하는것이기 때문입니다.


  2. OSTCBPrioTbl을 이용하는 방법입니다.


  OSTCBPrioTbl는 최대 Priority 개수인 64개 만큼의 Pointer Array로 되어있습니다. 즉 64개를 다 포인팅하고있습니다. 어떠한 구조로 되어있는지 보시겠습니다.



  0~63 까지의 Priority에 해당하는 TCB가 생성이 되었는지 아닌지 정보를 가지고 있습니다. 만약 생성이 안 된 경우라면 해당 값은 NULL 값이 저장되어 있습니다. 따라서 OSTaskQuery는 Priority를 받아 OSTCBPrioTbl에서 해당 번호가 NULL인지 아닌지만 확인하면 해당 Priority의 TCB가 존재하는지 안하는지 알 수 있게 됩니다. 이러한 방식은 해당 Priority의 번호만 확인하면 되므로 일일이 확인하는 1 방법을 쓰지 않은겁니다. 그럼이제 OSTaskQuery의 코드를 살펴보겠습니다.


OSTaskQuery

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
INT8U OSTaskQuery (INT8U prio, OS_TCB *pdata)
{
    #if OS_CRITICAL_METHOD == 3 
        OS_CPU_SR cpu_sr;
    #endif 
        OS_TCB *ptcb; 
 
    #if OS_ARG_CHK_EN > 0 
        if (prio > OS_LOWEST_PRIO && 
            prio != OS_PRIO_SELF) 
        {                
            return (OS_PRIO_INVALID); 
        } 
    #endif
 
    OS_ENTER_CRITICAL(); 
    
    if (prio == OS_PRIO_SELF) {
         prio = OSTCBCur->OSTCBPrio; 
    } 
 
    ptcb = OSTCBPrioTbl[prio]; 
    if (ptcb == (OS_TCB *)0) { 
        OS_EXIT_CRITICAL(); 
        return (OS_PRIO_ERR); 
    } 
 
    memcpy(pdata, ptcb, sizeof(OS_TCB)); 
    OS_EXIT_CRITICAL(); 
    return (OS_NO_ERR); 
}
cs


  어느정도 이해가 필요한 부분만 보겠습니다. 


  OS_LOWEST_PRIO는 63으로 정의가 되어있습니다. 따라서 Priority는 0~63까지만 가질 수 있으므로 64 이상이면 오류이므로 확인을해 조건이 만족이면 error를 return 하고 있습니다. 즉 Priority가 우선 존재 할 수 있는가를 확인했습니다. OS_PRIO_INVALID는 error의 의미를 담고있습니다.


1
OS_ENTER_CRITICAL(); 
cs


  CPU Scheduling 을 멈춤니다. CPU Scheduling은 후에 더 자세히 알아보겠습니다.


1
2
3
if (prio == OS_PRIO_SELF) {
    prio = OSTCBCur->OSTCBPrio; 
cs


  인자로 값을 받은 prio 가 현재 사용중인 prio면 OSTCBCur(현재 TCB)의 Priority를 받아들여 prio에 저장합니다.


1
ptcb = OSTCBPrioTbl[prio]; 
cs

  그리고 위에서 알아보았던 OSTCBPrioTbl을 통해 그 prio에 해당하는 TCB를 ptcb에 저장합니다.

1
2
3
4
if (ptcb == (OS_TCB *)0) { 
    OS_EXIT_CRITICAL(); 
    return (OS_PRIO_ERR); 
cs

  만약 받아온 TCB가 NULL 이라면 OS_EXIT_CRITICAL을 통해 CPU Scheduling을 다시 시작하고 error를 ruturn합니다.

1
memcpy(pdata, ptcb, sizeof(OS_TCB)); 
cs

  NULL이 아니라면 ptcb에 저장된 TCB를 인자로 받아온 공간인 pdata에 복사해 저장합니다.

1
2
OS_EXIT_CRITICAL(); 
return (OS_NO_ERR); 
cs

  끝은 역시 CPU Schduling을 다시 시작하고, no_error를 return 합니다.

간략하게 OSTaskQuery를 알아보았습니다. OSTaskQuery의 사용은 다음과 같이 사용합니다.

1
2
3
4
5
6
void task_start(void *pdata)
{
    OS_TCB MyTaskData;
    INT8U err;
    err = OSTaskQuery(10&MyTaskData);
}
cs

마지막으로 퀴즈 하나 하고 마치겠습니다.

Q. Priority를 확인 할 때 일일이 확인 하는 방법도 있었는데요 코드를 어떤식으로 작성하면 확인 할 수 있을까요?

A.  답확인 클릭!



댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday