그럼  Lesson 2 시~~작

Lesson 2. Modules and the TinyOS execution Model
TinyOS에 실행에 있어 중요한것은 Module,command,task 입니다. 기억 하세요.

*이제 편하게 애기하듯이 할 예정입니다.

TinyOS를 컴파일 하면 한개의 바이너리 파일이 나오며, 모트는 한번에 한개의 TinyOS 이미지를 실행 실킬 수 있습니다. 이미지 생성시에는 여러개의 컴포넌트를 필요로 합니다.  대부분의 모트들이 하드웨어적으로 메모리 보호를 할 수 없으며 더구나 하나의 주소맵을 모든 컴포넌트들이 공유 합니다. 그래서 컴포넌트들은 개인적이 변수를 가지게 해야 하며 포인터를 전달 하는건 피해야 합니다. 메모리충돌을 방지하기위해서는 메모리 공유를 피하시길 바랍니다.

1장에서 보다 시피 컴포넌트는 하나 이상의 제공받는 또는 제공 하는 인터페이스를 가지며 이건 두가지 컴포넌트 타입 모듈과 구성에 똑같이 적용 됩니다. 단지 구성 파일은 지가 구현 하는게 아니고 다른 모듈을 통해서 그기능을 제공 하며, 모듈은 실제적인 기능을 가지고 있습니다.(이런이유는 뭐 LED를 가지고 설명하면,, 모트에 따라 LED를 제어 하는 실제적인 모듈은 다를 것입니다만.. 구성파일을 래퍼로 앞세워 똑같은 컴포넌트 이름,인터페이스로 기능을 제공 할 수 있게 되는 것입니다.)

모듈에 선언되는 변수는 모두 공유 될수 없는 private 변수들이며 다른 컴포넌트는 절대 그 변수 이름으로 접근 할 수 없습니다. 단지 인터페이스를 통해 접근 가능 합니다.(여기서 문제,, 전역 변수는 어떻게 하느냐.. 어렵습니다. ㅡ.ㅡ;죄송 근데 전역 변수 설정이 되면.. 쓰기도 뭐 합니다. 제 경험상 크리티컬 세션 이 잘 작동 안합니다. atomic 이죠.);

