Translated by bruce, bruceKim.egloos.com >

Lesson 4: Mote-PC serial communication and SerialForwarder

Last updated June 27 2006

이번 레슨의 목표는 mote에서 PC로 어떻게 통신(communicate)하는지 보여주는 것이다. 이것은 network로부터 데이터를 수집하는 것이나, mote로 command를 보내거나 network traffic을 모니터링 하는 것을 허용한다. 이번 튜토리얼은 mote들과 통신(communicating)하기 위해 Java 기반으로 구현되어진 것을 보여줄 것 이다. /sdk/c 디렉토리에서 C 기반으로 구현된 것도 또한 찾아볼 수 있다. 더 자세한 사항은 mig 와 ncg 의 man page를 봐라.

Packet sources and TestSerial

첫 번째 step은mote와의 통신으로 여러분의 PC에서 데이터를 받아올 수 있는가를 체크하는 것이다. 대부분의 mote들은 serial 포트 또는 비슷한 인터페이스를 가지고 있다. 예를 들어 mica 계열은 serial port로 직접적으로 컨트롤 할 수 있다.:

프로그래밍 보드는 기본적으로 보드 위에 실제 serial port로 mote의 serial pin들에 접속한다. Telos mote는 역시 serial 인터페이스를 가지고 있다. 그러나 그것은 USB 하드웨어로 통신하며, 기능적으로 유사하나 케이블이나 커넥터등의 조건이 매우 다르다.

mote대 PC간 통신의 기본적인 추상화(abstraction)는 packet source이다. packet source는 정확하게 말하면: application이 mote로부터 패킷을 받거나 보낼수 있는 통신 매체(communication medium)이다.

packet source들의 예로는 serial port, TCP socket 그리고 SerialForwarder 툴과 같은 것을 포함한다. 대부분의 TinyOS 통신 툴(communication tool)은 옵션으로 –comm 파라미터를 취한다, 그 파라미터에 packet source를 문자열로 명시하면 되겠다. 예를들어:

$ java net.tinyos.tools.Listen -comm serial@COM1:telos

위의 내용은 Listen tool이 telos mote의 baud rate speed에서 COM1 serial port(윈도우 머신 상에서)를 사용하여 통신하라는(tell) 것을 말한다.

$ java net.tinyos.tools.Listen -comm serial@/dev/ttyS0:micaz

위의 내용은 micaz mote의 baud rate speed에서 serial port /dev/ttyS0 (UNIX 머신 상에서) 를 사용하여 통신하라는(tell) 것을 말한다. 여러분의 serial port를 테스트하기 위한 첫 번째 step으로 /apps/tests/TestSerial application을 mote에 인스톨한다. 이 application 은 매 초마다 serial port로 패밋을 보낸다. 그리고 serial port로 패킷을 받으면 패킷의 순서 번호 (sequence number)를 LED에 디스플레이한다. 여러분이 TestSerial를 한번 인스톨을 했다면, 여러분은serial port로 mote와 통신하는 Java application 을 실행하기를 필요로 할 것이다. 이것은 여러분이 TinyOS application 을 build 했을때 만들어진다. application 디렉터리에서 다음을 타이핑 해라:

$ java TestSerial

만약 다음과 같은 메시지를 보게 된다면

The java class is not found: TestSerial

그것은 java code로 컴파일 하지 못했거나( make platform 을 다시 해봐라) java 가 없다는 것을 의미한다. CLASSPATH 의 값을 한번 검사해봐라 (echo $CLASSPATH 하면 됨)

여러분이 packet source를 명시하지 않은 이유로, TestSerial 은 SerialForwarder에서 기본값을 돌려줄 것이다.(오류 난다는 얘기) 여러분이 SerialForwarder를 실행하지 않은 이래로 TestSerail은 종료 될것이고 mote로 접속할 수 없다고 불평할 것이다. 그래서 source로서 serial port를 명시해주자. serial source 의 문법은 다음과 같다.

serial@<PORT>:<SPEED>

