이제 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는 이전에 번역한걸 재 편집 할 예정 입니다~~



, .