19
Departamento de Engenharia Electrotécnica REDES AD HOC E DE SENSORES 2011 / 2012 Mestrado Integrado em Engenharia Electrotécnica e Computadores 4º/5º ano 7º/9º semestre Introdução ao desenvolvimento de aplicações em TinyOS 2.x http://tele1.dee.fct.unl.pt Luis Bernardo

REDES AD HOC E DE SENSORES 2011 / 2012tele1.dee.fct.unl.pt/radhoc_2011_2012/enuncs/enunc_radhoc_tinyos_20112012.pdf4º/5º ano 7º/9º semestre ... Para evitar problemas de portabilidade

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

Page 1: REDES AD HOC E DE SENSORES 2011 / 2012tele1.dee.fct.unl.pt/radhoc_2011_2012/enuncs/enunc_radhoc_tinyos_20112012.pdf4º/5º ano 7º/9º semestre ... Para evitar problemas de portabilidade

Departamento de Engenharia Electrotécnica

REDES AD HOC E DE SENSORES

2011 / 2012

Mestrado Integrado em Engenharia Electrotécnica

e Computadores

4º/5º ano

7º/9º semestre

Introdução ao desenvolvimento de aplicações em TinyOS 2.x

http://tele1.dee.fct.unl.pt Luis Bernardo

Page 2: REDES AD HOC E DE SENSORES 2011 / 2012tele1.dee.fct.unl.pt/radhoc_2011_2012/enuncs/enunc_radhoc_tinyos_20112012.pdf4º/5º ano 7º/9º semestre ... Para evitar problemas de portabilidade

Índice

1. Objetivo..................................................................................................................................................................32. Desenvolvimento de aplicações em nesC no TinyOS............................................................................................3

2.1. TinyOS............................................................................................................................................................ 32.1.1. Estrutura Típica de uma Aplicação ......................................................................................................... 32.1.2. Sensores IRIS...........................................................................................................................................4

2.2. Estruturação de um programa nesC................................................................................................................ 42.2.1. Componentes e interfaces........................................................................................................................ 5

2.2.1.1. Constantes e variáveis.......................................................................................................................62.2.2. Configurações e ligação entre componentes............................................................................................62.2.3. Modelo de execução................................................................................................................................ 7

2.3. Funcionalidades básicas em TinyOS.............................................................................................................. 72.3.1. Arranque...................................................................................................................................................72.3.2. LEDs........................................................................................................................................................ 82.3.3. Temporizadores........................................................................................................................................82.3.4. Leitura de sensores...................................................................................................................................82.3.5. Exemplo de aplicação.............................................................................................................................. 8

2.4. Comunicação entre motes em TinyOS..........................................................................................................102.4.1. Definição de Mensagens........................................................................................................................ 102.4.2. Troca de mensagens a um salto..............................................................................................................102.4.3. Comunicações numa Rede de Sensores.................................................................................................12

2.4.3.1. Recolha de Mensagens....................................................................................................................122.4.3.2. Disseminação de Mensagens.......................................................................................................... 13

2.4.4. Configurações avançadas das Comunicações........................................................................................142.4.4.1. Utilização de Protocolo MAC com Low-Power Listenning...........................................................142.4.4.2. Definição da potência de transmissão.............................................................................................152.4.4.3. Medição do RSSI ........................................................................................................................... 16

2.4.5. Comunicação entre Motes e aplicações Java no PC.............................................................................. 162.4.5.1. Comunicação entre a aplicação Java e o mote – código nesC........................................................172.4.5.2. Comunicação entre a aplicação Java e o mote – código Java.........................................................17

3. Instalação do TinyOS e do Ambiente de Desenvolvimento.................................................................................193.1. Instalação do TinyOS................................................................................................................................193.2. Ambiente de programação em nesC......................................................................................................... 19

4. Comandos Úteis para Usar Motes IRIS no Linux Ubuntu.................................................................................. 19

Page 3: REDES AD HOC E DE SENSORES 2011 / 2012tele1.dee.fct.unl.pt/radhoc_2011_2012/enuncs/enunc_radhoc_tinyos_20112012.pdf4º/5º ano 7º/9º semestre ... Para evitar problemas de portabilidade

1. OBJETIVO

Familiarização com o ambiente TinyOS e com o desenvolvimento de aplicações utilizando sensores sem fios IRIS/TelosB, o sistema operativo TinyOS, a linguagem nescC e o ambiente de desenvolvimento Eclipse para TinyOS. Pretende-se também que os sensores sem fios possam comunicar com aplicações Java num computador, para realizar a interface para o utilizador. Este documento inclui a descrição da interface de programação, suportado por vários excertos de programas de exemplo inspirados em código integrante da distribuição TinyOS 2.1.1. No final, o enunciado inclui um conjunto de comandos usados para compilar e instalar o código nos sensores sem fios (vulgarmente designados de motes).

2. DESENVOLVIMENTO DE APLICAÇÕES EM NESC NO TINYOS

Este documento contém um resumo com os aspectos mais relevantes do sistema operativo TinyOS, que vão ser necessários para a realização do 2º trabalho da disciplina. No entanto, para a realização de trabalhos mais complexos, recomenda-se a leitura dos documentos que foram consultados para preparar este documento, incluindo a extensa documentação disponível na Internet sobre o sistema operativo TinyOS, que pode ser encontrada em:

http://docs.tinyos.net/tinywiki/index.php/Main_Page e o livro “TinyOS Programming”, de Philip Levis e David Gay, Cambridge University Press, 2009, ISBN: 978-0-521-89606-1.

2.1. TinyOS

O TinyOS é um sistema operativo de baixa complexidade desenhado para correr no hardware limitado dos sensores sem fios de baixa potência. O TinyOS oferece um conjunto de abstrações e serviços que simplificam o desenvolvimento para redes de sensores sem fios (WSN – Wireless Sensor Networks), fornecendo também os mecanismos para interligar as aplicações a correr nos sensores às aplicações a correr em computadores.

2.1.1. Estrutura Típica de uma Aplicação

Uma aplicação típica numa rede de sensores sem fios (motes) recolhe informações ambientais recorrendo a um grupo de sensores espalhados no ambiente, que recolhem e enviam as medições realizadas (ou eventos associados às medidas, como a indicação de passagem de uma pessoa ou veículo) para um ou mais motes depósitos de dados (data sinks). Os motes data sink estão geralmente ligados a um computador pela porta série. O computador recebe os dados e apresenta-os, ou fornece uma interface Web, para que eles possam ficar acessíveis a partir da Internet1.

1 Quando se usa a abordagem 6lowPAN, pode ser usado uma gateway WSN-IP genérica, que permite aceder aos motes utilizando o protocolo IP.