PORT 는 여러분의 플랫폼 및 mote가 플러그된 곳에 종속적이다. Windows/Cygwin 플랫폼에 대해 그것은 COMN 이며 N은 포트 넘버이다.

Linux/UNIX 머신에 대해 그것은 serial port에 대해 /dev/ttySN 이고 /dev/ttyUSBN(USB로 쓸 때) 또는 serial over USB port에 대해 /dev/usb/tts/N 이 될 것이다. (N은 포트 넘버)

lesson 1에서 본 것같이 추가적으로 Linux에서 여러분은 이 serial port 를 쓸 권한을 만들어줘야한다. 슈퍼유저 권한에서 다음과 같은 명령어를 실행해라.

chmod 666 serialport

SPEED는 정수 값이거나 플랫폼의 이름이 될 수 있다. (여기서 SPEED는 baud rate) 플랫폼의 이름을 명시하는 것은 플랫폼의 디폴트 speed를 사용하는 것을 serial packet source에게 말하는 것이다.

유효한 플랫폼은 다음과 같다.

Platform / Speed (baud)
telos / 115200
telosb / 115200
tmote / 115200
micaz / 57600
mica2 / 57600
mica2dot / 19200
eyes / 115200
intelmote2 / 115200

Java 파일인 support/sdk/java/net/tinyos/packet/BaudRate.java 는 이러한 매핑을 정의하고 있다. TinyOS 1.x에서는 다르게 모든 플랫폼이 공통의 serial packet format를 가진다. 다음 테이블에 따르면 이러한 두 serial 명세는 일치한다.

serial@COM1:micaz

serial@COM1:57600

만일 여러분이 적절한 PORT와 SPEED를 세팅하고 TestSerial를 실행한다면 다음과 같은 출력을 볼 수 있을 것이다.

Sending packet 1

Received packet sequence number 4

Sending packet 2

Received packet sequence number 5

Sending packet 3

Received packet sequence number 6

Sending packet 4

Received packet sequence number 7

Received packet sequence number 8

Sending packet 5

Received packet sequence number 9

Sending packet 6

그리고 mote LED들은 깜빡일 꺼다.

Cannot find JNI error

만일 여러분이 TestSerial을 실행하려고 하는데 Java가 TOSComm JNI support를 찾을 수 없다는 에러를 받으면, 이것은 serial port 를 제어하는 Java Native Interface(JNI)파일이 올바르게 인스톨 되지 않았음을 의미한다.

tos-install-jni 라는 명령어를 실행해라 (리눅스에서 이것은 슈퍼유저로 실행해야 됨)

만일 이 명령어가 존재하지 않는다면 여러분은 tinyos-tools RPM을 설치하지 않았거나 정확하지 않게 설치된 것이다. tos- 으로 시작하는 명령어는 보통 /usr/bin에 설치되어있다. 만일 여전히 script를 찾을 수 없으면 tinyos-help로 메일 줘라.

CVS sources로부터 tos-install-jre를 설치하기

만일 tools RPM을 설치하지 않았고, TinyOS CVS 저장소로부터 직접 작업하지 않았으면, 여러분은 매뉴얼적으로(일일히 하라는 얘기) tos-locate-jre 스크립트를 설치할 수 있다. tinyos-2.x/tools/tinyos/java 로 가라. 만일 그 디렉터리에 Makefile이 존재하면 make를 타이핑하고(다시, 리눅스에서는 슈퍼유저로) make install를 타이핑 해라. 만일 Makefile이 없으면 tinyos-2.x/tools 로 가서 다음을 타이핑 해라.

$ ./Bootstrap

$ ./configure

$ ./make

$ ./make install

그러고 나면 tos-install-jni 가 여러분의 시스템에서 serial support를 설치 될 것이다.

MOTECOM

