임베디드 레시피

Egloos | Log-in





Queue와 Inter Task Communication

Motor_task는 Task구조와 Signal 에서 보았던 기본 적인 Task형태에요. Motor_task는 WORK이라는 signal을 받으면 Ready가 되고 Scheduler에 의해서 순번이 돌아오면 Context Switching되어 Motor를 켰다 껐다 하는 일을 하지요.
 
void Motor_task ()
{
 
    Motor_task_init();
     Motor_init();
                                    /* 우선은 초기화는 무조건 하네 */
     while (1)
     {
          wait (WORK);        /* 여기서 WORK이라는 signal을 일단 무작정 기다린다 */
                                    /* while(1)이니까 한번 깜빡이면 항상 여기서 signal을 기다린다 */
                                    /* Signal을 받기만 하면, 일을 시작 할테야 */■
          clear (WORK);       /* WORK을 받았으니, 다음번에도 WORK을 받을 수 있도록 초기화 해 주자 */
            Motor_on();
            time_wait (100); /* wait 100uS */
 
            Motor_off();
            time_wait (100); /* wait 100uS */
 
            send (LAMP, WORK);   /* Lamp task야 Lamp를 깜빡여봐 */
      }
}
 
너무 한산한 풍경이죠. Motor_task는 Motor를 켰다 껐다 하는 일을 100uS을 사이에 두고 일을 하는데, Motor_task에게 100uS말고 다른 시간을 인자로 주어서, 깜박거리게 하고 싶으면 어떻게 하면 좋을 까 궁리해 보아요. 일단은 Motor_task()가 인자로 뭔가 받기 위해서 Queue 자료 구조를 한번 이용해 보는 게 어떨까 생각하고 있습니다만. Queue는 FIFO 구조로서, 먼저 받은 녀석을 먼저 처리 하는 구조인 게죠. 자 그러면 이런걸 한번 생각해 보시죠. WORK이라는 Signal을 받은 경우에는 Queue에서 더 자세한 내용을 꺼내 보는 구조.
 
void Motor_task ()
{
 
    int ret;
 
     Motor_task_init();
     Motor_init();
                                    /* 우선은 초기화는 무조건 하네 */
     while (1)
     {
          wait (WORK);        /* 여기서 WORK이라는 signal을 일단 무작정 기다린다 */
                                    /* while(1)이니까 한번 깜빡이면 항상 여기서 signal을 기다린다 */
                                    /* Signal을 받기만 하면, 일을 시작 할테야 */■
          clear (WORK);       /* WORK을 받았으니, 다음번에도 WORK을 받을 수 있도록 초기화 해 주자 */
         
          ret = queue_get();       /* Queue에서 뭔가를 꺼내 온다 */
 
            Motor_on();
            time_wait (ret); /* wait ret 만큼 */
 
            Motor_off();
            time_wait (ret); /* wait ret 만큼 */
 
            send (LAMP, WORK);   /* Lamp task야 Lamp를 깜빡여봐 */
      }
}
 
어때요. 뭔지 모르겠지만, Queue에 뭔가 들어와 있으면 그걸 꺼내서 time_wait의 시간을 바꿀 수 있겠네요. 그렇다면 다른 Task에서는 Motor_task의 Queue에 이런 값만 제대로 넣어주면 되겠네요.
 
 
void Control_task ()
{
 
    int random;
 
     while (1)
     {
          wait (WORK);        /* 여기서 WORK이라는 signal을 일단 무작정 기다리죠 */
                                    /* while(1)이니까 한번 깜빡이면 항상 여기서 signal을 기다리죠 */
                                    /* Signal을 받기만 하면, 일을 시작 할테야 */
           clear (WORK);       /* WORK을 받았으니 다음번에도 WORK을 받을 수 있도록 초기화 해주자 */
 
          random = rand();    /* random한 숫자를 generation 해 주는 함수 */
          queue_put (Motor_task, random);  /* Motor_task가 가지고 있는 Queue에 random 숫자를 넣자 */
 
          send (MOTOR, WORK);  /* Motor task야 Motor를 돌려봐 */
      }
}
 
자, 어때요. Control_task는 Motor_task에게 random한 숫자를 넘겨주는 구조로 되어 있지요. 이제부터 Motor_task가 제어하는 Motor의 징~ 소리는 Random하게 울릴 거에요. 물론 Control_task도 누군가가 일을 시켜야 하겠지요. 아마도 Timer_service를 이용하면, Control_task도 주기적으로 일을 시킬 수 있겠죠. 이런 Queue를 이용하게 되면 Control_task이외의 다른 Task 들도 Motor_task에게 Queue를 통해서 일을 시킬 수 있을 것이고, Motor_task는 Queue에 해야 할 일들을 받아 두었다가, 자기가 CPU사용권을 할당 받았을 때는 while loop를 돌면서 Queue가 모두 비어질 때 까지 일을 하면 wait 상태에서 다른 녀석들이 해달라고 요청한 걸 모두 처리 할 수 있겠죠. 으흐흐.
 
이런 Queue를 각각의 Task마다 가지고 있을 수 있게 Task구조를 만들어 준다면, Task끼리의 통신을 Queue를 통해서 가능하게 해 줄 수 있어요. 더 큰 예를 든다면 이런 것도 있을 수 있겠죠. 
 
 
void Waiter _task ()
{
 
    int ret;
 
     waiter_task_init();
     waiter_init();
                                    /* 우선은 초기화는 무조건 하네 */
     while (1)
     {
          wait (WORK);        /* 여기서 WORK이라는 signal을 일단 무작정 기다린다 */
                                    /* while(1)이니까 한번 깜빡이면 항상 여기서 signal을 기다린다 */
                                    /* Signal을 받기만 하면, 일을 시작 할테야 */■
          clear (WORK);       /* WORK을 받았으니, 다음번에도 WORK을 받을 수 있도록 초기화 해 주자 */
         
          ret = queue_get();       /* Queue에서 뭔가를 꺼내 온다 */
 
          switch (ret)
          {
             case WORK:
                  work();
              break;
 
             case ORDER:
                   order();
              break;
            ............
          }
 
      }
}
 
뭐 이런 식도 가능하겠죠. Queue를 이용하게 되면 무궁무진하게 Task에게 많은 일을 시킬 수 있는 방법이 생겨난 거에요. 이러니 Queue는 RTOS Kernel에서 중요한 대접을 받는 자료 구조가 되겠죠. Incentive라도 줘서 대우해 줘야 할 판이라니깐요.
 
 요즘들어, 멋들어진 그림들을 넣지않아 조금 속상하지만, 금방 또 나오겠지요.

by 히언 | 2009/08/26 20:38 | RTOS팩토리(커널) | 트랙백 | 핑백(1)

Linked at 친절한 임베디드 시스템 개발자.. at 2009/10/01 12:45

... ⓝ Queue와 Inter Task Communication ... more

◀ 이전 페이지          다음 페이지 ▶