중요한 개념인 Task를 구현 합니다. 1.X에서는 상당히 애매한 상황이 벌여 졌지만 앞서 말한 TASK가 각 각 슬롯을 가짐으로 확실해 졌습니다.

TASK
이때까지 본 소스는 동시성과는 거리가 먼소스들이었습니다. 동시 실행 코드가 실행 되고 있을 동안에는 선점이 되지 않습니다. 이 메카니즘은 TinyOS 스케줄러의 자원 소모를 줄였으나 동시 실행 코드는 매우 작은 크기여야 합니다. 즉 동시 실행시 선점 되지 않기 때문에 즉각 반응 시스템엔 역효과를 내는 것입니다. 예로는 긴 코드가 실행 되어 패킷에 반응 하는 속도가 늦어 질 수 있는 것입니다.

이때까지 코드는 아주 짧은 실행 코드만을 지녀 별문제 없이 작동 했습니다. 하지만 매우 긴 시간을 요구하는 실행 코드의 경우 선점 되지 않는 문제는 많은 문제를 야기 할 수 있습니다. 그래도 2.0의 경우 매우 긴 시간을 요구하는 코드의 경우 여러부분으로 나눌것을 권장 합니다.

Task - Task는 어플리케이션에 백그라운드 프로세싱을 가능하게 합니다. 이정도로 생각 하시면 됩니다. OS에서 이야기하는 bottom halves와 deferred procedure call과 비슷 합니다.(*하드웨어 인터럽트가 먼저라 생각 하시면 됩니다.)

이제 Task를 실습 하도록 하겠습니다. cp 명령어를 사용 하여 새로운 BlinkC 백업 본을 만듭니다.(BlinkTask)

cp -R Blink BlinkTask

Timer0.fired() 이벤트를 수정하여 작업을 좀 넣도록 하겠습니다.

event void Timer0.fired()
  {
    uint32_t i;
    dbg("BlinkC", "Timer 0 fired @ %s.\n", sim_time_string());
    for(i =0; i<400001;i++){
      call Leds.led0Toggle();
    }
  }

대충 이작업은 MicaZ , Telosb 계열 모트가 20번의 패킷을 보낼 수 있는 시간의 작업을 수행 합니다. 퓨징 하시면 지연으로 인해 이상하게 동작 하는 모트를 보실 수 있습니다.

동작의 결과를 설명 드리면 Timer0에서 발생하는 연산이 Timer이벤트들의 실행을 방해 하며 결국은 Timer0의 연산이 끝나는 시점에서 동시에 발생 하게 되는것이다. 그래서 두개가 계속 나란히 켜지면 한개만 켜지는 경우는 없게 된다.

이문제를 해결 하기 위해서는 백그라운드로 저 작업을 실행 하면된다.

Task의 정의는 다음과 같다.

task void taskname(){}

Task는 인자를 가질수도 리턴값을 가질수도 없다. 그리고 Task를 실행 할때는 post를 사용한다.

post taskname();

여기서 중요한거 컴포넌트의 command,task,event는 task를 포스팅 할 수 있다. 그리고 이벤트 시그널을 위해서는 Task를 사용 하기 바란다. command에서 event를 사용하는건 루프를 발생 시킬 소지가 매우크다. 나중에 설명함(예로 인터페이스 I 제공 하는 컴포넌트 A 사용하는 B가 있을 경우 B의 이벤트에 핸들러에서 A의 command를 실행 하며 그 command에서 시그널을 날린다면 바로 루프가 발생하는 것이다.)

task를 다음과 같이 수정하여 만든다.

 task void computeTask(){
    uint32_t i;
    for(i=0;i<400001;i++){}
  }
  event void Timer0.fired()
  {
      call Leds.led0Toggle();
      post computeTask();
  }

그럼 TelosB는 아직 이상하지만 MicaZ는 작동 잘 할 것이다.

post는 Task를 큐에 FIFO 방식으로 넣는 역활을 한다. Task는 긴 수행시간을 가져서는 안된다. Task는 서로는 선점 하지 못하지만, 하드웨어 인터럽트는 Task를 선점 할수 있다. 긴시간의 수행시간을 가지는 Task의 경우 나누도록 한다. post 명령은 error_t 를 반환한다. (task가 반환 하는것이 아닌 post명령이다.) 이경우는 Task가 벌써 성공적으로 스팅 된 경우 이다.(물론 아직 실행은 안되었다.)

TelosB의 경우 아직 Task 가 많은 시간을 소모 하기 때문에 정상 작동 하지 않는 것이다. 다음과 같이 수정한다.

외적으로 static 변수를 사용하는건 생략 한다. 대략 컴포넌트안의 변수는 모두 Private이기때문에 static를 사용하는건 의미가 없다.
, .