만일 여러분이 –comm 파라미터를 안쓰면, tools는 packet source를 위한 MOTECOM 환경 변수를 체크할 것이다. 그리고 MOTECOM에 아무것도 없으면, 그것들은 SerialForwarder를 위한 기본값을 사용할 것이다. 이것이 의미하는 것은 만일 여러분이 항상 serial port를 통해 mote와 통신 하려면, 여러분은 MOTECOM 부터 세팅하여야 하고 세팅하면 –comm 파라미터를 명시하는 것은 더 이상 필요치 않다. 예를 들어:

export MOTECOM=serial@COM1:19200 # mica baud rate

export MOTECOM=serial@COM1:mica # mica baud rate, again

export MOTECOM=serial@COM2:mica2 # the mica2 baud rate, on a different serial port

export MOTECOM=serial@COM3:57600 # explicit mica2 baud rate

MOTECOM 환경 변수를 세팅하고 –comm 파라미터 없이 TestSerial 를 실행해봐라.

BaseStation and net.tinyos.tools.Listen

BaseStation은 basic TinyOS utility application (기본적인 tinyos 유틸리티 프로그램이라는 말)이다. 그것은 serial port와 무선 network 사이에 브릿지 역할로서 행동한다. serial port로부터 패킷을 받았을 때 그것은 무선으로 전송한다. 그것이 무선으로 패킷을 받았을때는, serial port로 전송한다. 왜냐하면 TinyOS는 serial port 를 통해 mote로 패킷을 보내거나 생성하는 툴체인을 갖기 때문이다. BaseStation 은 mote networks와 직접적으로 통신하는 PC tools을 허용한다.(뭐 허용한다는 말이 원래 그래 라는 말인 것같음)

lesson 3에서 봤던 BlinkToRadio를 한 노드에 인스톨하고 다른 하나에는 BaseStation 을 인스톨해라. 만일 여러분이 BlinkToRadio가 인스톨되어진 상태로 mote를 동작시키면 BaseStation 의 LED 1(micaz에서는 녹색)이 깜빡이는 것을 볼 수 있다. BaseStation 은 무선으로 패킷을 보낼 때 LED 0을 토글하고(micaz에서 빨간색) serial port로 패킷을 받았을 때 LED 1을 토글한다. 패킷이 드랍됐을때는 LED2(노란색)을 토글한다. 이것은 두개의 패킷이 있을 때 두개 중 하나가 다른 하나보다 빠를때 발생 한다.(예, micaZ는 256kbps로 무선 패킷을 받지만, serial로는 57.6kbps를 보낸다 : 역 무선네트워크로는 데이터를 빨리 받는데 시리얼로 받은 만큼 빨리 처리를 못해줘서 드랍되는 패킷이 생길 수 도 있다는 말 같다.)

BaseStation 은 BlinkToRadio 로부터 패킷을 받거나 serial port로 패킷을 보낸다. 그래서 BaseStaion이 PC와 연결(plugged)되어있다면 우리는 이러한 패킷을 볼 수 있다. Java tool인 Listen은 기본 패킷 스니퍼이다.: 그것은 받은 어떤 패킷의 바이너리 컨텐츠를 출력한다. Listen 을 MOTECOM 이나 –comm 파라미터를 이용해서 실행하다.

$ java net.tinyos.tools.Listen

Listen은 packet source를 생성하고, 그것을 계속 프린트하여 보여준다. 여러분의 출력은 다음과 비슷하게 보일 것이다.

00 FF FF 04 22 06 00 02 00 01

00 FF FF 04 22 06 00 02 00 02

00 FF FF 04 22 06 00 02 00 03

00 FF FF 04 22 06 00 02 00 04

00 FF FF 04 22 06 00 02 00 05

00 FF FF 04 22 06 00 02 00 06

00 FF FF 04 22 06 00 02 00 07

00 FF FF 04 22 06 00 02 00 08

00 FF FF 04 22 06 00 02 00 09

00 FF FF 04 22 06 00 02 00 0A

00 FF FF 04 22 06 00 02 00 0B

