ver.0.9 TinyOS 프로그래밍 KETI/ Ubiquitous Technology Research Center(www.keti.re.kr) TinyOS Korea Forum(www.tinyos.or.kr),,,, TinyOS Korea Forum, Jeonghoon Kang, 2007. All rights reserved. 본문서는비상업적목적으로수정없이재배포할수있습니다. jeonghoon.kang@gmail.com
1. TinyOS Kernel TinyOS는기존의 PC용또는임베디드시스템용 OS들과다르게한번에하나의애플리케이션만을실행한다. 기본적으로 TinyOS는센서로부터데이터를취득하여무선네트워크로전 송하는간단한동작을담당하기때문에, TinyOS의설계단계에서전원소모와메모리소모가많아지게할수있는여러개애플피케이션이동시에동작되는기능은제외하였다. 다만, 여 러가지기능을동시에동작시키고자할때에는하나의애플리케이션에, 아주작은단위로 동작을세분화하여태스크(Task) 형태로동작시킨다. 결국, TinyOS 커널은이런특징때문에하나의 main() 함수로구성되어있다. TinyOS 커널의동작순서에대한이해에앞서, nesc로작성된소프트웨어의컴파일순서를이해해야한다. nesc로작성된코드는 nesc 컴파일러에의해 C 언어로변환된다. C 언어로변환된후 GCC(GNU C 컴파일러) 에의해기계수준의바이너리파일로컴파일된다. 컴 파일은 make 를이용하여진행되며( 예, make telosb), nesc의 C 변환과컴파일이한번에이 루어진다. 컴파일과정에서사용되는 nesc 파일 (*.nc) 들은내용에따라해당디렉토리에분산되어있는데, make 시에포함되는(include) 옵션을분석하여찾을수있다. 컴파일된바이너리파일을플랫폼에다운로드한후, 전원을인가하면하드웨어초기화와 커널초기화가이루어진다. 이후 TinyOS 의커널이동작하게된다. TinyOS 커널은단순한 FIFO 형태의스케줄러로동작을하며, 이스케줄러는전원이꺼질때까지무한루프(loop) 에서동작한다. < 부팅후플랫폼동작순서 > 전원이켜졌을때의동작은 MainM.nc 파일에서분석할수있다. MainM component의위치는 make 파일을분석하여위치를찾을수있다. MainM은 nesc가 C언어로변환될때사용되는 main() 함수를포함하고있다. 아래 MainM component는텔로스b(telos revision B) 용소프트웨어컴파일에사용되는것 이다. 전원이켜지면 main() 의첫번째줄인 call hardwareinit() 부터실행된다. hardwareinit() 은하드웨어, 즉, 센서와칩들에대한초기화를실행한다. 하드웨어초기화후에, 스케줄러 초기화를위한 TOSH_sched_init() 을호출하여스케줄러의변수와태스크큐(Task Queue) 를초기화한다. call StdControl.init() 과call StdControl.start() 는각애플리케이션에서사용하는component 들의초기화를위한 command 이다. 이 command는각 component들이사용되기위해필요한초기화루틴(routine) 을포함하고있으며, 애플리케이션에서사용되는 component가많은경우에는각component의stdcontrol 코드가모두선택되어이위치에서호출된다. 애플리케이션초기화가 StdControl.init(), StdControl.start() 룰통해이루어진후에는하드웨 - 1 -
어인터럽트를 nesc_enable_interrupt() 를통해동작시키고무한루프에서TinyOS 커널, 즉, TOSH_run_task() 로TinyOS 태스크스케줄러를동작시킨다. module MainM { } uses command result_t hardwareinit(); uses interface StdControl; implementation { } int main() attribute ((C, spontaneous)) { } call hardwareinit(); TOSH_sched_init(); call StdControl.init(); call StdControl.start(); nesc_enable_interrupt(); for(;;) { TOSH_run_task(); } < MainM 의 main() > TinyOS 커널(Kernel) 의구조도는초기화다음에무한루프에빠지면서하나의함수를실행시키고슬립(Sleep) 상태로바뀌게되는것을표현하고있다. MainM component의 main() 에서무한루프로들어가게되면, 아래그림의 " Task Queue Empty? " 부분에서시작되며, 초기화후에는 Task Queue 가비어있으므로바로슬립(Sleep) 상태로바뀌게된다. 애플리케이션동작을실행시키기위해발생하는것이하드웨어인터럽트(Interrupt) 이다. 이런인터럽트기반에서초기화소프트웨어동작은중요한의미를가진다. 초기화된루틴후에플랫폼은슬립상태로존재하고하드웨어인터럽트가발생함에따라하드웨어인터럽트에관련된동작을수행하며수행이완료되면다시슬립상태가된다. 이런반복적인하드웨어인터럽트에따라동작하는것이 network embedded system 의가장큰특징이다. - 2 -
< TinyOS Kernel, Task Scheduler > main() 함수에서 StdControl 에의해초기화할때설정해놓은타이머(Timer) 등의하드웨어 인터럽트들이발생하면해당인터럽트서비스루틴으로빠지게된다. 위그림에서는인터럽트 벡터를통해, 해당이벤트핸들러로동작이수행된다. 이벤트핸들러의동작이종료되면다시 Task Queue Empty? 부분으로돌아가다음하드웨어인터럽트를기다리게된다. 센서네트워크가아닌, 지금까지의 PC, 임베디드시스템에서 OS들은인터럽트서비스루틴에서간단한작업만을한다. OS 코어에게인터럽트가발생하였다는표시만하고다시인터럽트를기다리는위치로간다. 이경우, OS는정해진시간마다인터럽트가발생했는지반복해서점검하게되고, 인터럽트가발생했을경우에는해당인터럽트를처리한다. TinyOS에서는 nesc 장점을살려서인터럽트가발생하게되면실시간(Real-Time) 으로해야 될동작을바로수행한다. 이런방식을통해대부분짧은처리시간을갖는인터럽트핸들 러로구성된 TinyOS 애플리케이션을효율적으로실행시킨다. 기존 OS들처럼하드웨어에서 발생한인터럽트를처리하게되면이벤트관리함수가많아지게되며, 메모리와전력사용이추가되는단점이발생한다. 이벤트핸들러에따라서동작들이수행되고, 실행되는동작들중에일부함수는실행할때일반적인호출방식이아닌태스크(Task) 라는방식으로실행시킬수있다. 이때, 포스트 (post) 라는키워드를쓰게된다. 그렇게되면여기서실행되는함수들이곧바로실행되지않고 Task Queue 에그함수의주소를입력하게된다. 그렇게되면태스크형태의함수를제외한함수들이다실행된후에, Task Queue 에함수주소가있는지없는지를확인하게된다. 태스크함수가있다면이함수의주소에해당하는함수를실행을시켜(Run Task) 주고, Task 에주소가없어질때까지태스크의실행을반복한다실행이완료되면에실행해야할함수의주소가없을것이고이때플랫폼은 Queue. Task Queue 어떻게보면 Sleep 상태로빠지게된다. Event Handler 에서호출하는태스크함수는곧바로실행이안되고, 추후에 안 - 3 -
다른일반함수들이다실행된후에동작되니이것은 Real-Time을보장하지못하는방법으로생각될것이다. 이 TinyOS의커널은메인함수에도봤듯이초기화하는과정이매우짧은시간동안이루어진다. 메인함수에서많은하드웨어와소프트웨어초기화명령이수행되었음에도불구하고짧은시간안에실행이이루어지기때문에이벤트핸들러에서수행하는코드의양이많아도전체적으로걸리는시간은짧기때문에, 함수하나를중간실행하지않고태스크큐에넣어주고이것의실행을나중으로미루고나머지함수들을실행해준후, Task Queue 에있는함수를실행해주어도상대적으로많은시간지연이발생하지않는다. 2.nesC 의특징 nesc는component( 컴포넌트) 기반의프로그래밍언어이기때문에여러가지장점이있다. Component를애플리케이션소프트웨어를만드는부품이라는의미로생각하는것이이해에도움이된다. 부품들을조립하면하나의시스템이만들어지듯이, 소프트웨어부품 (component) 들을잘연결하여조립하면쉽게하나의애플리케이션소프트웨어를만들수있다는것이 nesc 의가장큰장점이다. 임베디드네트워크환경에서의코드재사용성이많은프로그래밍언어이다. 만일, 1초마다 LED 가점등되는애플리케이션을만들고싶으면, 기본 component인main, 시간을관리하는 Timer, LED를관리하는LedC 세개의component를조립하면, 하나의애플리케이션을만들수있다. 조립은 interface( 인터페이스) 라는연결도구를이용한다. nesc의또하나의장점은컴파일시에하드웨어동작시에발생할수있는에러를체크할수있도록만들어져있다는것이다. Linux 등의 OS 에서는 ioctl(fd,tcsets,data); 방법으로 CPU 에연결되어있는디바이스를제어한다. 이방법은디바이스를지시하는 fd( 인자) 내 용이, 동작(running) 시에명령을내리는디바이스마다다르게되며, 시스템의특징에따라소프트웨어개발자가다른이름으로만들수있다. nesc 는이런방식과다르게, CPU에연결되 는각디바이스들를동작시키는컴포넌트로만들어놓고, 이컴포넌트를이용하기때문에 컴파일할때에적절한디바이스를사용했고, 이실제동작시에발생할수있는오류를컴파일과정중에체크할수있다. Linux 소프트웨어를컴파일할때, 플로우차트나어떤동작 이일어날것인가를컴파일러가파악하기는힘들다. fd 라는인자에어떠한디바이스가지정될지변수자체만으로는판단하기힘들고, 또각디바이스를제어하는명령을내릴때, 이것 이적절한명령인지등을파악할수없다. 센서네트워크디바이스처럼한정된개수의간단한주변디바이스를갖는경우, nesc로만들어진컴포넌트는소프트웨어의동작상태 (running) 다. 상태에서의오류를컴파일시에체크하고이를방지할수있는특징을지니고있 아래의그림은 Blink 라는애플리케이션의조립상태( 구조) 를보여주고있다. nesc의컴포넌트들은인터페이스를이용해서조립되는데, 아래그림에서 Main component는애플리케이션에반드시필요한최상위 component 이며, 이것이 SingleTimer, BlinkM component와각각의 StdControl interface 로연결되어있다. - 4 -
컴포넌트연결 조립상태도 < / > 3. nesc 프로그래밍 nesc의함수는commad와event 라는두가지함수를사용한다. command는일반적인 c 언어의함수와비슷하고, 명령의방향이상위소프트웨어에서하위하드웨어로호출된다. event 는하드웨어동작에대한이해가필요한데, command ( 명령) 에따른기능수행후에발생하는이벤트를호출하는함수이다. 2-Level Structure Command(Bottom direction) Non-time critical Long running operations Cannot preempt& can be preempted Background computation Events(Top direction) Time critical Small running operations Cannot be preempted Able to interrupt running Tasks TinyOS는 non Preemption 방식으로동작한다. 이는현재동작하고있는태스크를중지시키지못하고, 먼저실행되고있는태스크의수행이종료될때까지기다려야 하는방식을취하고있다. 다만하드웨어인터럽트는인터럽트서비스부문에서처리 되며, 모든수행중인동작보다우선적으로처리된다. 즉, 이전에수행되던태스크를정지시키고인터럽트핸들러가처리된다. Pre-emption 의개념 (www.wikipedia.org) Pre-emption as used with respect to operating systems means the ability of the operating system to preempt or stop a currently scheduled task in favour of a higher priority task. The scheduling may be one of, but not limited to, process or - 5 -
I/O scheduling etc. Non-preemptability arises, for instance, when handling an interrupt. In this case, scheduling is avoided until the interrupt is handled. Making a scheduler preemptible has the advantage of better system responsiveness and scalability. The schedulers used in most modern operating systems, such as various flavours of Unix, can preempt user processes. This is called preemptive multitasking, and is in contrast to cooperative multitasking wherein a process "gives away" its time by utilizing kernel resources or by specifically calling a kernel routine to allow other processes time to run. Some operating systems' schedulers (including Linux as of the 2.6 series) have the ability to preempt a process while it is processing a system call as well (a preemptible kernel). Linux, Unix, *BSD, Mac OS X, and Windows NT are all examples of operating systems that utilize preemptive multitasking; Netware, Windows for Workgroups, and Macintosh System 9 are all examples of cooperative multitasking operating systems. nesc 의특징은아래와같으며, 제약적인프로그램메모리와램메모리때문에, 대부분의경우 static( 정적) 메모리할당을하여, 컴파일시에플랫폼에서사용될메모리의크기를결정한다. [nes-si:] Network Embedded System C Language Supports TinyOS Make applications for Network Embedded system No dynamic memory allocation Extension of C programming language Efficient code for micro-controllers AbletointeractwitholdCcode Many C Programmer C is little helpful for safe code& structuring applications nesc와c 는동일한문법을따르고있고, nesc에추가된개념이component( 컴포넌트) 와Interface( 인터페이스) 이다. Component는일종의부품으로써소프트웨어를개발할때사용하는부품으로사용된다. 기능을모아놓은부품으로, RF 통신의기능이필요하다면해당 Component를사용하면된다. Component 들을연결하여원하는기능의소프트웨어를만들어가는데, 사용하는 component 들간에는 interface( 인터페이스) 를사용하여연결한다. Interface는각 component 들이제공하는기능 (command, event) 를정의하는데사용 - 6 -
된다. Component 는아래와같이 *.nc 파일의형태로존재하며, 세부적으로 Component는 Module, Configuration 으로구분된다. Module xxxm.nc Code file Configuration xxx.nc/oooc.nc Wiring of components Define wiring of Modules Interfaces xxx.nc Contains only definition Commands/Events 모듈(module) 은실제실행되는코드인함수가존재하는파일이다. 확장명은*.nc 이다. 모듈은여러개의함수를지원하는파일이며, 인터페이스를통해해당함수들이구현된다. 여기서인터페이스를통해함수들이제공(provides) 되거나사용(uses) 되는방법은주 의해서이해해야한다. 일반적으로함수를코드로구현해서제공하고, 원하는곳에서 호출하여사용하는것이C 언어에서함수를사용하는방법이다. nesc에서는일반c와 다르게그냥함수를구현하여제공만하지않는다. 인터페이스라는것은일반C와다르게함수를두가지로분류한다. 커맨드(command) 와이벤트(event) 이다. 모듈은 provides 키워드로제공할커맨드함수를정할수있다. 제공된커맨드함수는다른모듈에서호출하여사용할수있다. provides interface Leds 는 Lesd.nc 인터페이스파일에정의되어있는커맨드함수들을모듈파일내에서구현하여, 다른모듈에서호출하여사용할수있다. 반대로모듈은 uses 키워드로다른모듈에서제공하는커맨드함수를호출하여사용할수있다. 위에서예를든, provides interface Leds; 에대응되는코드는 uses interface Leds; 이다. uses 키워드는인터페이스 Leds.nc 파일에정의되어있는커맨드함수를호출할수있다는의미이다. - 7 -
uses 키워드는한가지의미를더포함하고있다. 이것은 nesc 프로그래밍언어의문법을이해하는초기에가장이해하기힘든부분이다. uses interface Leds; 는 Leds.nc 에정의되어있는이벤트(event) 함수를구현해야함을의미한다. 만약, Leds.nc 파일에정의되어있는이벤트가없는경우도있다. provides 와 uses 의사용방법은아래그림과같이, 하나의컴포넌트에서 provides 키워드로인터페이스를제공하고다른쪽컴포넌트에서는uses 키워드를사용하여해당인터페이스에정외된커맨드와이벤트를사용한다. 사용한다는의미는, 제공되는커맨드를호출할수있다는것이며, 이벤트를구현하는것이다. < 그림> 컴포넌트와인터페이스연결예 위그림에서, App.nc 는 Component-1.nc 와인터페이스 Interface-1.nc 로연결되어있다. Component-1.nc에서 provides interface Interface-1; 로인터페이스를제공하며, App.nc에서 uses interface Interface-1; 로Interface-1 을사용한다. 이를통해서, App.nc에서는 Interface-1.nc 에정의되어있는커맨드함수를호출할수있으며, Interfacd-1.nc 에정의되어있는이벤트를구현한다. 커맨드함수를호출하는것은일반 C 언어에서의함수호출과동일하다. 이벤트는기존의 C 언어에서의함수중함수포인터를이용한Callback 함수호출과동일한기능을제공한다. 하드웨어에서인터럽트가발생하면그에해당하는이벤트함수가실행된다. 어떤모듈에서 uses interface Timer; 코드를이용하여 Timer 인터페이스를사용하 - 8 -
면, Timer.nc 에정의되어있는커맨드함수를호출할수있으며, Timer.nc에정의된이벤트함수를구현해야한다. 모듈과인터페이스는각커맨드, 이벤트함수를구현하고호출, 실행시키기위한방법에대해설명하였다. nesc에는이런모듈을그룹화하여추상화하기위해서는컨 피규레이션컴포넌트를사용할수있다. 컨피규레이션은여러모듈을서로연결 (wiring) 하여그룹화하고, 외부컴포넌트가기능을사용할수있도록해당인터페이스를제공(provides) 한다. < 그림> 컴포넌트, 인터페이스파일 위그림에서와같이컴포넌트인컨피규레이션, 모듈과인터페이스는확장명이*.nc 이다. 파일이어떤종류인지는파일내부를확인해봐야한다. 반드시정확하지는않지 만는컨피규레이션을의미하고는모듈임을의, CC2420RadioC.nc, CC2420RadioM.nc 미한다. - 9 -
Component Configuration Module Provides Uses Interface Command Event Task Post Interface Command/ Event, (command), (event). < 그림> 컴포넌트, 컨피규레이션 위그림은컴포넌트의예를보여준다. 이컴포넌트는이름이 Blink인컨피규레이션이다. 39 줄처럼선언되어있고, 42줄과같이Main, BlinkM, SingleTimer, LedsC, UART 컴포넌트를사용한다. 이컴포넌트들은컨피규레이션또는모듈이며, Main.nc, BlinkM.nc, SingleTimer.nc, LedsC.nc, UART.nc 의파일로존재한다. 이파일들은현재디렉토리에위치하거나, 또는컴파일러가사용하는경로중에존재한다. - 10 -
컨피규레이션에서는컴포넌트의이름은명시적으로표시되어있지만, 어떤것이인 터페이스인지에대해서는해당파일에명시적으로표현되고있지않다. 따라서컴포 넌트들의이름과와이어링상태를확인하여, 해당파일을일일이열어서코드를읽어 보면알수있다. 43줄Main.StdControl 의경우는Main 은42줄에따라컴포넌트임을알수있다. 그러나 StdControl 에대한선언은없다. 컨피규레이션에서컨포넌트와인 터페이스를구분하는. 의사용을이해하면, 추가적인파일을읽지않아도쉽게컴포넌트와인터페이스를구분할수있다. C 언어는. 의역할이구조체의멤버변수를구분할때사용한다. nesc에서도비슷하게컴포넌트에서제공또는사용하는인 터페이스를소속을개념으로파악하면비슷한의미를갖는다.. 은소속의의미를갖는다고할수있다. 컨피규레이션에서. 앞쪽은컴포넌트를의미하고, 뒤쪽은컴포넌트에소속된인터페이스를의미한다.. 의사용은추후설명할모듈에서는동일한소속의의미를갖으나, 인터페이스에소속된커맨드또는이벤트함수를의미하기때문에코드분석시에주의해야한다. 43줄 Main.StdControl -> SingleTimer.StdControl; 은 Main 컴포넌트와 SingleTimer 컴포넌트가어떻게연결(wiring) 되어있는지를표현한다. Main과SingleTimer는 StdControl 이라는인터페이스로연결된것이며, SingleTimer가StdControl 인터페이스를제공하고Main이StdControl 인터페이스를사용한다. SingleTimer.nc 파일에는 provides interface StdControl; 이라는코드가포함되어있고, Main.nc 에는 uses interface StdControl; 이라는코드가포함되어있다. 따라서StdControl.nc 파일에정의되어있는커맨드함수들이 SingleTimer.nc 파일에구현된다. StdControl 은이벤트함수가없지만, 만약에있다면, 해당이벤트들이Main.nc 에구현될것이다. -> (wiring) 의의미는제공(provides) 와사용 (uses) 의관계를표현한다. 제공이라 는의미와는다르게화살표방향이제공과는반대로되어있다. 이기호의의미를해석할때실제커맨드함수가구현된코드가어느곳에있는지코드의위치를지시하 고있다고해석해야한다. 와이어링은 -> 과 =, 두가지기호가있다. = 기호에대해서는추후설명한다. 46 줄은인터페이스를생략한경우다. 42줄처럼 LedsC는컴포넌트라는것을알수있고, 일반적인경우에는컴포넌트뒤에. 이찍히고이어서인터페이스이름이적혀있어야하지만, 여기서는생략되어있다. 컴포넌트들은동일한인터페이스로연결되어야하기때문에생략하여도컴파일러는해당인터페이스를찾을수있다. - 11 -
- 12 -
< 그림> 컴포넌트, 모듈 모듈은인터페이스를제공또는사용하며, 커맨드와이벤트가실행될수있도록구현한다. 즉, C 언어의함수처럼실행되는코드를제공한다. 36줄은 BlinkM 이라는모듈을정의하고있으며, 이모듈은인터페이스StdControl 을제 공하고, Timer, Leds, StdControl, ByteComm 인터페이스를사용한다. 36줄부터 45줄까지는모듈 BlinkM 에대해속성을선언한것으로, 제공하는인터페이스의커맨드들이구현 될것이며, 다른컴포넌트에서제공하는인터페이스들을사용하여호출하고이벤트를사용할것을표현한다. 37, 38줄은 StdControl 인터페이스를제공(provides) 하고있음나타내며, 다른컴포넌트 에서는이인터페이스를사용(uses) 할수있다. 제공하는 StdControl.nc 인터페이스파일 에정의된커맨드함수들이 BlinkM.nc 파일하단에코드로구현된다. StdConrol.nc 파일을확인해보면, command StdControl.init(), command StdControl.start(), command StdControl.stop(), 세가지커맨드를정의하고있다. 40에서 45 줄까지는사용(uses) 하는인터페이스를의미한다. 사용하는인터페이스는 다른컴포넌트에서제공하는인터페이스의커맨드함수를호출하여실행할수있고, 그 인터페이스에이벤트함수가정의되어있다면, 이벤트함수를구현하여실행시킨다는의미를갖고있다. 줄의 인터페이스파일은 41 Timer.nc commnad Timer.start(type, sec), command - 13 -
Timer.stop() 의두커맨드함수와 event Timer.fired() 의한개이벤트함수가정의되어있다. BlinkM 모듈에서는다른컴포넌트에서제공하는 Timer 인터페이스의커맨드함수를호출하여실행시킬수있으며, Timer.fired() 를반드시구현하여해당이벤트발생시실행할수있도록해야한다. 다만, 이벤트발생시에실행할것이없으면, 함수의중괄호안을공란으로비워두면된다. BlinM 컴포넌트에서사용되고있는다른인터페이스인도동일한방법으로커맨드함수, 이벤트함수를사용한다. Leds, ByteControl, ByteComm 43 줄의 " as " 키워드는하나의컴포넌트안에서동일한인터페이스가여러번다른목적으로사용될때, 중복사용으로인한혼동을막기위해사용하는키워드이다. 실제는 StdControl 이지만, 38줄의인터페이스와구분하기위해 as로사용이름만변경한것이다. 사용하는인터페이스의커맨드함수의구현된코드를보기위해서는, 상위컨피규레이 션에서의연결관계를찾아실제코드가위치를파악해야한다. 실제실행되는코드를 찾기위해서는상위컨피규레이션파일을확인해야한다. 41줄은Blin.nc 컨피규레이션을통해SingleTimer.nc에서제공되는Timer 인터페이스를사용하고있다. < 그림> 인터페이스 - 14 -
< 그림> 인터페이스 인터페이스는컴포넌트와컴포넌트간의커맨드와이벤트의제공, 구현을명시하는역 할을한다. 인터페이스파일에정의된커맨드와이벤트함수만이컴포넌트간에연결될 수있으며, 인터페이스에정의되지않은함수는해당파일에서만개별적으로사용된다. 즉, 개발자가어떤기능을구현하여외부다른컴포넌트에제공하고자한다면, 인터페이 스파일을구현하고, 그에맞도록컴포넌트를작성해서제공해야한다. 반대로, 어떤기 능을사용하고자할때는, 그기능이구현된컴포넌트에서제공하는인터페이스를사용 (uses) 한다는것을명시적으로표현해야한다. 위그림중, Timer.nc 인터페이스는41줄에서헤더파일인Timer.h를include 하고있다. interface Timer는 command result_t start(char type, uint32_t interval); 59 줄, command result_t result_t stop(); 68 줄, event result_t rired(); 73 줄을정의하고있다. 여기서 command 들은 Timer 인터페이스를제공하는컴포넌트에서구현되며, event 는 Timer 인터페이스를사용하는컴포넌트에서구현된다. - 15 -
module PTimer{ provides interface Timer; } implementation{ } command result_t Timer.start(){ dosomething(); dosomething(); return SUCCESS; } command result_t Timer.stop(){ dosomething(); dosomething(); return SUCCESS; } 위예제와같이 PTimer 모듈은 Timer 인터페이스를제공(provides) 하고, Timer.nc 인터페이스파일에정의된command인Timer.start() 와Timer.stop() 을반드시제공해야한다. module UTimer{ provides interface GoUse; uses interface Timer; } implementation{ } command result_t GoUse.dosomething(){ call Timer.start(); call Timer.stop(); return SUCCESS; } command result_t Timer.fired(){ dosomething(); dosomething(); return SUCCESS; } 반대로 Timer 인터페이스를사용(uses) 하는모듈에서는위예제와같이 Timer.nc 에 정의되어있는 command 함수를 call 키워드를이용해서호출, 실행시킨다. 이 command 함수들은연결(wiring) 되어있는컴포넌트에구현되어있다. 연결(wiring) 을확인하가위해서는 UTimer 의연결상태를표현하고있는, 컨피규레이션파일을확인해야 한다. - 16 -
configuration UApp{ } implementation{ components Main, UTimer, PTimer; } Main.StdControl-> UTimer.StdControl; Main.StdControl-> PTimer.StdControl; UTimer.Timer-> PTimer.Timer; configuration 연결(wiring) 상태는상위컨피규레이션을확인해야한다. 위내용처럼 UTimer 에서사용(uses) 하는 Timer 인터페이스는 PTimer 에서제공(provides) 되었다는연결(wiring) 을해주어야한다. < 그림> 태스크 태스크의정의는위예제처럼 task 키워드로정해주며, 리턴타입은 void 로해준다. 태스크의실행을위해서는 post 키워드를사용하여호출하며, 이태스크의실행은바로실행되지않고, 일반 command 와함수들이실행된후로순서가뒤쪽으로스케줄링된다. 이런태스크의실행은리소스가한정된무선플랫폼에서중요한의미를갖는다. 빠르게실행되는스케줄이정해진동작에비해, 스케줄에자유로운태스크들을 post 키워드를통해플랫폼리소스를효율적으로할당할수있다. atomic 키워드는 atomic { } 범위안에서는하드웨어인터럽트가발생되지않도록정의하는것이며, 이벤트(event) 함수에서전역변수를사용할때, 컴파일러가경고 (warning) 를표시한다. 이경우는컴파일러가변수의race condition 을경고하는것이다. 이벤트함수는언제나발생할수있기때문에, 여러이벤트함수에서동일한변수를처리하면, 변수의변경순서를보장할수없다. 만약, 개발자가변수의race condition을확신하고여러개이벤트의실행에따른변수변화를허용한다면, 변수선언시에 no_race 라는키워드로컴파일러경고(warning) 을제거할수있다. - 17 -
4. VMPlayer 개발환경 VMPlayer를이용한 TinyOS 개발환경구축은 Linux, Windows, MACOS 등의다양한플랫폼에서일관된개발환경을구축할수있다는장점때문에, 많이사용되고있다. 그러 나 Linux / Unix 개발환경에익숙하지않은개발자들에겐몇가지기본적인사용방법이제공되어야한다. 이장에서는VMPlayer(2.0 이상) 과TinyOS 개발환경 Fedora 이미지 (Kmote Release) 소프트웨어를이용한설치, 사용방법에대해설명한다. VMPlayer 를설치하고, TinyOS 개발환경 Fedora 이미지를하드디스크에복사한다. 를실행하고의위치를지정한다 VMPlayer, virtual machine configuration file. 위같은창이나타나면를선택한다일반적으로컴퓨터가변경되면나타난다그외의질문들에대해서는최소또는확인을선택한다., Create.. 가리눅스를부팅하는화면이지나가면로그인 메시지를출력하며로그 VMPlayer issue, - 18 -
인을기다린다. issue 메시지를살펴보면, root / tinyos 로로그인할수있음을알수있다. VMPlayer 창으로들어가려면마우스로클릭하고, VMPlayer에서빠져나오려면 ALT-CTRL 키를동시에누른다. 로그인후에는 tinyos를입력하여로그인메시지를볼수 있다. 일반적으로는 startxfce4 를실행하여가벼운윈도우를실행시키며, gnome 환경을실행시키기위해서는 startx 를쉘프롬프트에서실행하면된다. 앞으로는 XFCE 환경을기본으로설명한다. 위와같은그림은윈도우가실행된상태이며좌측최상단의아이콘을이용해서터미, 널을실행시킨다. - 19 -
초기에는 TinyOS-1.x 개발환경으로설정되어있다. 위처럼 VMPlayer가동작하고키보 드의제어권이VMPlayer으로넘어간상태에서Kmote를USB 포트에연결하면, 아래그림 처럼 VMPlayer의제목표시줄에 Future Technology Devices USB Device 라는탭이생긴다. 이버튼은토글되며, 눌려있는경우는 VMPlayer 가제어권을갖고, 안눌려있는경우는 Windows 가제어권을갖는다. 아래그림들은 Fedora Linux 상태에서 TinyOS 개발을위해입력한몇개의명령어예제이다. motelist 는현재어떤 USB 포트에 mote 가연결되어있는지를확인할수있으며, make telosb는 telosb 플랫폼에맞게애플리케이션코드를컴파일하라는명령이며, make telosb reisntall,1 bsl,/dev/ttyusb0 는 USB0 포트로컴파일된 telosb 실행바이너리이미지를다운로드하라는명령이다. source /opt/env.scripts/env.opt.tinyos2.x 는 tinyos-2.x 개발환경으로변경하라는명령이다. VMPlayer 를사용하여, 윈도우에서작업할경우에가장문제시되는것이윈도우( 호스 - 20 -
트 OS) 와리눅스( 게스트 OS) 간의파일공유이다. Samba 를이용하여, 네트워크공유로윈도우와리눅스간의파일공유하는방법은윈도우즈탐색기에서해당주소를 \ \ 192.168.1.100 입력하면된다. 리눅스의 IP 주소를얻기위해서는아래그림처럼, 프롬포트쉘에서ifconfig 명령을입력한다. 윈도우에서 \ \ 192.168.1.100 을입력하면, 아래와같은창이나타난다. 이에 ID, Password를 tinyos / tinyos 로입력하면, 리눅스의 /share 디렉토리에직접접근할수있다. - 21 -
- 22 -
5. 그외사항들 TinyOS 개발환경 DVD http://www.tinyosmall.co.kr/shop/shopdetail.html?brandcode=016002000001&search=& sort=brandname Xubuntos 의경우는아래링크참조 http://sing.stanford.edu/klueska/running_xubuntos_vm.html 은 VMPlayer 1.03 USB 사용시에에러발생함 FedoraID-root/PASSWORD-tinyos 주요명령어 (shell command) cd, ls, ls -al, mkdir, rmdir, cp, env, env grep TOS, source, grep -rn tinyos *, find./-name good, clear, exit, printenv 윈도우즈에서공유디렉토리설정 공유 directory에 tinyos-1.x source tree copy ifconfig mount.cifs//192.168.1/1/tinyos/opt/mnt.win umount/opt/mnt.win /etc/profile.d/tinyos.sh 생성 export TOSROOT=/opt/mnt.win/tinyos-1.x export TOSDIR=$TOSROOT/tos export MAKERULES=$TOSROOT/tools/make/Makerules echo $TOSDIR echo $MAKERULES export MOTECOM=serial@/dev/ttyUSB0:telos 윈도우즈에서생성한파일( 스크립트) 가동작을안할경우 envt1 파일을공유중인윈도우즈디렉토리에만들었을경우반드시 dos2unix envt1 이라는명령으로 unix 파일형태로변환시켜줘어야함 - 23 -
변환하지않았을때에는 source envt1 이라고해도제대로동작을안함윈도우상에서 envt1을만들고리눅스쉘에서 dos2unix 명령을한번실행해주면됨 make telosb reinstall.2 라는명령을내렸을때, make가동작을안하면 안의모든파일들의모드를 /opt/tinyos-1.x/tools/make 777 예 )chmod 777* 채널, 그룹아이디,RF 세기바꾸기기본적으로는 로변경 /opt/tinyos-1.x/tools/make/makelocal 을고칩니다. Makelocal 내용을아래와같이바꾸면됩니다. 또는/opt/tinyos-1.x/apps/Blink 내에있는Makefile 에추가해줘도됩니다. DEFAULT_LOCAL_GROUP=0x01 PFLAGS +=-DCC2420_DEF_CHANNEL=12 PFLAGS +=-DCC2420_DEF_RFPOWER=31 PFLAGS +=-DDEFAULT_BAUDRATE=38400 채널은 11~26/ RF Power는 1~31 컴파일및다운로드명령 make telosb make telosb reinstall make telosb install make telosb reinstall.1 make telosb install.1 bsl,/dev/ttyusb0 Windows에서공유디렉토리생성 ifconfig 로현재windows의IP 확인 mount.cifs//192.168.12.1/tinyos /mnt 파일의경우 삼바이용방법 ifconfig 로현재 chmod 777, dos2unix Linux IP 확인 로상태변경필요 - 24 -
윈도우즈의폴더주소표시줄에 \ \ 192.168.111.11 과같이주소입력 id:tinyos /password:tinyos 문제발생시 vi/etc/samba/smb.conf 에있는 IP Allow 부분에 ifconfig 에서확인하IP가접근가능하도록설정되었는지확인 ------------------------------------------------------------------------------------------------------------- nesdoc 만드는방법내부의 /opt/tinyos-1.x/apps make telosb docs application 중에한곳에서 cd /opt/tinyos-1.x/doc/nesdoc/telosb firefox/opt/tinyos-1.x/doc/nesdoc/telosb/index.html OscilloscopeRF 의동작센서를 TelosB 에있는빛센서로변경하기 InternalTempC.nc 컴포넌트file 찾는방법: 찾기시작할디렉토리찾고자하는파일이름예, find /-name*internaltempc.nc* HamamatsuC.nc 컴포넌트로변경한다. find { }-name{ } ------------------------------------------------------------------------------------------------------------- Java 실행방법 - SerialForwarder java net/tinyos/sf/serialforwarder& 실행되는윈도우창에서히변경해준다 - Oscilloscope serial@/dev/ttyusb0:telos 로자신의시스템에맞게정확 java net/tinyos/oscope/oscilloscope& 화면에그래프가안그려지면, scroll 또는 zoom out Y, 버튼을눌러준다. Surge 실행방법 java net/tinyos/surge/mainclass 0x7d& ------------------------------------------------------------------------------------------------------------- 를이용한와간의파일공유 Samba windows Linux 사용법 - 25 -
ifconfig 를쳐서, Linux의IP 확인탐색기에서 \ \ windows 192.168.11.1 id:tinyos,password:tinyos 문제발생시 이라고치면공유폴더가보임 vi/etc/samba/smb.conf 에있는 IP Allow 부분에 ifconfig 에서확인하여현재작동중인IP가접근가능하도록설정되었는지확인 Linux에서 Windows 를마운팅하는방법 ( 되도록이면위에설명한samba 사용을권장합니다.) mount.cifs//192.168.11.1/tinyos /mnt ------------------------------------------------------------------------------------------------------------- TinyOS 2.0 설치방법 http://www.tinyos.net/tinyos-2.x/doc/html/install-tinyos.html TinyOS 의사용을위해서는크게두가지단계로설치를진행하여야한다. 첫번째는개발환경 ( 컴파일러, 리눅스환경등) 의설치이고, 두번째는 TinyOS 소스코드설치이 다. TinyOS 개발환경으로는 Linux 실행환경을위한 Cygwin 설치, 호스트소프트웨어를위한 JAVA 설치, Mote 용소프트웨어를위한컴파일러설치, 환경변수설정이필요하다. TinyOS 코드설치는 CVS(http://en.wikipedia.org/wiki/Concurrent_Versions_System) 서버로부터소스코드를다운받아설치하는것이필요하다. 1.Java1.5JDK 설치 Download and install Sun's 1.5 JDK from http://java.sun.com TinyOS 1.x의 Java 실행환경을위한 Javax Comm API 는 www.tinyos.re.kr 의 files 게시판에서찾아설치한다. 2. Linux 환경설치- Cygwin 설치(Linux 사용하는경우필요없음) http://www.tinyos.net/dist-1.2.0/tools/windows/cygwin-1.2a.tgz 3. Mote 용컴파일러설치 - 26 -
TI MSP430 용컴파일러또는에서아래와같이실행하여설치 Cygwin Linux Shell rpm-ivh msp430tools-base-0.1-20050607.cygwin.i386.rpm 만일os 또는dependancy 문제가발생하면아래와같은옵션으로실행 rpm-ivh--ignoreos--nodeps--force msp430tools-base-0.1-20050607.cygwin.i386.rpm 아래rpm 파일들을순서대로설치(Windows 경우5 개, Linux 경우7 개) Tool Windows/Cygwin Linux base msp430tools-base-0.1-20050607.cygwin.i386.rpm msp430tools-base-0.1-20050607.i386.rpm python tools msp430tools-python-tools-1.0-1.cygwin.noarch.rpm msp430tools-python-tools-1.0-1.noarch.rpm binutils msp430tools-binutils-2.16-20050607.cygwin.i386.rpm msp430tools-binutils-2.16-20050607.i386.rpm gcc msp430tools-gcc-3.2.3-20050607.cygwin.i386.rpm msp430tools-gcc-3.2.3-20050607.i386.rpm libc jtag msp430tools-libc-20050308cvs-20050608.cygwin.i386.rpm Not yet available msp430tools-libc-20050308cvs-20050608.i386.r pm msp430tools-jtag-lib-20031101cvs-20050610.i3 86.rpm gdb Not yet available msp430tools-gdb-6.0-20050609.i386.rpm 4. TinyOS Toolchain(nesC, tinyos-tools) rpm-uvh nesc-1.2.8a-1.cygwin.i386.rpm 또는 rpm-uvh--ignoreos--nodeps--force nesc-1.2.8a-1.cygwin.i386.rpm 로설치 nesc: nesc-1.2.8a-1.cygwin.i386.rpm tinyos-tools: tinyos-tools-1.2.3-1.cygwin.i386.rpm 5. Graphviz 설치 nesc document를생성하기위한에서다운로드하여설치한다. 를 Graphviz http://www.graphviz.org/download..php - 27 -
6. 환경변수설정 cygwin, Linux shell 에서는 export, unset 명령으로환경변수를추가, 제거할수있다. TinyOS의개발환경에작성되어있는 Makefile은아래와같은환경변수가설정되어야컴파일등의작업을수행할수있다. TinyOS 2.0 의경우는아래와같이환경변수가설정되어야한다. TOSROOT=/opt/tinyos-2.x TOSDIR=$TOSROOT/tos MAKERULES=$TOSROOT/support/make/Makerules CLASSPATH=`cygpath-w $TOSROOT/support/s 아/java/tinyos.jar` CLASSPATH="$CLASSPATH;." PATH=/opt/msp430/bin:$PATH 각환경변수를추가하기위해서는아래와같이 export 명령을이용해수행해야한다. export TOSROOT=/opt/tinyos-2.x env grep TOS 같은명령으로현재설정되어있는환경변수를확인할수있다. 환경변수를하나씩매번등록하는것은비효율적이므로, 하나의파일, 예를들면 envt2 라는파일에 6 줄의환경설정내용을작성해놓고, shell 상에서 source envt2 라고실행하면환경변수가모두적용된다. TinyOS 1.0의경우는 TOSROOT=/opt/tinyos-1.x, 로변경해주면된다그리고해당 MAKERULES=/opt/tinyos-1.x/tools/make/Makerules. JAVA. 하는 경로로변경하면된다 [TinyOS Source code Download] TinyOS 환경변수설정에맞게 TinyOS source code 가위치해야한다. 일반적인방법으로는 TinyOS source tree rpm 파일을다운로드받아설치하지만, 항상업데이트되는상태를유지하기위해서는 cvs 도구를이용하여 cvs 서버로부터다운로드받고, 필요시마다업데이트하는것이좋다. - 28 -
CVS 클라이언트는 www.tortoisecvs.org 를사용하는것이간편하다. 설치후바탕화면에서마우스오른쪽버튼을누르면아래와같이 checkout 이라는항목이생성된다. pop-up 메뉴에 CVS Protocol은 pserver, Server는 tinyos.cvs.sourceforge.net ( 또는 tinyos.cvs.sf.net), Repository folder 는 /cvsroot/tinyos, user name은 anonymous, module은 tinyos-1.x 또는 tinyos-2.x 로적어주면, tinyos-1.x/ tinyos-2.x 소스코드를다운로드받을수있다. - 29 -