apps Blink를 다시 `~~ 분석 하죠.

module BlinkC{
  uses interface Timer<TMilli> as Timer0;
  uses interface Timer<TMilli> as Timer1;
  uses interface Timer<TMilli> as Timer2;
  uses interface Leds;
  uses interface Boot;
}
implementation{
event void Boot.booted()
{
  call Timer0.startPeriodic(250);
  call Timer1.startPeriodic(500);
  call Timer2.startPeriodic(1000);
}

event void Timer0.fired(){
  call Leds.led0Toggle();

}

-----------------------------------중    략-----------------------------------------

보시다 시피 BlinkC는 어떻한 변수도 선언 안합니다.. 여기서 잠깐 실습 Blink를 BlinkSingle로 복사하세요.

cp -R Blink BlinkSingle 명령어 사용( tinyos-2.x/app 위치에서)

그리고 다음 과 같이 수정 합니다.

event void Timer1.fired()
  {
    // call Leds.led1Toggle();
  }
 
  event void Timer2.fired()
  {
    // call Leds.led2Toggle();
  }
일단 타이머는 한개만 사용 할 예정 입니다.

그리고 변수 하나를 선언하고 사용합니다. 선언하고 쓰는 요령은 C와 같습니다.

uint8_t counter=0;
  event void Boot.booted()
  {
    call Timer0.startPeriodic( 250 );
    //call Timer1.startPeriodic( 500 );
    //call Timer2.startPeriodic( 1000 );
  }

(아!! 전 걍 저렇게 첨부터 타이머를 막았습니다.^^;;)

그리고 다른건 C와 비슷하게 쓰더라도 자료형은 다음과 같은 규칙에 의거해서 사용할것을 추천 합니다.물론 걍 C자료형 써도 무방하지만 메모리가 부족한 관계로 필요한 만큼 쓰는게 좋은겁니다.물론 float,bool다 지원 합니다.

사용자 삽입 이미지
이제 다시 BlinkC로 와서, 우리가 선언한 counter는 모트가 켜지면서 0으로 초기화 됩니다.
그리고 Timer가 터질때 counter를 증가 시켜 counter에 따라 모트를 제어 합니다.

event void Timer0.fired()
  {
    counter++;
    if (counter & 0x1) {
      call Leds.led0On();
    }
    else {
      call Leds.led0Off();
    }
    if (counter & 0x2) {
      call Leds.led2On();
    }
    else {
      call Leds.led2Off();
    }
    if (counter & 0x4) {
      call Leds.led2On();
    }
    else {
      call Leds.led2Off();
    }
  }

이와 같이 수정 합니다. 대충 알고리즘은 걍 카운터 입니다. ^^;

그리고 좀더 쉬운 방법으로 ^^ set command를 사용 하는 겁니다.

event void Timer0.fired()
  {
    counter++;
    call Leds.set(counter);
  }
결과는 똑같은 겁니다. 왜냐.. LedC 컴포넌트 소스 따라가면 위에꺼 똑같이 쳐져 있을겁니다.(1.x에서는 그랬습니다. ㅎㅎ ^^);
 실행 시켜 보시면 똑같이 동작 하게 될겁니다.

이제 Timer는 하나만 사용 하고 있습니다. 타이머도 역시 리소스를 먹으므로 이제 두개타이머는 제거 하도록 합니다.

module BlinkC {
  uses interface Timer<TMilli> as Timer0;
  uses interface Leds;
  users interface Boot;
}
implementation
{
  uint8_t counter = 0;

  event void Boot.booted()
  {
    call Timer0.startPeriodic( 250 );
  }

  event void Timer0.fired()
  {
    counter++;
    call Leds.set(counter);
  }
 
}

다음과 같이 적고 컴파일 하면 ?? 당연 에러 납니다. 구성파일에서 와이어링 해놓은 게 있기때문에 에러 나게 됩니다. BlinkAppC에서 타이머와 와이어링을 제거 하고 다시 컴파일 하면 에러 안나게 될것입니다.


configuration BlinkAppC
{
}
implementation
{
  components MainC, BlinkC, LedsC;
  components new TimerMilliC() as Timer0;
 

  BlinkC -> MainC.Boot;

  BlinkC.Timer0 -> Timer0;
  BlinkC.Leds -> LedsC;
}
이렇게 수정 하시면 됩니다.
그라면 다음에 계속..

, .

이제 Lesson1은 끝내자...

The BlinkAppC.nc configuration

이제 소스를 살펴 보도록 하겟습니다. 우선 어플의 시작이라 할 수있는 top-level을 분석 해 보겠습니다.

apps/Blink/BlinkAppc.nc

configuration BlinkAppC
{
}
implementation
{
  components MainC, BlinkC, LedsC;
  components new TimerMilliC() as Timer0;
  components new TimerMilliC() as Timer1;
  components new TimerMilliC()fd as Timer2;


  BlinkC -> MainC.Boot;

  BlinkC.Timer0 -> Timer0;
  BlinkC.Timer1 -> Timer1;
  BlinkC.Timer2 -> Timer2;
  BlinkC.Leds -> LedsC;
}

먼저 configuration 키워드를 사용 이파일이 configuration이라는 걸 알린다. 위 두줄을 분석하면 BlinkAppC라는 구성 파일( configuration을 구성이라 하겟다.) 위 브라켓 사이에는 사용 하는 인터페이스 또는 제공 인터페이스가 올수 있다. 즉 구성 파일도 인터페이스를 사용 제공 할 수 있다는 것이며, 이것은 모든 구성 파일이 top-level은 아니라는 것이다.

실제적으로 이 구성 파일의 구현은 implementation안에 있다. components 부분은 이 구성 파일이 참조할 모듈들을 나열 한다. 여기서는 Main,BlinkC,LedsC, 그리고 Timer1,2,3으로 참조 되어 지는 TimerMilliC라는 모듈을 열거 하고 있다.

자 여기서 명심 할것 BlinkAppC와 BlinkC.nc는 다르다. 구성 파일은 BlinkC,Main,Leds,Timer를 조합 하고 있는 파일이다.

BlinkAppC는 인터페이스를 제공 하는 컴포넌트와 사용 하는 컴포넌트를 연결하고 있다. 일단 MainC.boot와 MainC.SoftwareInit는 부트 순서에 따라 실행 되며 이건 Lesson 3 에서 다룰 예정이다. 이 의미는 LED를 enable 하며,  타이머를 초기화 한다.

나머지 4줄은 BlinkC가 TimerMilliC 와 LedsC가 제공 하는 인터페이스를 사용 한다는 의미이다.

BlinkC.nc 모듈
이제 실제 구현을 살펴 보도록 하겠습니다.

module BlinkC
{
  uses interface Timer<TMilli> as Timer0;
  uses interface Timer<TMilli> as Timer1;
  uses interface Timer<TMilli> as Timer2;
  uses interface Leds;
  uses interface Boot;
}

첫줄은 구성 파일과 같다 이파일은 BlinkC라는 모듈이라는 의미이다. 그리고 사용하는 인터페이스와 제공하는 인터페이스를 기술한다. (즉 사용할 함수를 열거하는 의미와 비슷하다.)BlinkC는 다섯개의인터페이스 를 사용하며 그중 Timer0,1,2로 Timer<TMilli> 인터페이스의 인스턴스를 사용한다. (<TMilli> 구문은 필요한 타이머 정확도로 타이머 인터페이스를 간단하게 제공 한다.) 마지막 두줄은 Leds와 Boot인터페이스를 사용하여 이 두개의 인터페이스가 제공 해주는 command를 부를수 있다는 의미이다.

BlinkC를 분석하면 앞선 BlinkAppC의 마지막 4라인을 이해 할 수 있다. BlinkC.Timer0 -> Timer0  이줄의 의미는 TimerMilliC 컴포넌트에서 제공하는 Timer<Milli> 인터페이스를 BlinkC에서 사용 하는 Timer<MilliC> 인터페이스에 연결 하는 작업이다. 그외 도 같다고 생각 하면 된다.BlinkC.Leds->LedC 이건 LedC에서 제공 하는 인터페이스 Leds를 BlinkC에서 사용할 Leds 인터페이스에 연결 하는 것이다.

와이어링 규칙은 A->B 일때 A 는 B에 연결 되는 것이며, A가 유저 B가 제공자 이다. A.a -> B.b 는 컴포넌트 A의 인터페이스 a를 컴포넌트 B의 인터페이스 b에 연결 하는 것이다.(이때 두개의 특성은 같은 것이어야 한다.) 인터페이스의 이름은 즉 객체의 이름은 여러개의 인터페이스를 제공 또는 사용 할때 잘 구분 해야 한다. 예로 BlinkC는 세개의 Timer 인터페이스 Timer0,1,2로 사용 하고 있다. 컴포넌트가 인터페이스를 하나의 객체로만 사용 하면 인터페이스 이름을 생략 할 수 있다.

그래서 BlinkC.Leds->LedC 를 보면 생략 된걸 알 수 있으며 이 줄은 "BlinkC.Leds->LedC.Leds"와 같으며 역으로 "Leds->LedC.Leds"으로 사용 해도 동작 한다.

그럼 TimerMilliC의 경우를 분석 해 보도록 하자. TimerMilliC의 경우 한개의 Timer 인스턴스를 제공 하고 있다 이와 같은 경우 유저쪽의 인터페이스 이름을 생략 할 경우 컴파일러는 어떤 Timer 객체를 연결 할 지 혼란 되기 때문에 에러가 발생한다.

BlinkC->Timer0.Timer // 에러 발생

BlinkC.Timer0 -> Timer0.Timer //에러 발생 안함 , 인터페이스 객체와 컴포넌트 객체의 이름은 같을수 있다.

오른쪽 왼쪽은 의미 없다 Timer0.Timer <- BlinkC.Timer0  똑같은 의미이다. 이게 더 명확하다고 생각 할 사람은 이렇게 프로그래밍 해도 상관 없다.

Visualizing a Component Graph

TinyOS 시스템을 신중히 프로그램 할려면 짧은 코드로 이루어진 여러 층의 추상계층으로 이루어진 구성 파일을 프로그래밍 해야 할 것이다. 그러면 여러층의 추상 계층으로 이루어진 모듈들을 분석하는건 텍스트 기반 에디터로는 아주 힘든 작업이 된다. 그래서 TinyOS는 nesDOC 이라 불리는 툴을 제공 한다. NesDoc은 소스 코드로 부터 비주얼한 문서를 자동으로 생성하며 그 문서는 모듈의 구조와 구성을 볼 수 있다.

nesDoc을 생성 하기 위해서는 "make telosb docs"를 사용한다.

실행하면 꽤 긴 몇줄의 컴포넌트 인터페이스의 출력을 확인 할 수 있으며 에러 메세지가 출력 된다면
"sh : dot: command not found"
Graphviz가 인스톨 되지 않은 것이다. 다시 인스톨하도록 한다.

nesdoc은 다음 tinyos-2.x/doc/nesdoc 폴더에 생성 되며 생성된 플랫폼 폴더가 생성 되어 그 안에 문서가 생성 된다. 폴더안의 index.html을 살펴 보자. telosb 기반에 생성 했다면, Boot,Leds,Timer 인터페이스와 하드웨어와 관련된 Msp430TimerEvents 등을 찾을 수 있을 것이다.

왼쪽 하단에서 BlinkAppC를 클릭하면 다음과 같은 비주얼 구조도를 볼수 있을 것이다.
 

사용자 삽입 이미지


여기서 한줄로된 박스는 모듈이며 두줄로 된 박스는 구성 파일 이다. 점선으로된 박스는 범용이라는 것을 의미한다.(객체?)

화살표는 와이어링을 의미 한다. 그리고 줄옆에는 인터페이스 이름이며 짙은 배경의 타원 역시 제공 또는 사용 하는 인터페이스이다. . 다 클릭 가능 하다. MainC를 클릭 하면 부팅 순서를 알수 있으며 타원형의 인터페이스도 볼 수 있다.
사용자 삽입 이미지

 
여기서 Boot,SoftwareInit가 와이어링 가능한 인터페이스이다. MainC는 Boot를 제공 하며, SoftwareInit를 사용한다. 방향을 자세히 보면 사용 하는 SoftwareInit은 RealMainP에서 나가며 제공 하는 Boot의 경우 들어오는 걸 확인 할 수 있다. MainC의 경우 Lesson3에서 살펴볼 예정이니 무시하자. 보통 스케줄러,하드웨어 초기화,소프트웨어 초기화등을 담당 하고 있다.

휴 대충 끝냈네요 결론은 생략 입니다.

Lesson2는 이전에 번역한걸 재 편집 할 예정 입니다~~



, .

두번째 입니다.

NesC 컴파일러 버젼 확인

sytanx error before 'new'

컴파일시 이런 메세지가 출력 될 경우에는 ncc --version으로 버젼을 확인하세요.

ncc : 1.2.1
nescc : 1.2.6

이상 이어야 합니다.

그리고 버젼 확인 후에도 에러가 발생 한다면 다른 버젼의 ncc 가 컴파일시 불러와지는겁니다.
그리니 "which ncc" 라는 명령어로 ncc의 위치를 파악하여 버젼을 다시 확인 하시길 바랍니다. 이와 같은 경우는 tinyos1.x에서 업그레이드 했을 경우 더욱 쉽게 발생 할 수 있으니 유의 하시길 바랍니다.

자.. 이제 모트에 넣어 보도록 하죠.~~

다 건너뛰고 .. 제가 가진전 telosb  뿐이라 ㅎㅎ telosb만 합니다.

telosb 계열은 아시다 시피 USB로 퓨징이 가능 합니다. 그래서 걍 컴터에 꽂고 "motelist"라고 쳐봅시다
그럼 연결된 모트를 확인 하실 수 있습니다.

연결이 확인되면 make telosb resintall bsl,/dev/ttyUSB2 명령으로 퓨징 가능 합니다.

제가 telosb 계열을 사용 하는 관계로 install 부분은 간단하게 넘어갔습니다. 다른 모트를 사용 하시는 분들은 해당 튜터리얼을 보세요.

이제 본격적으로 TinyOS, NesC의 컨셉을 간단히 알아 보도록 하겠습니다.

- Components and Interfaces -

이제 컴파일 해서 설치 했으니 이제 시작 입니다. 이제 어떻게 깜빡깜빡 하는지 알아야 겠죠 ^^;

자 Blink라는 어플은 nesc로 되어 있으며 nesc는 씨언어에 컴포넌트와 동시 실행을 지원 하도록 만든 언어 입니다.
nesc 어플리케이션은 한개 이상의 컴포넌트들이 wired 즉 연결되어 실행 되어 집니다. 컴포넌트는 1.x와 마찬가지로 구성을 저장 하는 모듈과, 실제적인 기능을 하는 함수들을 포함 하고 있는 모듈로 구성 됩니다.컴포넌트는 인터페이스를 제공 또는 사용 합니다. 제공 하는 인터페이스는 컴포넌트의 사용자에게 기능의 명세를 제공하며 사용하는 인터페이스는 컴포넌트의 기능 구현에 있어 필요한 하위 컴포넌트의 인터페이스이다. (말이 어렵네.. ㅡ.ㅡ; 즉 제공 하는건 위에 자기의 기능을 주고 사용하는건 자기가 하위에게 명령을 내릴때 사용 한다는 것)

인터페이스는 양방향 입니다. 제공자에서 기능을 구현해야 하는 command와 사용자에서 구현 해야 하는 event가 있습니다. 하나의 컴포넌트는 하나 이상의 컴포넌트를 사용 제공 할 수 있으며 또한 하나의 인터페이스를 여러개의 개체로 사용 할 수도 있다.

configurations and module
앞에서 살짝 애기 했습니다. nesc는 두가지 타입의 컴포넌트 즉 module과 configurations 가 있습니다. 모듈은 제공 인터페이스를 구현하며 configuration은 컴포넌트끼리 연결 하기 위해 사용 합니다. 모든 어플은 top-level-configuration이라는 파일에서 시작 합니다. 여기선 BlinkAppC가 되겠죠 ^^; 위 두개의 컴포넌트는 하나의 파일에 위치 할수 도 있습니다.~~

- Blink:EXAM -

blink를 살펴 보면 생각 하는 거랑 약간 틀립니다. LED의 깜빡이는 속도를 제어하여 binary 카운터를 실행 합니다. (생각 보다 ver2.0에서는 타이머가 정확하게 동작 하는 겁니다.)

Blink는 BlinkC.nc(module), BlinkAppC.nc(configuration) 두개로 구성 되어 있습니다.모든 어플은 top-level이 필요 하다고 했죠. 여기서 top-level은 BlinkAppC 입니다. BlinkC.nc 는 실제로 Blink 어플의 기능을 제공 합니다. 그럼 여기서 바로 나오죠.. BlinkAppC 파일은 BlinkC.nc파일을 다른 컴포넌트와 엮기 위해서 사용 하는 겁니다.

여기서 Module 과 configuration 을 나누는 이유는 system designer는 바로 바로 구성하고 개발자는 라이브러리 모듈을 제공 하여 개발할 수 있기 때문이다.그래서 디자이너가 실제로 없는 모듈을 사용해서 개발 가능 하고 개발자가 그 모듈을 만들어서 줘서 어플을 완성 할 수도 있게 되는 것이다. 그래서 모듈과 configuration 파일은 서로 다른 폴더에 있어도 상관 없다.

File Name File Type
Foo.nc Interface
Foo.h Header File
FooC.nc Public Module
FooP.nc Private Module

tinyOS 에서 추천하는 파일 포맷은 다음과 같으니 참조 하자.

이제 실제로 소스를 다음장 부터 보도록 하자.


, .
다시 시작..

정말 열심히 해보자구요.

Lesson1 TinyOS 2.0 을 시작해요~

이판엔 TinyOS프로그램을 컴파일 해서 모트에 넣는 방법, 기본적인 컴포넌트모델 컨셉, TinyOS docs를 생성 하고 따라가는 방법등을 설명 할 예정 입니다.

컴파일과 인스톨

첫번째~~~!!!! 그 유명한 Blink를 설치 합니다.

모트가 없다면?~~!!! TOSSIM기반으로 컴파일 해서 테스트 하실수 있습니다. 여기서 토심은 TinyOS 시뮬레이터 입니다. 오~~

TinyOS는 make를 사용 하며, 아주 아주 make 환경이 잘되어 있어서 새로운 플랫폼을 더하거나...옵션등을 쉽게 변경 하실 수 있습니다. make는 tinyos-2.x/support/make에 있으니 참고 하세요

시작을 위한 첫번째 점검 사항은 환경을 점검 하는 겁니다. tos-check-env로 환경을 점검하세요
(*전 Graphicviz에서 에러 났습니다만 docs만드는데 문제 없어 패스 했습니다.)

결과로 출력된건 대충 영어되면 해석 가능 할 겁니다. 그리고 큰문제가 있다고 판단되면. tinyos-help 여기에 가입하고 한번 요청을 해보세요(단 .. 영어를 잘하셔야 할겁니다.^^) 또는 여기를 검색해보세요. help archives 비슷한 문제를 찾으실 수 있을 겁니다.(이것도 .. 영업니다.)-그리고 생각보다.. 없네요 자료가 ㅡ.ㅡ; -

위에서 체크해서 문제가 생기면.. TinyOS tools를 점검 하세요. RPM으로 인스톨 했다면 /usr/bin, /usr/local/bin 을 살펴보고, CVS로 깔았다면 컴파일 하고 인스톨 해야 한다니 tinyos-2.x/tools/tinyos로 가서 configure,make,make install을 순서대로 치세요.

그리고 위 세과정을 인스톨 하기전엔 왠만하면 root계정으로 하세요.

환경을 살펴 보았다면 이제 build System을 체크 할 시간 입니다. echo $MAKERULES를 통해서 체크하세요. /opt/tinyos-2.x/support/make/Makerules가 나와야 합니다.
위와 같이 안나온다면 shall을 사용해 꼭 설정 하세요. export를 사용 하시면 됩니다.(bash 쓰시죠 다들 ^^?)

자 이제 실제로 컴파일 하고 설치 해봅시다.

해당 어플 디렉토리로 이동 하세요 Blink는 apps/Blink 입니다. 그리고 가지고 있는 하드웨어에 따라서 make [hardware]를 치세요~

EX) telosb 는 "make install telosb" 입니다. TOSSIM을 사용 하신다면 "make micaz sim"입니다.

자 이제 실습입니다.~~ 자
, .

windows 2003 설치후 서비스팩 2 적용후

위와 같은 http://www.vmware.com/info?id=28 에러 날 경우

해당 vmx 파일을 에디터로 열어

다음 항목을 추가 한후 종료후 다시 시작 해보세요

paevm = "TRUE"

입니다. 있는 사람도 있고 없는 있을 것 같은데..

전 없어서 항목 추가 했습니다.

이제 또 부팅 되는 군요..

남들 잘 일어 나지 않는다는데.. 이게 뭔일인지 원.. 암튼 컴터도 최신형을 써야 하는겁니다 ㅡ.ㅡ;

, .