Listen은 mote로부터 오는 패킷을 간단히 출력한다. 각 데이터 패킷은 mote가 포함하는 데이터의 몇가지 필드이다. 첫번째 바이트 (00) 은 그 패킷의 AM packet을 가르킨다. 다음 필드는 generic Active Message fields이며 tinyos-2.x/tos/lib/serial/Serial.h 에 정의되어있다. 마지막으로 메시지의 데이터 payload가 나머지 필드에 온다. 그것은 BlinkToRadio.h에 정의되어있다.

typedef nx_struct BlinkToRadioMsg {

nx_uint16_t nodeid;

nx_uint16_t counter;

} BlinkToRadioMsg;

BlinkToRadioC application 에 대한 전체적인 메시지 포맷은 다음과 같다.( 처음의 00바이트는 무시해라)

·  Destination address (2 bytes)

·  Message length (1 byte)

·  Group ID (1 byte)

·  Active Message handler type (1 byte)

·  Payload (up to 28 bytes):

o  source mote ID (2 bytes)

o  sample counter (2 bytes)

그리고 우리는 다음처럼 데이터 패킷을 번역할 수 있다.

dest addr / msg len / groupID / handlerID / source addr / counter
ff ff / 04 / 22 / 06 / 00 02 / 00 0B

source address는 mote ID를 여러분이 BlinkToRadio application 을 인스톨할 때 뭘 줬는지에 의존한다. 기본값은 (만약 ID 를 아무것도 명시하지 않았다면) 00 01 이다. data는 big-endian 포맷으로 mote에 의해 보내진다는 것을 유의해라.

예를 들어 01 02 는 258을 의미한다. (256 *1 + 2)

이 포맷은 processor의 engian 표기법에 독립적이다. 왜냐하면 패킷 의 포맷은 nx_struct이기 때문이다. (nx_struct 는 network format인 big-endian 바이트 정렬이다.) message payload에 대해 nx_struct nx_struct를 사용하는 것은 ( 표준 C struct를 보다 오히려) platform 에 상관없이 작동하는 것을( will work across) 확실히 한다. 여러분이 packet들을 스크롤해서 본다면, 여러분은 BlinkToRadio app가 그자신의 카운터를 증가시키는 것처럼 counter 필드값이 증가하는 것을 볼수 있을 것이다.

MIG: generating packet objects

MIG: 패킷 objects 생성하기

Listen 프로그램은 mote와 통신하는 기본적인 방법이다. 그것은 단지 스크린에 바이너리 패킷을 출력할 뿐이다. 분명히 이 프로그램을 이용해 센서의 데이터를 떠올리는 것은 쉽지않다. 우리가 정말 원하는 것은 센서 network 로부터 데이터를 검색하거나 관찰하는 더 좋은 방법이다. 물론, 정확하게 데이터를 디스플레이하고 어떤방법으로 비쥬얼하게 보려면 application 을 보다 더 명시적(specific)이어야 할 수 있다.

이러한 이유로 TinyOS는 몇가지 간단한 센서 데이터를 비쥬얼적으로 하는 application 을 가지고 있다.(다음 lesson에서 여러분은 Oscilloscope application 을 사용할 수 있을 것이다.), 그러나 그것은 새로운 visualization 또는 logging systems에 대한 support를 제공한다.

Listen에서 한 문제점은 그게 단지 이진 데이터를 덤프할 뿐이라는 거다. 사용자는 byte단위로 읽어야 하고, 주어진 패킷 포맷으로 그것들을 parse(분석)해야 한다. TinyOS 툴체인(toolchain)은 패킷 분석 으로부터 메시지 object를 자동으로 생성하는 것에 대해 툴을 제공하여 더 쉽게 이러한 process를 가능하게 한다.

패킷 포맷을 수작업으로(manually) parse(‘분석’의 의미 정도?)하기 보다 , 여러분은 메시지 구조가 Java, Python, 또는 C interface로 빌드하는 mig(Message Interface Generator) tool을 사용할 수 있다. 주어진 바이트들의 순서에서 MIG-생성된 코드는 패킷의 필드 각각을 자동으로 parse하고, 받은 패킷이나 새로 생성된 하나(one?)의 출력을 위한 표준 accessors와 mutator을 제공한다.