3

Page 4: REDES AD HOC E DE SENSORES 2011 / 2012tele1.dee.fct.unl.pt/radhoc_2011_2012/enuncs/enunc_radhoc_tinyos_20112012.pdf4º/5º ano 7º/9º semestre ... Para evitar problemas de portabilidade

Figura do livro “TinyOS Programming”

Desta forma, uma aplicação em redes de sensores sem fios é composta por três programas distintos:

• O programa que corre nos nós sensores (mote sensor)• O programa que corre no data sink (mote raiz)• O programa que corre no computador (gateway)

2.1.2. Sensores IRIS

Existem vários tipos de motes disponíveis no mercado, que são suportados no sistema operativo TinyOS. A lista completa está disponível em:

http://docs.tinyos.net/tinywiki/index.php/Platform_Hardware .No trabalho de laboratório vão ser usados os sensores IRIS, atualmente

comercializados pela MemSic, podendo-se obter a especificação dos equipamentos em:

http://www.memsic.com/products/wireless-sensor-networks/wireless-modules.html .Estes motes têm 8KBytes de RAM, 128KBytes de memória flash para código de programas

e 512 KBytes de memória flash para dados. No laboratório vai ser usada a placa sensorial mais simples, MDA100CB, apenas com sensores de luminosidade e de temperatura.

Os motes IRIS estão equipados com o integrado de rádio RF230 da Atmel, cujo manual está disponível em http://www.atmel.com/dyn/resources/prod_documents/doc5131.pdf .

Para ligar os motes ao computador é necessário recorrer ao adaptador MIB520CA, representado ao lado, que permite o carregamento de aplicações, mas também a comunicação através da porta série.

No laboratório, cada grupo de alunos vai ter acesso a 3 motes IRIS, um adaptador MIB520CA, duas placas de sensores MDA100CB, mais um cabo de ligação à porta USB, para testarem as aplicações desenvolvidas.

2.2. Estruturação de um programa nesC

A linguagem de programação nesC organiza o programa num conjunto de componentes, que interagem entre si através da geração de eventos e da invocação de comandos, especificadas em interfaces. A programação é orientada para eventos: um componente corre quando recebe um evento, terminando com a armação de outro evento. No intervalo entre os dois eventos, o TinyOS tenta desligar todo o hardware que não está a ser utilizado (cortando a alimentação do rádio ou colocando o processador num modo de poupança de energia, por exemplo), para minimizar o consumo de energia.

A tabela seguinte compara os diferentes tipos de abstrações usados em nesC, e como eles se comparam com as existentes nas liguagens C e C++. A principal é o módulo componente e a sua especificação está associada à palavra-chave module. Os componentes realizam interfaces, especificadas com a palavra-chave interface. Finalmente, em nesC existe um tipo de

4

Page 5: REDES AD HOC E DE SENSORES 2011 / 2012tele1.dee.fct.unl.pt/radhoc_2011_2012/enuncs/enunc_radhoc_tinyos_20112012.pdf4º/5º ano 7º/9º semestre ... Para evitar problemas de portabilidade

componente adicional que realiza a interligação entre outros componentes e a associação de nomes, especificado com a palavra-chave configuration. Este módulo é novo em relação às linguagens C e C++.

Elemento estrutural C C++ nesCUnidade de programa Ficheiro Classe ComponenteEspecificação Unidade

Ficheiro .h Declaração de classe Especificação de componente

Especificação de padrão

– Classe abstrata Interface

Composição de Unidades

Associação de nomes Associação de nomes Associação explícita por ligações

Mapeamento de funções

Ponteiro para funções Método virtual Associação explícita por ligações

Nas subsecções seguintes é ilustrada a utilização de uma aplicação simples que se limita a ligar e desligar o LED 0 de um mote, designada de Blink.

2.2.1. Componentes e interfaces

A especificação de um componente é realizada num ficheiro com o mesmo nome, e com a extensão .nc. A especificação está dividida em dois blocos: a primeira parte, precedida de module especifica quais são as interfaces usadas pelo componente (com a palavra-chave uses); a segunda parte, dentro de parêntises após implementation, contém a realização das funções que tratam os eventos, ou realizam os comandos.

Na realização da aplicação Blink, são usados três componentes fornecidos pelo TinyOS (associados ao arranque da aplicação, temporizadores e controlo de LEDs), mais um componente principal, designado de BlinkC. Este componente é especificado no ficheiro BlinkC.nc, com o seguinte conteúdo:

