2009년 8월 30일 일요일

Synchronized Low-power Protocol

동기 방식 저전력 프로토콜은 멀티홉 네트워크에서 time sync를 유지하면서 active/sleep 스케줄링을 하도록 설계되어 있다.
32KHz로 동작하는 자신의 타이머를 이용하여 time stamp를 얻고, 자신의 시간 정보를 broadcasting한다. 시간 정보를 담고 있는 sync 메시지를 받은 노드들은 자신의 시간 정보와 수신된 시간 정보를 비교하여 업데이트한다.
  • routing message : minimum cost를 계산하여 route-path를 설정하기 위한 메시지
  • sync message : 시간 동기화를 위한 메시지로 자신의 시간 정보를 브로드캐스팅
  • period : active/sleep 주기를 설정
  • duty cycle : 한 주기 동안 동작 가능한 비율
period가 길고 duty cycle이 큰 경우 좋은 성능을 나타낸다.



다음의 원문은 주기를 이용한 duty cycle 적용 방법이다.

Boomerang lowpower works upon the principle of synchronised global time known to all motes in the network. All synchronised motes then go to sleep and wake up at the same time (duty cycle). All messages are sent/received within this duty cycle. Messages queued to sending outside this time are simply buffered until the next duty cycle.
In Boomerang this is managed by 2 components, netSync which handles global time and netWake which handles the wake/sleep mechanism.

If you have access to a Boomerang environment, run the Trawler application compiled for lowpower. There you can see that messages may arrive at an inconsistent rate, but they all arrive eventually.
Boomerang allows you to change the duty cycle via the lowpower parameter of make.
The NETSYNC_PERIOD_LOG2 macro allows you to change the time between listening periods

by default NETSYNC_PERIOD_LOG2 is 16 i.e. 2**16 ticks of the 32khz clock is 2 seconds. Default lowpower is 5% .
5% of 2 seconds is 100msecs. So by default you listen for 100msecs every 2 seconds.
Suppose I want 100sec every 4 seconds, set NETSYNC_PERIOD_LOG2 to 17 ( 4 seconds) and lowpower to 3 (3% of 4 seconds = 120msec)

Add the following line to your makefile

ifeq ($(filter netsync_period_log2,$(MAKECMDGOALS)),netsync_period_log2)

then do

make lowpower,3 netsync_period_log2,17

2009년 8월 27일 목요일

xubuntu에서 압축 해제

tar 압축 파일 중 노틸러스에서 자동으로 압축이 풀리지 않는 파일이 간혹 있다.
이 경우 터미널을 이용하여 압축을 해제하면 된다.

tar로 생성된 파일은
# tar xvf

tgz나 tar.gz는
# tar xvfz

와 같이 하면 된다.

2009년 8월 26일 수요일

MAC ack & retransmission

retransmission 기능을 사용할 때는 AMPromiscuous + Queue 조합을 사용하는데, 1hop adhoc mode의 경우는 이것이 불필요할 뿐더러 programmer-controllable하지 않은 부분이 추가되는 단점이 있음. 따라서 AMStandard component를 사용하면서 retransmission을 적용하는 것이 필요하다.

reliability를 높이기 위해 retransmission 기능을 사용하고자 할 때는 다음과 같이 설정한다.

0. 설정
  •    /opt/tinyos-1.x/tos/lib/CC2420Radio/CC2420RadioM.nc에서 bAckEnable = TRUE;로 설정
  •    /tos/system/AMPromiscuous.nc에서 crc_check = TRUE;로 설정
  •    /tos/lib/Queue/QueueSendM.nc에서 retransmit = TRUE;로 설정

1. Application에서 MacControl Component를 wiring
        configuration Test {
        }
        implementation {
           component CC2420RadioC;
           ...
           TestM.MacControl -> CC2420RadioC;
        }
           