mig toold은 세개의 기본 인자를 갖는다. 어떤 프로그램 언어로 코드를 생성하냐(Java, Phython, C), 어디서 구조체를 찾을꺼냐, 구조체의 이름은 뭐냐. 이렇게 세개!

tool은 또한 include에 대한 –I나 define에 대한 –D와 같은 표준 C 옵션을 취한다. TestSerial application 을 보자, 예를 들어 mig를 사용하는게 serialport를 통해 패킷을 parse하고 쉽게 create한단다. (머 의미상 ㅎㅎ) TestSerial 폴더로 돌아가서 make clean;make platform를 타이핑 하면 다음과 같은 내용을 볼수 있을 것이다.

rm -rf build *.class TestSerialMsg.java

rm -rf _TOSSIMmodule.so TOSSIM.pyc TOSSIM.py

mkdir -p build/telosb

mig java -target=telosb -I%T/lib/oski -java-classname=TestSerialMsg TestSerial.h TestSerialMsg -o TestSerialMsg.java

javac *.java

compiling TestSerialAppC to a telosb binary

ncc -o build/telosb/main.exe -Os -O -mdisable-hwmul -Wall -Wshadow -DDEF_TOS_AM_GROUP=0x66 -Wnesc-all -DCC2420_DEF_CHANNEL=19 -target=telosb -fnesc-cfile=build/telosb/app.c -board= -I%T/lib/oski TestSerialAppC.nc -lm

compiled TestSerialAppC to build/telosb/main.exe

6300 bytes in ROM

281 bytes in RAM

msp430-objcopy --output-target=ihex build/telosb/main.exe build/telosb/main.ihex

writing TOS image

TinyOS application 을 생성하기(building) 전에 Makefile이 TestSerialMsg.java를 생성하는 규칙이 있다. TestSerialMsg.java 뿐만아리나 TestSerial.java를 컴파일하고 나서 마지막에 TinyOS application을 컴파일한다. Makefile을 봐라, 우리는 BlinkToRadio 보다 몇가지 규칙을 더 가지고 있다는 것을 볼 수 있을 것이다.

COMPONENT=TestSerialAppC

BUILD_EXTRA_DEPS += TestSerial.class

CLEAN_EXTRA = *.class TestSerialMsg.java

TestSerial.class: $(wildcard *.java) TestSerialMsg.java

javac *.java

TestSerialMsg.java:

mig java -target=null -java-classname=TestSerialMsg TestSerial.h TestSerialMsg -o $@

include $(MAKERULES)

BUILD_EXTRA_DEPS 줄은 TinyOS application 의 build가 완성되기 전에 만족되어야 하는 추가적인 의존성들을 TinyOS make system 에게 말한다. (컴파일하기전에 뭐 환경변수같은거 미리 세팅해주는 의미정도?) Makefile은 serial 통신을 테스트하기위해 실행할 TestSerial.class라는 Java application을 make system에게 말한다.

The CLEAN_EXTRA line tells the make system extra things that need to be done when a user types make clean to clean up. CLEAN_EXTRA 줄은 사용자가 make clean 을 타이핑 했을 때 지워야 하는 나머지 것들을 make system에 알린다. BUILD_EXTRA_DEPS줄은 application 전에(?) TestSerial.class를 컴파일하기 위해 make에게 알린다.

TestSerial.class: $(wildcard *.java) TestSerialMsg.java

javac *.java

TestSerial.class가 디렉터리 안의 모든 .java파일 뿐만 아니라 TestSerialMsg.java에 의존한다는 것을 알린다. 한번에 이것들의 모든 의존성이 풀릴 때, make system은 javac *.java를 호출하고 TestSerial.class를 만든다. 마지막 라인으로,

TestSerialMsg.java:

mig java -target=null -java-classname=TestSerialMsg TestSerial.h TestSerialMsg -o $@