module BlinkC {uses { interface Boot; // Evento de arranque do mote interface Timer; // Evento de disparar do temporizador interface Leds; // Comando de modificação do LEDS}

}implementation {

event void Boot.booted() { // Código corrido quando o mote arranca call Timer.startPeriodic(250);}

event void Timer.fired() { // Código corrido quando o timer dispara call Leds.led0Toggle();}

}

Na primeira secção, o módulo BlinkC especifica as interfaces usadas, associando-as explicitamente a um nome igual ao nome do tipo de interface. No entanto, pode-se associar uma interface a um nome diferente, usando a palavra-chave as. No exemplo seguinte, são usadas duas instâncias da interface Timer, cada uma com um nome distinto.

uses interface Timer as Timer1; // Exemplo onde são usados dois timers uses interface Timer as Timer2; //

A especificação de uma interface define uma lista de comandos (com a palavra-chave command) e eventos (com a palavra-chave event). A especificação de uma interface pode ainda ter tipos como parâmetros, tal como os templates do C++ ou do Java. Um módulo que use uma interface tem de implementar funções para tratar todos os eventos gerados na interface, e pode

5

Page 6: REDES AD HOC E DE SENSORES 2011 / 2012tele1.dee.fct.unl.pt/radhoc_2011_2012/enuncs/enunc_radhoc_tinyos_20112012.pdf4º/5º ano 7º/9º semestre ... Para evitar problemas de portabilidade

invocar os comandos da interface utilizando a palavra-chave call. O exemplo seguinte invoca o comando startPeriodic sobre a interface com o nome Timer1.

call Timer1. startPeriodic(250);

O subconjunto de eventos e comandos da interface Timer usado no módulo BlinkC é interface Timer {

command void startPeriodic(uint32_t interval); // Arma temporizador periódico

event void fired(); // Temporizador disparou}

Na secção de implementação do módulo BlinkC são realizadas duas funções que tratam do arranque inicial do mote, lançando o temporizador periódico, e do disparo do temporizador, comutando a luz do LED 0. A linguagem de programação das funções é semelhante à linguagem C. Suporta os comandos para o préprocessador (e.g. #define) e a utilização de bibliotecas do C (e.g. #include <math.h>).

2.2.1.1. Constantes e variáveisA implementação de um módulo pode incluir a definição de constantes e de variáveis. Para

poupar memória, as constantes devem ser definidas utilizando tipos enumerados:enum {

TIMER_PERIOD = 250};

As variáveis são declaradas com a sintaxe da linguagem C: uint16_t contador = 0;

Para evitar problemas de portabilidade de código, deve-se sempre usar os tipos de dados inteiros que especificam o número de bytes do número (uint8_t, uint16_t e uint32_t para números sem sinal e int8_t, int16_t e int32_t para números com sinal). Podem-se também usar estruturas e typedef, da linguagem C:

typedef struct estrutura_t {uint16_t contador1;uint16_t contador2;

} estrutura_t;

É comum a criação de um ficheiro .h (e.g tipos.h) com constantes e definição de tipos, que é depois incluído em vários módulos.

2.2.2. Configurações e ligação entre componentes

As configurações correspondem a uma maneira alternativa de definir componentes, que resultam da interligação entre módulos ou entre outras configurações. Tal como os módulos, também podem incluir uma secção inicial onde especificam se usam (uses) ou oferecem (provides) interfaces. Desta forma, podem ser interligadas como qualquer outro componente. A exceção é geralmente o componente principal de uma aplicação (que recebe o evento Boot do componente do sistema MainC, associado ao aranque do mote), que não necessita de realizar nenhuma interface.

No corpo principal da declaração de um componente de configuração, são declarados os componentes que são interligados (após a palavra-chave components) e as ligações entre eles (quem usa e quem fornece a interface).

Existem alguns componentes que fazem parte do sistema, e estão associados a componentes de hardware dos motes, ou a componentes do sistema operativo. Por exemplo:

• MainC – componente invocado durante o arranque do sistema;• LedsC – associado ao hardware (LEDs do mote).Existem outros componentes de software do sistema que podem ser instanciados com a

palavra-chave new, ou corresponder a módulos declarados pelo programador.

6

Page 7: REDES AD HOC E DE SENSORES 2011 / 2012tele1.dee.fct.unl.pt/radhoc_2011_2012/enuncs/enunc_radhoc_tinyos_20112012.pdf4º/5º ano 7º/9º semestre ... Para evitar problemas de portabilidade

O componente associado à aplicação Blink poderia ser a configuração BlinkAppC, que seria especificada no ficheiro BlinkAppC.nc, com o seguinte conteúdo:

configuration BlinkAppC { }implementation {

components MainC, LedsC, new TimerC() as MyTimer, BlinkC;

BlinkC.Boot -> MainC.Boot;BlinkC.Leds -> LedsC.Leds;BlinkC.Timer -> MyTimer.Timer;

}

O componente do tipo associação BlinkAppC usa os componentes de sistema, o componente do tipo módulo BlinkC especificado anteriormente e:

• Define a interface BlinkC.Boot (Boot do componente BlinkC) como cliente da interface MainC.Boot – desta forma recebe o evento Boot.booted();

• Define a interface BlinkC.Leds como cliente do componente LedsC.Leds – desta forma pode invocar o comando Leds.startPeriodic;

• Define a interface BlickC.Timer como cliente da interface MyTimer.Timer – desta forma pode armar o temporizador e receber o evento de expiração do temporizador.

2.2.3. Modelo de execução

O sistema operativo TinyOS não suporta a execução de tarefas em paralelo. Desta forma, é comum partir as funções com tempos de execução longos (e.g. a leitura de dados de alguns sensores) em duas fases (split-phase): a invocação de uma função inicial que inicia o processamento; e a geração de um evento quando o processamento terminou e os dados de saída estão disponíveis para consulta. Um comando pode apenas ser usado sincronamente numa tarefa, com garantias que só corre a função isoladamente. Noutros casos, tipicamente associados a funções de tratamento de interrupções, pode interromper uma tarefa. Os comandos preparados para funcionado no segundo caso são declarados com a palavra-chave async (por omissão, são sync – síncronos).

O TinyOS permite ainda agendar para o futuro, o processamento de uma função, reduzindo o tempo de processamento associado à receção de um evento. As tarefas são declaradas com a palavra-chave task, sendo invocadas tal como um comando, excepto que se usa a palavra-chave post. Um exemplo de utilização de tarefas é:

task void setupTask(){ // No parameters are allowed// run code after finishing the event handler

}

event void Boot.booted() {call Timer.startPeriodic(512);post setupTask();

}

2.3. Funcionalidades básicas em TinyOS

Quase todas as aplicações que correm nos motes requerem um conjunto mínimo de funcionalidades, suportadas por um conjunto de interfaces apresentado nesta secção.

2.3.1. Arranque

Como já foi ilustrado anteriormente, uma aplicação arranca quando recebe o evento através da interface Boot, disponibilizado pelo componente do sistema MainC.

interface Boot {event void booted();

}

7

Page 8: REDES AD HOC E DE SENSORES 2011 / 2012tele1.dee.fct.unl.pt/radhoc_2011_2012/enuncs/enunc_radhoc_tinyos_20112012.pdf4º/5º ano 7º/9º semestre ... Para evitar problemas de portabilidade

2.3.2. LEDs

A interface Leds permite controlar o estado dos três LEDs que equipam os motes. Permite ligar, desligar, trocar o estado individualmente; ou então através de uma máscara de bits (do tipo uint8_t), estando definidas as constantes LEDS_LED0, LEDS_LED1 e LEDS_LED2. No sistema está definido o componente LedsC que suporta esta interface.

interface Leds {async command void led0On();async command void led0Off();async command void led0Toggle ();async command void led1On();async command void led1Off();async command void led1Toggle ();async command void led2On();async command void led2Off();async command void led2Toggle();async command void led0On();

async command uint8_t get();async command void set(uint8_t val);

}

2.3.3. Temporizadores

Para além da utilização periódica, a interface Timer suporta um agendamento único de um evento em relação ao tempo atual, ou em relação a um instante t0 (disparando o evento fired no instante t0+dt. A interface Timer pode ter a precisão de milisegundos (precision_tag= TMili, que é equivalente ao componente TimerMilliC) ou de microsegundos, geralmente associado a outra fonte de relógio no hardware no mote com maior consumo energético. No entanto, a precisão do relógio nos motes é baixa, e é afetada por fatores como a temperatura do mote, etc.

interface Timer<precision_tag> {command void startPeriodic(uint32_t dt);command void startOneShot(uint32_t dt);command void stop();event fired();

command bool isRunning();command bool isOneShot();command uint32_t gett0(); // Get starting timecommand uint32_t getdt(); // Get the scheduled waiting time

command void statPeriodicAt(uint32_t t0, uint32_t dt);command void statOneShotAt(uint32_t t0, uint32_t dt);command uint32_t getNow(); // Get current

time}

2.3.4. Leitura de sensores

A leitura de um valor isolado num sensor é realizada através da interface Read, que oferece um comando de leitura em duas fases: o evento readDone é gerado quando a leitura está disponível ou foi identificada alguma avaria (nesse caso, result != SUCCESS). O parâmetro val_t define o tipo do valor retornado pelo sensor.

interface Read<val_t> {command error_t read();event void readDone(error_t result, val_t val);

}

2.3.5. Exemplo de aplicação

Nesta secção é apresentado um exemplo de uma aplicação AntiTheft que usa as interfaces apresentadas anteriormente para realizar um serviço anti-roubo simples, que liga o LED 0 cada

8

Page 9: REDES AD HOC E DE SENSORES 2011 / 2012tele1.dee.fct.unl.pt/radhoc_2011_2012/enuncs/enunc_radhoc_tinyos_20112012.pdf4º/5º ano 7º/9º semestre ... Para evitar problemas de portabilidade

vez que o sensor fica às escuras. Este exemplo é uma versão simplificada da aplicação com o mesmo nome, escrita por David Gay, que faz parte da distribuição do TinyOS, disponível em:

$(TOSROOT)/apps/AntiTheft/Nodesonde TOSROOT é geralmente igual a /opt/tinyos2.1.1 ou /opt/tinyos2.x.

O módulo AntiTheftC (em AntiTheftC.nc) implementa um temporizador que verifica periodicamente (com período DEFAULT_CHECK_INTERVAL) o valor da intensidade luminosa, acendendo o LED quando fica com um valor abaixo de DARK_THRESHOLD. O LED é mantido aceso durante WARNING_TIME períodos.

module AntiTheftC {uses {

interface Timer<TMilli> as Check;interface Read<uint16_t> as Light;interface Leds;interface Boot;

}}implementation {

enum {/* Period for checking the light sensor */DEFAULT_CHECK_INTERVAL = 1000, // 1 seg/* Threshold for considering mote in a dark place */DARK_THRESHOLD = 600,/* Amount of time warning leds should stay on (in checkInterval counts) */WARNING_TIME = 3,

};

uint16_t ledTime;

/* Turn on bright red light! (LED) */void theftLed() {

ledTime = WARNING_TIME;call Leds.led0On();

}

/* Time-out leds. Called every checkInterval */void updateLeds() {

if(ledTime && ! --ledTime)call Leds.led0Off();

}

/* Report theft, based on current settings */void theft() {

theftLed();}

/* At boot time, start the periodic timer and the radio */event void Boot.booted() {

call Check.startPeriodic(DEFAULT_CHECK_INTERVAL);}

/* Every check interval: update leds, check for theft based on current settings */event void Check.fired() {

updateLeds();call Light.read();

}

/* Light sample completed. Check if it indicates theft */event void Light.readDone(error_t ok, uint16_t val) {

if(ok == SUCCESS && val < DARK_THRESHOLD) theft();

/* ALERT! ALERT! */}

}

O componente de configuração associado à aplicação é designado de AntiTheftAppC (em AntiTheftAppC.nc):

configuration AntiTheftAppC { }implementation{ /* First wire the low-level services */

9

Page 10: REDES AD HOC E DE SENSORES 2011 / 2012tele1.dee.fct.unl.pt/radhoc_2011_2012/enuncs/enunc_radhoc_tinyos_20112012.pdf4º/5º ano 7º/9º semestre ... Para evitar problemas de portabilidade

components AntiTheftC, MainC, LedsC, new TimerMilliC() as MyTimer; AntiTheftC.Boot -> MainC.Boot; AntiTheftC.Check -> MyTimer; AntiTheftC.Leds -> LedsC;

/* Instantiate, wire MDA100 sensor board components. */ components new PhotoC(); AntiTheftC.Light -> PhotoC;}

2.4. Comunicação entre motes em TinyOS

O TinyOS permite suportar a comunicação entre motes, utilizando diferentes níveis de protocolo. Os componentes de mensagens activas permitem a comunicação a um salto. Outros componentes realizam protocolos de comunicação mais complexos, como difusão ou recolha de informação numa rede.

2.4.1. Definição de Mensagens

A comunicação é realizada através da troca de mensagens. As mensagens são contidas em variáveis do tipo message_t, que contêm um inteiro de 8 bits que define o tipo de pacote mais um campo com os dados do utilizador. Cada pacote pode guardar até TOSH_DATA_LENGTH bytes de dados, uma constante que por omissão é igual a 28 bytes, mas pode ser modificada durante a compilação do código para um valor até 255 bytes.

O conteúdo de uma mensagem é definido através da definição de uma estrutura, vulgarmente num ficheiro .h, utilizando tipos de dados de rede portáveis, identificados pelo seu nome ter o prefixo “nx_”. Uma mensagem é definida numa estrutura (nx_struct), que pode conter campos dos tipos nx_uint8_t, nx_uint16_t, nx_uint32_t, etc.

#ifndef ANTITHEFT_H#define ANTITHEFT_H

typedef nx_struct theft {nx_uint16_t who;

} theft_t;…#endif

2.4.2. Troca de mensagens a um salto

O nível mais baixo de protocolo de comunicação disponibilizado pelo TinyOS está montado diretamente sobre o rádio, suportando o envio e recepção não fiável de mensagens a um salto de distância (i.e. dentro do alcance rádio). Designam-se de mensagens activas (AM) porque permitem associar emissores e receptores distintos a cada tipo de mensagem.

O envio de mensagens é suportado pela interface AMSend. O comando send e o evento sendDone realizam o envio de pacotes em duas fases. Existem dois endereços que estão definidos à partida no sistema: o endereço de broadcast, definido por TOS_BCAST_ADDR, e o endereço do próprio nó, definido por TOS_NODE_ID. O valor do endereço de um nó é definido no instante da compilação e instalação do código no mote (ver secção 4 na página 19). O envio de uma mensagem pode ser cancelado. Esta interface é realizada pelo componente de configuração genérico AMSenderC, que recebe como argumento o número do tipo de mensagem trocada. Desta forma, os vários tipos de mensagens são geridos em filas de espera independentes.

interface AMSend {command error_t send(am_addr_t addr, message_t* msg, uint8_t len);event void sendDone(message_t* msg, error_t error);command error_t cancel(message_t* msg);command uint8_t maxPayloadLength();command void* getPayload(message_t* msg, uint8_t len);

}

10

Page 11: REDES AD HOC E DE SENSORES 2011 / 2012tele1.dee.fct.unl.pt/radhoc_2011_2012/enuncs/enunc_radhoc_tinyos_20112012.pdf4º/5º ano 7º/9º semestre ... Para evitar problemas de portabilidade

No excerto de código seguinte é apresentado um exemplo do envio de um pacote do tipo theft_t, definido na secção 2.4.1, e que pode ser usado para acrescentar a funcionalidade de sinalizar um roubo, no exemplo introduzido na secção 2.3.5. Este exemplo define a função reportTheft, que envia um pacote com a mensagem theft_t para todos os vizinhos em broadcast. Repare-se que apenas pode haver um envio ativo em cada instante.

uses interface AMSend as Theft;…message_t reportMsg; // Theft report message bufferbool sending; // Flag to avoid sending while a packet is being sent

void reportTheft() {theft_t *payload= call Theft.getPayload(&reportMsg, sizeof(theft_t));if (payload && !sending) {

payload->who= TOS_NODE_ID;if (call Theft.send(TOS_BCAST_ADDR, &reportMsg, sizeof(theft_t)) == SUCCESS)

sending= true;}

}

event void Theft.sendDone(message_t* msg, error_t error) {sending= FALSE;

}

A recepção de mensagens é realizada através da interface Receive, que apenas disponibiliza o evento receive. Esta interface é realizada pelo componente de configuração genérico AMReceiverC, que recebe como argumento o número do tipo de mensagem.

interface Receive {event message_t* receive(message_t* msg, void* payload, uint8_t len);

}

Voltando ao exemplo, a recepção de mensagem poderia basear-se no seguinte excerto de código.

uses interface Receive as TheftRec;…event message_t * TheftRec.receive(message_t *msg, void *payload, uint8_t len) {

if (len >= sizeof(theft_t)) { // Check the packet seams validtheft_t *theftMsg= payload;// code may use theftMsg->who for some purposetheftLed();

}return msg;

}

O rádio do mote pode ser ligado ou desligado recorrendo-se à interface SplitControl. Esta interface suporta duas operações realizadas em duas fases, para iniciar e parar o rádio. O rádio é o componente de hardware que mais energia gasta, em paralelo com o processador, mesmo quando não está a enviar ou receber mensagens. Esta interface é realizada pelo componente de configuração genérico ActiveMessageC.

interface SplitControl {command error_t start();event void startDone(error_t result);command error_t stop();event void stopDone(error_t result);

}

No exemplo anterior, o evento booted deve desencadear o arranque do rádio.uses interface SplitControl as CommControl;…event void Boot.booted() {

call CommControl.start();}

event void CommControl.startDone(error_t ok) {// Start everything else after the radio is ON

}

event void stopDone(error_t ok) {} // Ignores event

11

Page 12: REDES AD HOC E DE SENSORES 2011 / 2012tele1.dee.fct.unl.pt/radhoc_2011_2012/enuncs/enunc_radhoc_tinyos_20112012.pdf4º/5º ano 7º/9º semestre ... Para evitar problemas de portabilidade

O componente de configuração AntiTheftAppC teria de associar as interfaces aos componentes de rádio. Admitindo que o tipo de mensagem associado é AM_THEFT, ficaria:

enum { AM_THEFT = 42 };…components new AMSenderC(AM_THEFT) as SendTheft, new AMReceiverC(AM_THEFT) as ReceiveTheft, RF230ActiveMessageC as Radio; // Específico para o RF230 dos IRIS

AntiTheftC.RadioControl -> Radio; AntiTheftC.Theft -> SendTheft; AntiTheftC.TheftRec -> ReceiveTheft;

Pode encontrar mais informações sobre a interface de nível pacote em:http://www.tinyos.net/tinyos-2.x/doc/html/tep116.html

2.4.3. Comunicações numa Rede de Sensores

Tal como foi ilustrado na secção 2.1.1 (na página 3), uma rede de sensores sem fios é geralmente complexa, e inclui a comunicação entre motes sensores, atravessando vários saltos, até um mote raiz (data sink), que recolhe a informação. Para simplificar o desenvolvimento deste tipo de aplicações, o TinyOS fornece dois tipos específicos de protocolos de comunicação para suportar a recolha de dados para um mote raiz, ou a disseminação de mensagens para todos os motes sensores a partir de um mote raiz.

2.4.3.1. Recolha de MensagensPara suporta a recolha de mensagens através de uma árvore, com raiz num ou mais motes

raiz, o TinyOS oferece o serviço Collection. Os motes sensores usam a interface Send para enviar mensagens para a raiz da árvore. Esta interface é muito parecida com a interface AMSend, apresentada na secção anterior, excepto que não é indicado o endereço de destino. Portanto, o envio é praticamente igual ao apresentado anteriormente para a interface AMSend.

interface Send {command error_t send(message_t* msg, uint8_t len);event void sendDone(message_t* msg, error_t error);command error_t cancel(message_t* msg);command uint8_t maxPayloadLength();command void* getPayload(message_t* msg, uint8_t len);

}

O mote raiz recebe os pacotes através da interface Receive, usada na secção anterior. Para se registar como raiz, usa a interface RootControl. Quando se selecciona o comando setRoot é corrido um protocolo na rede de sensores que cria a árvore de recolha de informação; que pode ser desativada com o comando unsetRoot.

interface RootControl {command error_t setRoot();command error_t unsetRoot();command bool isRoot();

}

O serviço de recolha de mensagens tem de ser ligado explicitamente, após o arranque do componente de rádio, utilizando-se a interface StdControl.

interface StdControl {command error_t start();command error_t stop();

}

Um excerto de código seguinte ilustra como pode ser feito o arranque do serviço de recolha de mensagens.

uses interface StdControl as CollectionControl;…event void Boot.booted() {

call CommControl.start();}

12

Page 13: REDES AD HOC E DE SENSORES 2011 / 2012tele1.dee.fct.unl.pt/radhoc_2011_2012/enuncs/enunc_radhoc_tinyos_20112012.pdf4º/5º ano 7º/9º semestre ... Para evitar problemas de portabilidade

event void CommControl.startDone(error_t ok) { // Radio startedcall CollectionControl.start();…

}

Tal como anteriormente, as mensagens são identificadas por um tipo. Desta forma, podemos ter várias árvores de recolha de dados numa rede, desde que identificadas por números de tipo diferentes. A instanciação de um componente para um mote sensor é suportada pelo componente de ligação CollectionSenderC, ilustrado com o seguinte código para um componente de ligação AntiTheftAppC que liga o módulo AntiTheftC, e para o tipo de mensagem COL_THEFT:

enum { COL_THEFT = 54 };…components ActiveMessageC, CollectionC;AntiTheftC.CommControl -> ActiveMessageC;AntiTheftC.CollectionControl -> CollectionC;

// Instatiate and wire the collection servicescomponent new CollectionSenderC(COL_THEFT) as TheftSender;AntiTheftC.Theft -> TheftSender;

O exemplo dual correspondente para o mote raiz recorre ao componente CollectionC. A criação e ligação dos componentes no componente de ligação AntiTheftRootAppC (que liga o módulo AntiTheftRootC) tem o seguinte conteúdo:

enum { COL_THEFT = 54 };…// Instatiate and wire the collection servicescomponents CollectionC;AntiTheftRootC.CollectionControl -> CollectionC;AntiTheftRoot.RootControl -> CollectionC;AntiTheftRoot.RTheft -> CollectionC.Receive[COL_THEFT];…

Neste segundo caso, o módulo AntiTheftRootC ficaria:module AntiTheftRootC {

uses interface RootControl;uses interface Receive as RTheft;

…event void CommControl.startDone(error_t error) {

call RootControl.setRoot();}

event message_t *RTheft.receive(message_t* msg, void* payload, uint8_t len) {… handle message …

}

Pode encontrar mais informações sobre a interface do protocolo de recolha de mensagens em:

http://www.tinyos.net/tinyos-2.x/doc/html/tep123.html

2.4.3.2. Disseminação de MensagensPara suportar a disseminação de um valor através de uma rede, a partir de um mote raiz, o

TinyOS oferece o serviço Dissemination. Acede-se ao serviço através de uma interface do tipo DisseminationValue parametrizada com o tipo do valor que se pretende disseminar. Desta forma, qualquer mote pode modificar o valor (embora seja mais eficiente realizar a modificação a partir do mote raiz).

interface DisseminationValue<t> {command const t* get();command void set ( const t* );event void changed();

}

O mote raiz usa a interface DisseminationUpdate para modificar o valor, associada à raiz da árvore de disseminação.

interface DisseminationUpdate<t> {command void change(t* newVal);

}

13

Page 14: REDES AD HOC E DE SENSORES 2011 / 2012tele1.dee.fct.unl.pt/radhoc_2011_2012/enuncs/enunc_radhoc_tinyos_20112012.pdf4º/5º ano 7º/9º semestre ... Para evitar problemas de portabilidade

Tal como no serviço anterior, o serviço de disseminação tem de ser ligado explicitamente, após o arranque do componente de rádio, utilizando-se a interface StdControl. Um excerto de código seguinte ilustra como pode ser feito o arranque do serviço de disseminação.

uses interface StdControl as DisseminationControl;…event void Boot.booted() {

call CommControl.start();}

event void CommControl.startDone(error_t ok) {call DisseminationControl.start();…

}

Tal como anteriormente, as mensagens são identificadas por um tipo. Desta forma, podemos ter várias árvores de disseminação numa rede, desde que identificadas por números de tipo diferentes. A recepção dos valores num mote sensor para o tipo settings_t seria realizada utilizando o seguinte código, num ficheiro AntiTheftC.nc:

uses interface DisseminationValue<setting_t> as Settings;…event void Settings.changed () {

const settings_t *new_value= call Settings.get();// use new_value …

}

A instanciação de um componente para um mote sensor é suportada pelo componente de ligação DisseminatorC, ilustrado com o seguinte código para um componente de ligação AntiTheftAppC (que liga o módulo AntiTheftC), para o tipo de mensagem DIS_THEFT:

enum { DIS_THEFT = 55 };…components DisseminationC, new DisseminatorC(settings_t, DIS_THEFT);AntiTheftC.DisseminationControl -> DisseminationC;AntiTheftC.Settings -> DisseminatorC;

Um mote raiz correspondente limita-se a invocar o comando change, sempre que quer actualizar o valor da variável, no módulo AntiTheftRootC:

uses interface DisseminationUpdate<settings_t> as USettings;…

// Update settings valuecall USettings.change((settings *)new_value);

A instanciação de um componente para um mote raiz também é suportada pelo componente de ligação DisseminatorC, ilustrado com o seguinte código para um componente de ligação AntiTheftRootAppC, para o tipo de mensagem DIS_THEFT:

enum { DIS_THEFT = 55 };…components DisseminationC, new DisseminatorC(settings_t, DIS_THEFT);AntiTheftRootC.DisseminationControl -> DisseminationC;AntiTheftRootC.USettings -> DisseminatorC;

Pode encontrar mais informações sobre a interface do protocolo de disseminação em:http://www.tinyos.net/tinyos-2.x/doc/html/tep118.html

2.4.4. Configurações Avançadas das Comunicações

O TinyOS permite modificar o comportamento do sistema, regulando o tipo de protocolo MAC, regulando a potência de transmissão. Também permite medir o nível de potência do sinal recebido num pacote.

2.4.4.1. Utilização de Protocolo MAC com Low-Power Listenning

O sistema operativo suporta de forma simples a utilização de um protocolo de controlo de acesso ao meio (MAC) do tipo Low Power Listening (LPL), em que o rádio é desligado durante

14

Page 15: REDES AD HOC E DE SENSORES 2011 / 2012tele1.dee.fct.unl.pt/radhoc_2011_2012/enuncs/enunc_radhoc_tinyos_20112012.pdf4º/5º ano 7º/9º semestre ... Para evitar problemas de portabilidade

uma percentagem do tempo, e apenas é ligado periodicamente. As mensagens enviadas com LPL são precedidas de um comboio de preâmbulos de dimensão superior ao período de adormecimento do rádio, permitindo poupar a bateria à custa de uma latência maior na comunicação. Para poder ser usado, requer a utilização da interface LowPowerListening, na definição do módulo de arranque do rádio. A configuração do duty cycle2 é realizada no evento startDone, gerado quando o componente de rádio é ligado.

module AntiTheftC {…

uses interface LowPowerListening;}Implementation {…

/* Radio started. Set the wakeup interval for low-power-listening wakeup to half a second. */

event void RadioControl.startDone(error_t ok) {if(ok == SUCCESS) {

…call LowPowerListening.setLocalWakeupInterval(512);

}}

}

Nos motes IRIS, também é necessário modificar o componente de ligação, efetuando a ligação ao componente RF230ActiveMessageC.LowPowerListening:

configuration AntiTheftAppC { }implementation{ components RF230ActiveMessageC as Radio;… AntiTheftC.LowPowerListening -> Radio;}

2.4.4.2. Definição da potência de transmissão

É possível controlar a potência do sinal transmitido pelos motes IRIS, mensagem a mensagem, invocando o comando set sobre a interface PacketTransmitPower. O comando tem como parâmetros um apontador para a mensagem e um inteiro de 8 bits com um número entre 0 (+3 dBm) e 15 (-17.2 dBm)3:

call PacketTransmitPower.set(message_t *msg, uint8_t t_power);// send the message

Para poder ser usado requer a utilização da interface PacketField, na definição do módulo:module AntiTheftC {

…uses interface PacketField<uint8_t> as PacketTransmitPower;

}

Nos motes IRIS, também é necessário modificar o componente de ligação, efetuando a ligação ao componente RF230ActiveMessageC.PacketTransmitPower:

configuration AntiTheftAppC { }implementation{ components RF230ActiveMessageC as Radio;… AntiTheftC.PacketTransmitPower -> Radio.PacketTransmitPower;}

No caso dos motes IRIS, existe ainda a alternativa de modificar a potência de transmissão para todos os pacotes durante a compilação de um componente, acrescentando à Makefile do projeto a seguinte linha (no exemplo, para 15):

PFLAGS+=-DRF230_DEF_RFPOWER=15

2 Pode encontrar mais informação em http://www.tinyos.net/tinyos-2.x/doc/html/tep105.html 3 Pode encontrar uma descrição detalhada no manual do RF230, em http://www.atmel.com/dyn/resources/prod_documents/doc5131.pdf

15

Page 16: REDES AD HOC E DE SENSORES 2011 / 2012tele1.dee.fct.unl.pt/radhoc_2011_2012/enuncs/enunc_radhoc_tinyos_20112012.pdf4º/5º ano 7º/9º semestre ... Para evitar problemas de portabilidade

2.4.4.3. Medição do RSSI

É possível medir a potência de sinal recebido (RSSI - Received Signal Strength Indication) numa mensagem em vários tipos de motes, utilizando a função getRssi declarada em baixo.

#ifdef __CC2420_H__ uint16_t getRssi(message_t * msg) {

return(uint16_t) call CC2420Packet.getRssi(msg);}

#elif defined(CC1K_RADIO_MSG_H)uint16_t getRssi(message_t * msg) {

cc1000_metadata_t * md = (cc1000_metadata_t * ) msg->metadata;return md->strength_or_preamble;

}#elif defined(PLATFORM_IRIS)

uint16_t getRssi(message_t * msg) {if(call PacketRSSI.isSet(msg))

return(uint16_t) call PacketRSSI.get(msg);else

return 0xFFFF;}

#elif defined(TDA5250_MESSAGE_H)uint16_t getRssi(message_t * msg) {

return call Tda5250Packet.getSnr(msg);}

#else#error Radio chip not supported! This demo currently works only \

for motes with CC1000, CC2420, RF230 or TDA5250 radios. #endif

No caso dos motes IRIS requer a utilização da interface PacketField, na definição do módulo:

module AntiTheftC {…uses interface PacketField<uint8_t> as PacketRSSI;

}

Requer ainda a sua ligação ao componente RF230ActiveMessageC.PacketRSSI, no componente de ligação da aplicação:

configuration AntiTheftAppC { }implementation{ components RF230ActiveMessageC as Radio;… AntiTheftC.PacketRSSI->Radio.PacketRSSI;}

O componente de rádio dos IRIS permite obter uma média de valores de potência de sinal, em vez de uma única amostra, acrescentando à Makefile do projeto a seguinte linha:

CFLAGS += -DRF230_RSSI_ENERGY

2.4.5. Comunicação entre Motes e Aplicações Java no Computador

O TinyOS suporta a comunicação entre o mote raiz e uma aplicação a correr num computador, ligado através do adaptador para a porta série. Para isso, suporta a abstração de um canal série de comunicações não fiável equivalente a um canal de rádio, que suporta a troca de AMpackets. Tal como anteriormente, assume-se que existe o tipo theft_t declarado, tal como na secção 2.4.1 na página 10, que vai ser enviado nos dois sentidos.

2.4.5.1. Comunicação entre a aplicação Java e o mote – código nesCA criação do componente responsável pela comunicação com o PC é quase igual à criação

do componente rádio, utilizando as mesmas interfaces. A recepção de dados do componente da porta série também é idêntica. Já o envio dos dados, requer que apenas exista um processo a enviar dados num dado instante. Assim, no exemplo fornecido é usada a variável Booleana fwdBusy, como semáforo. Novamente, o código do envio é idêntico ao envio para a rede. Neste caso, o endereço de destino poderia ser usado para realizar multiplexagem entre várias

16

Page 17: REDES AD HOC E DE SENSORES 2011 / 2012tele1.dee.fct.unl.pt/radhoc_2011_2012/enuncs/enunc_radhoc_tinyos_20112012.pdf4º/5º ano 7º/9º semestre ... Para evitar problemas de portabilidade

aplicações a comunicar pela mesma porta série, ou para pré-atribuir o endereço de destino na rede sem fios diretamente na aplicação Java.

uses interface SplitControl as SerialControl;uses interface Receive as TheftReceive;uses interface AMSend as TheftForward;…/* Start the radio and serial ports when booting */event void Boot.booted() {

call SerialControl.start();…

}event void SerialControl.startDone(error_t error) { }

/* When we receive new message from the serial port */event message_t * TheftReceive.receive(message_t * msg, void * payload,

uint8_t len) {theft_t * newTheft = payload;…return msg;

}

message_t fwdMsg; // bufferbool fwdBusy; // Semaphore

/* To forward a new message to the PC via the serial port */void forward_alert(theft_t * newAlert) {

if( ! fwdBusy) {/* Copy payload (newAlert) from collection system to our serial message buffer (fwdAlert), then send our serial message */theft_t * fwdAlert = call TheftForward.getPayload(&fwdMsg,

sizeof(theft_t));if(fwdAlert != NULL) {

*fwdAlert = *newAlert;if(call TheftForward.send(AM_BROADCAST_ADDR, &fwdMsg,

sizeof(*fwdAlert)) == SUCCESS) fwdBusy = TRUE;

}}

}event void TheftForward.sendDone(message_t * msg, error_t error) {

if(msg == &fwdMsg) fwdBusy = FALSE;

}

As modificações face ao rádio são visíveis principalmente no componente de configuração AntiTheftRootAppC, onde são usados os componentes SerialAMReceiverC, SerialAMSenderC e SerialActiveMessageC para realizar a associação das interfaces à porta série.

components SerialActiveMessageC,new SerialAMReceiverC(AM_THEFT) as TheftReceiver,new SerialAMSenderC(AM_THEFT) as TheftForwarder;

AntiTheftRootC.SerialControl->SerialActiveMessageC;AntiTheftRootC.TheftReceive->TheftReceiver;AntiTheftRootC.TheftForward->TheftForwarder;

2.4.5.2. Comunicação entre a aplicação Java e o mote – código JavaDo lado da aplicação Java, o TinyOS fornece um conjunto de ferramentas que mapeiam

todos os tipos e constantes definidos em nesC para classes em Java. Paralelamente, fornece um conjunto de métodos em código nativo (JNI) que permitem instanciar os objetos de ligação ao mote, da classe MoteIF. No caso dos motes IRIS, estes ligam-se à porta série através do adaptador MIB520. Desta forma, no sistema operativo aparecem duas portas série associadas ao mote. Para efeitos de programação deve ser usada a de numeração mais baixa (geralmente a /dev/ttyUSB0, associada ao MIB520), mas para comunicação com o mote deve ser sempre usada a de numeração mais alta (geralmente a /dev/ttyUSB1). Para receber as mensagens é criado um objecto da classe TheftReceiver, explicada mais à frente nesta secção. A instanciação do objecto MoteIF pode ser feita usando:

17

Page 18: REDES AD HOC E DE SENSORES 2011 / 2012tele1.dee.fct.unl.pt/radhoc_2011_2012/enuncs/enunc_radhoc_tinyos_20112012.pdf4º/5º ano 7º/9º semestre ... Para evitar problemas de portabilidade

public MoteIF connect_to_mote(String ttytxt) {String serial= "serial@" + ttytxt + ":iris";PhoenixSource phoenix = BuildSource.makePhoenix(serial, null);MoteIF mote = new MoteIF(phoenix);mote.registerListener(new AlertReceiver(), this);

}

Para obter as classes Java associadas aos tipos de mensagens definidas em TinyOS, usa-se o programa mig (message interface generator) para compilar o ficheiro nesC com a definição dos tipos (geralmente um ficheiro .h). Para obter uma classe com todas as constantes definidas no código nesC usa-se o programa ncg (nesC constant generator). Para facilitar a geração automática das classes Java quando o código nesC é modificado, é comum definir um ficheiro Makefile que automatiza a compilação do código. De seguida é apresentado um exemplo de uma Makefile, que gera a classe Java TheftMsg a partir da estrutura nx_struct theft declarada no ficheiro antitheft.h, e que gera a classe Constants com todas as constantes definidas no mesmo ficheiro.

GEN=TheftMsg.java Constants.java

ANTITHEFT_H=antitheft.h

all: $(GEN)

TheftMsg.java: $(ANTITHEFT_H)mig -target=null -java-classname=TheftMsg java $(ANTITHEFT_H) theft -o $@

Constants.java: $(ANTITHEFT_H)ncg -target=null -java-classname=Constants java $(ANTITHEFT_H) antitheft.h -o

$@

A programação de uma aplicação em Java torna-se simples com estas duas classes. Para enviar uma mensagem, cria-se uma nova instância da classe TheftMsg e preenchem-se os campos utilizando os métodos cujo nome tem o prefixo “set_” seguindo do nome do campo da estrutura. Finalmente, usa-se o método send do objecto de ligação ao mote.

public void sendMessage(short who) {TheftMsg payload= new TheftMsg();payload.set_who(who);moteIF.send(0, payload);

}

Para receber dados da porta série é necessário criar uma classe que implemente a interface Java net.tinyos.message.MessageListener. No exemplo seguinte é apresentada a classe TheftReceiver, que contém a função messageReceive invocada de cada vez que é recebida uma mensagem nova.

public class TheftReceiver implements MessageListener {

public void messageReceive(int to, Message msg) {if (msg instanceof TheftMsg) {

TheftMsg theftMsg = (TheftMsg) msg;…

} else {// Invalid message type…}

}}

18

Page 19: REDES AD HOC E DE SENSORES 2011 / 2012tele1.dee.fct.unl.pt/radhoc_2011_2012/enuncs/enunc_radhoc_tinyos_20112012.pdf4º/5º ano 7º/9º semestre ... Para evitar problemas de portabilidade

3. INSTALAÇÃO DO TINYOS E DO AMBIENTE DE DESENVOLVIMENTO

3.1. Instalação do TinyOS

Na página do TinyOS, em www.tinyos.net, existe disponível vasta informação sobre todos os aspetos da plataforma, incluindo a instalação, em:

http://docs.tinyos.net/tinywiki/index.php/Getting_startedTeoricamente, para um sistema com pacotes Debian, como é o caso do Ubuntu, bastariam

cinco passos simples para instalar o ambiente de desenvolvimento, e o sistema TinyOS. Infelizmente, a disponibilidade do sistema depende de quem mantém a base de dados de pacotes, e desde o meio do mês de Setembro, com a atualização da versão de Ubuntu, a base de dados de pacotes está corrompida, e não instala a biblioteca para motes avr, baseados em processadores Atmel, como o IRIS. Desta forma, o trabalho vai ser realizado com uma máquina virtual a correr Ubuntu, criada em Agosto, quando o sistema de pacotes para avr ainda estava operacional. É provável que no futuro próximo este problema seja resolvido.

3.2. Ambiente de programação em nesC

O trabalho vai ser maioritariamente realizado utilizando a linha de comando para compilar, instalar o código nos motes, etc. No entanto, a edição dos ficheiros nesC pode ser feita recorrendo ao editor do Eclipse. Na página http://en.wikipedia.org/wiki/TinyOS são identificados vários plugins que suportam nesC. Na máquina virtual fornecida foi instalado o Yeti 2 (http://tos-ide.ethz.ch/wiki/index.php), que suporta métodos de visualização avançada dos componentes.

4. COMANDOS ÚTEIS PARA USAR MOTES IRIS NO LINUX UBUNTU

Grande parte do trabalho vai ser realizada introduzindo comandos num terminal, na máquina virtual fornecida. Nesta secção reúne-se uma lista dos comandos mais importantes, que vai necessitar para procurar as portas USB onde os motes estão ligados, instalar aplicações nos motes, etc.

Identificar as portas séries associadas a motes:ls –lh /dev/ttyUSB*

Desproteger todas as portas séries para poderem ser utilizadas por aplicações:sudo chmod a+rw /dev/ttyUSB*

Limpar a aplicação a correr num mote:cd /opt/tinyos-2.1.1/apps/Null; make iris install mib510,/dev/ttyUSB0

Compilar uma aplicação TinyOS:make iris

Instalar uma aplicação num mote (com o adaptador mib510) associado à porta /dev/ttyUSB0 e definindo o endereço do mote como 1:

make iris install.1 mib510,/dev/ttyUSB0

Para modificar o endereço MAC do mote, basta modificar o número introduzido após “install.”.

19