2. StdControl.start() 에 MacControl.enableAck() 을 추가
        module TestM {

          provides {
          ...
          }
          uses {
             interface MacControl;
              ...
          }
         implementation {
            ...
            command result_t StdControl.start() {
            call MacControl.enableAck();
            }
            ...
         }

3. tos/lib/CC2420Radio/CC2420RadioM.nc
  • BackoffTimerJiffy.fired() 에서 case TIMER_ACK 의 if (!post PacketSent()) 를 주석처리. 이것 때문에 ACK이 오지 않더라도 ack timeout 시 sendDone에 SUCCESS가 return된다.
  • sendDone event callback에서 success == FAIL 인 경우 바로 msg ptr을 retransmission. 필요에 따라 retransmission counter를 두고 max_retransmission을 초과할 경우 drop
4. 멀티 홉 과 재전송 기능을 사용할 경우에 발생하는 문제 및 해결 방법
  • opt/tinyos-1.x/lib/Queue/QueuedSendM.nc 는 TinyOS의 메시지 전송 큐를 관리한다. 재전송 기능도 QueuedSendM 에서 수행된다.

event result_t SerialSendMsg.sendDone[uint8_t id](TOS_MsgPtr msg, result_t success) {
...
if (!retransmit \\ msg->ack != 0 \\ msgqueue[dequeue_next].address == TOS_UART_ADDR) {
// 재전송이 필요 없는 경우 큐의 포인터를 다음 패킷으로 이동시키고,
// 상위 컴포넌트로 메시지 전송 성공 이벤트 발생 (signal, SUCCESS)
...
} else {
...
if ((++(msgqueue[dequeue_next].xmit_count) > MAX_RETRANSMIT_COUNT)) {
// 최대 재전송횟수를 초과했을 경우 큐의 포인터를 다음 패킷으로 이동시키고,
// 상위 컴포넌트로 메시지 전송 실패 이벤트 발생 (signal, FAIL)
...
}
}
// 데이터 전송 Task 실행
post QueueServiceTask();

return SUCCESS;

}

테스트는 멀티홉 라우팅 기능을 사용하며, 라우팅 경로를 빨리 설정하기 위해 라우팅 메시지 전송 주기를 짧게 설정하였다. 그리고 모트 3개 정도에 프로그램을 올리고 테스트 한 결과 재전송이 계속 발생하지만 Base Node에 패킷이 수신되지 않는 현상이 발생하였다. 문제의 원인을 파악한 결과, 라우팅 메시지는 Broadcast 를 사용하며 Broadcast도 이 QueuedSend 의 큐를 통해 전송이 일어나고, Broadcast에 대해서도 재전송을 수행하기 때문이었다.
따라서 위 소스를 그대로 사용하여 재전송 기능을 사용할 경우, Broadcast 하는 패킷에 대한 Ack 가 없을 경우에도 계속 재전송을 하게 되어 Breadcast가 많을 경우 Queue Overflow가 발생할 수 있으며, 쓸데 없이 계속 재전송을 수행하게 된다.
(※ 수신 노드에서는 unicast 일 경우에만 ack 메시지를 전송한다)
이 문제를 해결하기 위해서 위 소스의 if 문 조건을 다음과 같이 변경하여야 한다.

if ((!retransmit) \\ (msg->ack != 0)  \\ (msgqueue[dequeue_next].address == TOS_UART_ADDR) \\ (msgqueue[dequeue_next].address == TOS_BCAST_ADDR)) {
...
}

2009년 8월 25일 화요일

Sensor...

센서 노드에 탑재되어 있는 센서들은 보통 14bit ADC, 또는 12bit ADC를 가지고 있다.
이는 표현할 수 있는 한계를 의미하는데 SHT11의 온도센서의 경우 14bit로 4800까지 표현이 가능하다. 하지만 더 큰 값도 간혹 나오기도 한다. 12bit ADC를 사용하는 센서는 2의 12승, 즉 4096까지 출력 된다.
더욱 큰 값을 출력하고자 한다면 12bit보다 좋은 ADC를 연결하면 가능하다.

Packet Loss...

telosb 계열의 모트에서 사용되는 라디오 모듈인 CC2420 RF Chip은 802.15.4 규격에 의해 2.4GHz 대역에서 250Kbps의 최대 통신 속도를 가진다. 그러나 이는 통신(전파) 환경이 깨끗한 상태에서의 1:1 통신의 경우에 해당된다. tinyos는 기본적으로 csma/ca방식을 사용하여, 현재 RF채널이 사용되고 있는지 확인 후 없으면 얼마의 시간지연 후에 데이터를 전송하게 된다.
예를 들어, 100 bytes의 데이터를 전송하는데 약 3 ms의 시간이 걸리는데, 데이터 전송 전에 필요한 Random Backoff 시간과 RF와 CPU간의 통신 및 레지스터 설정 등의 시간을 고려할 경우 약 5ms 정도의 전송 시간이 필요한 것이다.
멀티홉으로 통신하는 경우에는 센서 노드가 서로에게 영향을 줄 수 있다. 즉, 시간 지연이나 패킷 손실을 일으킬 수 있다. 특히 중간단에 위치한 노드들은 말단에 위치한 노드들이 보내는 패킷을 모두 수신하고, 이를 또 상위 노드에 전송하므로 여기에서 손실이 발생할 가능성이 매우 크다. 또한, Radio의 경우와는 다르게 UART의 손실이 발생할 가능성도 있다. UART의 통신 속도등이 패킷 손실을 불러올 수도 있다.

http://www.ee.kth.se/php/modules/publications/reports/2005/2284.pdf http://www.cs.berkeley.edu/~arsalan/Papers/PacketDelivery_Poster.pdf

T1에서의 ADC Mapping

ADC를 사용할 때 주요 인자가 2가지가 있다.
reference 전압과 resolution 이다. mica 시리즈에서 사용되는 atmega128L의 경우 보통 reference 2.56V, resolution은 10bit를 사용하는데, telos 계열에 사용되는 msp430의 경우 reference 1.5 or 2.5V, resolution은 12bit를 사용한다. 따라서 mica 계열로 했을 때와 telos 계열로 했을 때의 ADC에서 읽히는 Raw값에 대한 전압계산식은 다르다.

다음은 ADC를 매핑하는 예이다.
ADCC 컴포넌트를 사용하여 ADCControl 인터페이스와 bindPort 커맨드를 이용한다.
========================================================================
** Test.h **
#include "MSP430ADC12.h"
enum {
TOS_ADC_TEST_PORT = unique("ADCPort"),
TOSH_ACTUAL_ADC_TEST_PORT = ASSOCIATE_ADC_CHANNEL ( INPUT_CHANNEL_A0, REFERENCE_VREFplus_AVss, REFVOLT_LEVEL_2_5),};

#define MSP430ADC12_Test ADC12_SETTINGS( \ INPUT_CHANNEL_A0, REFERENCE_VREFplus_AVss, SAMPLE_HOLD_4_CYCLES, \ SHT_SOURCE_ACLK, SHT_CLOCK_DIV_1, SAMPCON_SOURCE_SMCLK, \ SAMPCON_CLOCK_DIV_1, REFVOLT_LEVEL_1_5)

** Test.nc **
configuration Test {
}
implementation {
components Main, TestM, ADCC;
Main.StdControl -> TestM;
TestM.ADC -> ADCC.ADC[TOS_ADC_TEST_PORT];
TestM.ADCControl -> ADCC;
}

** TestM.nc **
module TestM {
provides interface StdControl;
uses interface ADC;
uses interface ADCControl;
}
implementation {
command result_t StdControl.init() {
call ADCControl.init();
call ADCControl.bindPort(TOS_ADC_TEST_PORT, TOSH_ACTUAL_ADC_TEST_PORT);
return SUCCESS;
}
.....
}

zigbee & tinyos

제목대로 둘의 관계는 본질적으로 다른데 웹을 뒤적거리다 보면 터무니 없는 이야기가 많아서 자칫 헷갈리기 쉽다.
그래서 이 둘을 파헤쳐 본다.
이 둘의 관계를 좀 더 명확히 하자면 IEEE 802.15.4 (PHY와 MAC) 표준에 zigbee를 사용하는지 tinyos를 사용하는지가 다르다면 다르다.

먼저 zigbee와 IEEE 802.15.4의 관계를 보자.
zigbee 표준 = IEEE 802.15.4 + zigbee spec
IEEE 802.15.4 = PHY + MAC
zigbee spec = NWK + APS + (security, ZDO)

그렇다면 tinyos는
tinyos = IEEE 802.15.4 + tinyos
IEEE 802.15.4 = PHY + MAC
tinyos = OS + (MAC) + APS

위와 같이 구성된다.

2009년 8월 24일 월요일

Node ID

식별 가능한 Node ID는 0~65565 까지 지정해서 사용이 가능하며, 보통 0번은 베이스 노드로 사용한다.
보통 센서 노드의 ID를 부여하는 방법은, 인스톨할 때 뒤에 숫자를 붙여서 노드 ID를 부여한다. 그러나 이것은 어디까지나 임시적인 방법이다. 즉, 다른 노드들도 같은 ID를 가질수가 있기 때문이다. 이런 것을 Short Address 라고 해서 RF통신상에 트래픽을 줄이기 위해 사용한다. IEEE 802.15.4에서는 이 Short Address 외에 64bit의 고유주소를 사용한다. (EUI64) 비슷한 예로, 보통 인터넷에서 IP주소 외에 실제적으로 통신하기 위해 쓰이는 NIC 고유주소가 있는데, (이것도 MAC주소 혹은 번호라고 보통 칭한다.) 그것은 그 네트워크장치가 다른 어떤 장치와도 같지 않음을 보장해야 한다. 그래서 IEEE에서 일정부분의 일련번호를 받은 제조회사가 그 나머지 부분에 대해 겹치지 않도록 하여 제품 생산시에 기록하게 된다. 센서네트워크에서도 64bit의 주소를 용하는데 그 중 앞의 24bit는 IEEE에서 부여받은 번호를 나머지 40bit는 제조회사가 겹치지 않도록 부여 한다. 모트의 경우, 보통 이러한 40bit에 대해 제조사가 일일이 번호를 부여하기 어려우므로, DS2411과 같이 고유의 ID를 가진 칩을 사용하여 이 칩이 가지고 있는 일련번호와 제조회사과 부여받은 번호를 합쳐서 사용하게 되는데 이를 이용하면 된다. 하지만 현재 센서 네트워크 시장규모나, 성장의 규모로 볼 때, 아직 이러한 고유번호들은 사용이 미흡한 상태이다.

- maxfor -

atomic

NesC에 자주 볼 수 있는 키워드 중에 atomic 이 있다.
atomic은 race condition을 막기 위해 존재한다.

race condition이란, 인터럽트에 의해서 발생하는
비동기적 코드들이 갑작스럽게 사용중인 전역변수에
접근하는 일이 발생했을때 일어나는 충돌을 말한다.

해결방법은 다음과 같다.
- 전역변수를 사용하지 않는다.
- 인터럽트를 사용하지 않는다.
- 되도록이면 코드를 짧게 구성한다.
- atomic키워드를 사용한다.

여기서 atomic코드는 모든 전역변수의 값을
정의할때,


atomic {
var1 = var1 + 1;
var2 = var2 -1;
}

이렇게 하게 되면, 만약 이 데이터를
처리 도중에 다른 인터럽트가 발생한다고 해도 이 데이터에
대한 선점권이 넘어가지 않으므로, 충돌은 일어나지 않게 된다.

2009년 8월 21일 금요일

Timer에 대한 진실(?) 혹은 거짓(?)

타이머가 매 3분 마다 호출되어도 매번 데이터를 전송하지는 않는다. 이는 통신 과정 중간에 task처리 과정과 rf 전송을 위해 경합하는 과정도 있기 때문에 고정된 시간에 데이터를 전송하는 것은 어렵다.

[TIP]
1024ms = 1 second
60 second * 1024ms = 61440ms(1 minute)
3600 second * 1024ms = 1 hour

센서 노드의 H/W 동작 범위

  • CC2420 : 2.1v ~ 3.6v
  • MSP430 : 1.8v ~ 3.6v
  • SHT11 : 2.4v ~ 5.5v

tinyos check

#/opt/tinyos-1.x/tools/script
#./toscheck

2009년 8월 18일 화요일

How to convert RSSI value to dBm?

Convert the unsigned raw counts (x) to a signed integer (y).

If x < 127; y = x
If x > 127; y = x - 256

Convert the signed counts (y) to RSSI in dBm, subtract -45 dBm
RSSI = y – 45 dBm

Example:
Raw Counts = 217
Convert to signed integer : 217 – 256 = -39
Calculate RSSI (dBm) : -39 – 45 = -84 dBm