어떻게 TestSerialMsg.java가 만들어지는가를 make system에 알린다. 패킷으로 표현하는 Java class를 mote와 PC사이에 보낸다.(?) 왜냐하면 TestSerialMsg.java는 TestSerial.class에 의존하기 때문이다. make는 그것이 필요로 하게 되면 생성할 것이다. TestSerialMsg.java를 생성하기 위해 Makefile은 mig tool을 호출할 것이다. 다음으로 파라미터들을 하나 하나씩 보자.

mig / Invoke mig
java / Build a Java class
-target=null / For the nullplatform
-java-classname=TestSerialMsg / Name the Java class TestSerialMsg
TestSerial.h / The structure is in TestSerial.h
TestSerialMsg / The structure is named TestSerialMsg
-o $@ / Write the file to $@, which is TestSerialMsg.java

null 플랫폼은 mig를 사용할 때 타켓으로서 사용하기 편리한 특수한 플랫폼이다. 그것은 표준 시스템 컴포넌트를 포함한다. 그러나 더미는 아무것도 구현(implementation)하지 않는다. null 플랫폼에 대해 application 을 build하는 것은 쓸모없지만 mig가 packet의 레이아웃을 추출하기 위해 허용한다. BlinkToRadio의 Java packet object를 build하자. BlinkToRadio의 Makefile을 열고서 다음 dependency(의존)을 추가해라.

BUILD_EXTRA_DEPS=BlinkToRadioMsg.class

그리고나서 어떻게 .java가 .class로 컴파일하는가를 설명하는 단계를 추가해라.

BlinkToRadioMsg.class: BlinkToRadioMsg.java

javac BlinkToRadioMsg.java

javac 앞에는 오직 한 tab문자가 와야하며 space문자들로 되면 안된다는 것을 주위해라

마지막으로 BlinkToRadioMsg.java가 어떻게 생성되는지를 설명하는 줄을 추가해라.

BlinkToRadioMsg.java:

mig java -target=null -java-classname=BlinkToRadioMsg BlinkToRadio.h BlinkToRadioMsg -o $@

mig 이전에도 javac에서 처럼 탭문자 하나만 와야한다.(space문자들이 아님) 이제, 여러분이 BlinkToRadio/에서 make를 타이핑 했다면 make system은 BlinkToRadioMsg.class를 컴파일 할 것이다. 그러면 Java class는 메시지 필드안의 바이너리 패킷들을 method들을 통하여 접근할 수 있어서 적절히 parse 해줄 것이다. 한가지 step이 더있다, 뭐냐하면 여러분이 컴파일했을 때, 아마 이러한 경고를 보게 됐을 때.

warning: Cannot determine AM type for BlinkToRadioMsg

(Looking for definition of AM_BLINKTORADIOMSG)

TinyOS 통신 toolchain의 한 부분은 패킷의 종류가 무엇인지 상응하는 AM type이 있어야하는 것을 요구한다. 이것을 정의하기위해, 패킷의 이름이 X라면 mig는 AM_X 의 형식을 상수로 취해서 볼것이다. 우리가 AM type을 AM_BLINKTORADIO로 정의한 이유로(경고가 나오는 것이고) mig는 AM_BLINKTORADIOMSG를 원한다. BlinkToRadio.h을 다음 정의하는 것처럼 바꿔라. 여러분은 또한 BlinkToRadioAppC.nc파일을 업데이트할 필요가 있을것이다. AMSenderC와 AMReceiverC가 그것을 참조 하고 있었으니까. application 을 다시 컴파일 해라. 그러면 여러분은 경고메시지가 안나오는 것을 볼 수 있다. mote 하나에 인스톨 해라.

이제 우리는 Java message class를 가졌다. 우리는 메시지의 출력으로부터 그것을 사용할 수 있으며 BaseStation으로부터 볼 수 있다. BaseStation을 serial port에 연결하고(plugged) 다른 하나의 mote에는 BlinkToRadio를 실행하고 BlinkToRadio 디렉터리에서 다음을 타이핑 해라.