UMinho | 2012
Marco Pedro Fernandes Alves Estudo de ambientes de execução para redes de sensores sem fios
Universidade do Minho
Escola de Engenharia
Marco Pedro Fernandes Alves
Estudo de ambientes de execução
para redes de sensores sem fios
Outubro de 2012
Universidade do Minho
Escola de Engenharia
Marco Pedro Fernandes Alves
Estudo de ambientes de execução
para redes de sensores sem fios
Tese de Mestrado
Ciclo de Estudos Integrados Conducentes ao Grau de
Mestre em Engenharia Eletrónica Industrial e Computadores
Trabalho efetuado sob a orientação do
Professor Doutor Paulo Francisco S. Cardoso
Outubro de 2012
Agradecimentos
Gostaria de expressar o meu agradecimento a todas as pessoas que, de alguma
forma, contribuíram para a realização desta dissertação e me ajudaram a ultrapassar
as dificuldades por mim sentidas, nomeadamente ao meu orientador, Professor
Doutor Paulo Francisco S. Cardoso, por toda a disponibilidade e colaboração
prestada durante a realização desta dissertação.
Gostaria de agradecer igualmente aos meus colegas e amigos que me apoiaram
durante a dissertação e em toda a minha jornada por esta nobre academia,
especialmente ao Nuno Gonçalves e ao José Luís Rodrigues.
Agradeço ao Departamento de Eletrónica Industrial da Universidade do Minho,
todas as condições e facilidades proporcionadas para a realização deste trabalho.
Agradeço igualmente à minha família por acreditarem sempre na realização da
minha formação académica.
E, por fim mas não menos importante, queria agradecer à minha namorada,
melhor
amiga
e
companheira
pela
sua
paciência
e
total
apoio.
iii
iv
Resumo
Atualmente devido à maturidade atingida pela tecnologia, as redes de sensores
deixaram ter utilização exclusiva em sistemas especializados, existindo uma miríade
de aplicações onde podem ser aplicadas.
O maior entrave da sua aplicação deixou de ser o custo da tecnologia em si, como
apontado acima, mas antes o desenvolvimento das soluções.
Ao se tratar de soluções cada vez mais necessárias, tanto na indústria como nas
habitações, implica que cada vez mais pessoas tenham necessidade de obter
conhecimentos especializado e treino suficiente para desenvolver, garantir a
manutenção, expandir e melhorar sistemas de redes de sensores que podem variar de
complexidade consoante a aplicação desejada.
Foi neste contexto que foi elaborado o estudo de ambientes de desenvolvimento e
execução para redes de sensores sem fios. O principal objetivo é apontar os prós e
contras de cada uma das plataformas de desenvolvimento e os seus respetivos
ambientes.
Palavras-chaves: Microcontroladores, Linguagem de Programação, Protocolo
ZigBeeTM, Mote Runner, AVR BitCoud, Programação Orientada a Eventos, Redes
de Sensores Sem Fios.
v
vi
Abstract
Nowaday due to maturity of technology, sensor networks have use left solely in
dedicated systems and there are a myriad of applications where they can be applied.
The biggest obstacle of its application isn’t longer the cost of the technology
itself, as pointed out above, but the development of solutions itself.
Since this is an increasingly necessary technology both in industry and in
households, it means that more people have a need to obtain specialized knowledge
and training to develop and mantain this kind of systems.
It was in this context that the study was designed environments for development
and implementation of wireless sensor networks. The main objective is to point out
the pros and cons of each of the platforms and development environments.
Keywords: Microcontroller, Programming language, ZigBeeTM Protocol, Mote
Runner, AVR BitCoud, Event-driven programming, Wireless Sensor Network.
vii
viii
“A persistência é o caminho do êxito.”
Charles Chaplin
ix
x
Índice
CAPÍTULO 1 .................................................................................................................... 1
INTRODUÇÃO ................................................................................................................. 1
1.1
Enquadramento ...................................................................................................................... 2
1.2
Motivação e Objetivos do trabalho ......................................................................................... 2
1.3
Organização da Tese................................................................................................................ 3
CAPÍTULO 2 .................................................................................................................... 5
CONCEITOS ..................................................................................................................... 5
2.1 Redes de dados ....................................................................................................................... 6
2.1.1
Conceitos de redes de computadores.............................................................................. 6
2.1.2
Modelo OSI ..................................................................................................................... 8
2.1.3
Conceito de serviço....................................................................................................... 11
2.2 Redes de Sensores Sem Fios (RSSF/WSN) .............................................................................. 13
2.2.1
IEEE 802.15.4TM............................................................................................................. 16
2.2.2
Tecnologias WPANs ...................................................................................................... 26
2.2.3
Tecnologias WLANs....................................................................................................... 28
2.3 Plataforma Computacional.................................................................................................... 30
2.3.1
ATMEL RZRAVEN........................................................................................................... 30
CAPÍTULO 3 ..................................................................................................................33
INTERFACE DE PROGRAMAÇÃO .............................................................................33
3.1 BitCloud ................................................................................................................................ 34
3.1.1
Introdução do BitCloud ................................................................................................. 34
3.1.2
Ambiente de programação............................................................................................ 35
3.1.3
API de comunicações .................................................................................................... 38
3.1.3.1
ZDO ..................................................................................................................... 38
3.1.3.2
APS ...................................................................................................................... 40
3.1.4
APIs de interface com o hardware................................................................................. 44
3.1.4.1
HAL ..................................................................................................................... 45
3.1.4.2
BSP ...................................................................................................................... 46
3.2 Mote Runner ......................................................................................................................... 46
3.2.1
Introdução do Mote Runner.......................................................................................... 46
3.2.2
Ambiente de programação............................................................................................ 47
xi
3.2.3
API Mote Runner .......................................................................................................... 51
CAPÍTULO 4 ..................................................................................................................55
ESTUDO DO CASO .......................................................................................................55
4.1
Descrição das aplicações ....................................................................................................... 56
4.2 Implementação BitCloud ....................................................................................................... 58
4.2.1
Atuador ........................................................................................................................ 58
4.2.2
Emissor ......................................................................................................................... 63
4.3 Implementação Mote Runner ............................................................................................... 64
4.3.1
Recetor ......................................................................................................................... 64
4.3.2
Emissor ......................................................................................................................... 67
4.4
Comparação/Discussão ......................................................................................................... 71
CAPÍTULO 5 ..................................................................................................................75
CONCLUSÃO ..................................................................................................................75
5.1
Aplicações em ambiente de redes de sensores sem fios ........................................................ 76
5.2
Trabalho futuro ..................................................................................................................... 77
ANEXO A: .......................................................................................................................85
ANEXO B: .......................................................................................................................87
ANEXO C: .......................................................................................................................97
ANEXO D:.................................................................................................................... 101
ANEXO E: .................................................................................................................... 111
ANEXO F: .................................................................................................................... 115
ANEXO G: .................................................................................................................... 119
xii
Lista de Figuras
FIGURA 1: MODELO OSI ......................................................................................................................... 9
FIGURA 2: NÍVEIS DE APLICAÇÃO E FÍSICO DO MODELO OSI ............................................................................ 10
FIGURA 3: CAMADA DE ENLACE .............................................................................................................. 11
FIGURA 4: COMUNICAÇÃO ENTRE SISTEMAS DE REDE [F1] ............................................................................. 12
FIGURA 5: ESQUEMA DE UM MOTE E OS SEUS PRINCIPAIS COMPONENTES........................................................... 14
FIGURA 6: ESQUEMA SIMPLIFICADO DA INTERLIGAÇÃO DE UMA REDE DE SENSORES SEM FIOS COM UM HOST .............. 16
FIGURA 7: BANDAS DE FREQUÊNCIAS OPERACIONAIS NAS DIFERENTES FREQUÊNCIAS [F2] ...................................... 18
FIGURA 8: ARQUITETURA DO PADRÃO IEEE 802.15.4 [F3]........................................................................... 19
FIGURA 9: FORMATO DO PPDU.............................................................................................................. 20
FIGURA 10: EXEMPLO DE UMA REDE COM TOPOLOGIA EM ESTRELA. ................................................................. 21
FIGURA 11: EXEMPLO DE UMA REDE COM TOPOLOGIA PEER-TO-PEER. .............................................................. 22
FIGURA 12: EXEMPLO DE UMA REDE COM TOPOLOGIA EM ÁRVORE. ................................................................. 22
FIGURA 13: ESTRUTURA GENÉRICA DAS TRAMAS MPDU [F4] ........................................................................ 23
FIGURA 14: FORMATO DA TRAMA DE DADOS [F5] ....................................................................................... 24
FIGURA 15: FORMATO DA TRAMA BEACON [F6] ......................................................................................... 24
FIGURA 16: FORMATO DA TRAMA DE CONFIRMAÇÃO [F7] ............................................................................. 25
FIGURA 17: FORMATO DA TRAMA DE COMANDO MAC [F8] .......................................................................... 25
FIGURA 18: ENQUADRAMENTO DA PILHA ZIGBEE [F9] .................................................................................. 26
FIGURA 20: ARQUITETURA DO PADRÃO IEEE 802.11 [F11] .......................................................................... 29
FIGURA 21: REPRESENTAÇÃO GRÁFICA DAS DIFERENTES REDES DE TRANSMISSÃO SEM FIO [F20].............................. 29
FIGURA 21: MÓDULOS DO KIT RZRAVEN [F12] ........................................................................................ 30
FIGURA 22: LISTA DE PLATAFORMAS AVR PASSÍVEIS DE EXECUTAR O BITCLOUD .................................................. 34
FIGURA 24: PILHA PROTOCOLAR BITCLOUD [F13]....................................................................................... 35
FIGURA 25: RESPOSTA SÍNCRONA E ASSÍNCRONA [F14] ................................................................................ 37
FIGURA 26: LISTA DE FUNÇÕES RELATIVAS À CAMADA APS ............................................................................ 42
FIGURA 27: FORMATO TÍPICO DO ADSU [F15] .......................................................................................... 42
FIGURA 28: TRANSMISSÃO DE DADOS [F16] .............................................................................................. 43
FIGURA 29: RECEÇÃO DE DADOS [F17] ..................................................................................................... 44
FIGURA 39: ARQUITETURA DO SISTEMA MOTE RUNNER [F18] ....................................................................... 47
FIGURA 40: MODELO DA TOOLCHAIN DO SISTEMA MOTE RUNNER [F19] .......................................................... 51
FIGURA 41: CLASSES DO SISTEMA MOTE RUNNER........................................................................................ 52
FIGURA 42: DELEGATES DO SISTEMA MOTE RUNNER .................................................................................... 53
FIGURA 43: EXCEÇÕES DO SISTEMA MOTE RUNNER ..................................................................................... 54
FIGURA 44: FLUXOGRAMA DA APLICAÇÃO DO ATUADOR ................................................................................ 56
FIGURA 45: FLUXOGRAMA DA APLICAÇÃO EMISSORA .................................................................................... 57
FIGURA 46: CONFIGURAÇÃO DO DISPOSITIVO ............................................................................................. 58
FIGURA 47: PEDIDO DE ARRANQUE DA REDE ............................................................................................... 60
FIGURA 48: REGISTRO DE ENDPOINT ASSOCIADA À UMA FUNÇÃO CALLBACK........................................................ 60
FIGURA 49: INICIALIZAÇÃO DAS VARIÁVEIS RELATIVAS AO TIMER ...................................................................... 61
FIGURA 50: CONFIGURAÇÃO DO TIMER ..................................................................................................... 61
FIGURA 51: ARRANQUE DO TIMER ........................................................................................................... 61
FIGURA 52: FUNÇÃO DE CALLBACK DE RECEÇÃO DE TRAMAS ........................................................................... 62
FIGURA 53: FUNÇÃO DE CALLBACK DO TÉRMINO DO TIMER ............................................................................ 62
FIGURA 54: CONFIGURAÇÃO DO DISPOSITIVO END DEVICE .............................................................................. 63
FIGURA 55: LEITURA DO ESTADO DO SENSOR DE PRESENÇA ............................................................................ 64
xiii
FIGURA 56: ENVIO DA TRAMA ................................................................................................................ 64
FIGURA 57: INICIALIZAÇÃO DO DISPOSITIVO DE RÁDIO ................................................................................... 65
FIGURA 58: ATRIBUIÇÃO DOS PARÂMETROS DE REDE E DO DISPOSITIVO ............................................................. 65
FIGURA 59: DELEGATE DE RECEÇÃO DAS TRAMAS ........................................................................................ 66
FIGURA 60: DELEGATE DE ALARME DO TIMER ............................................................................................. 66
FIGURA 61: FUNÇÃO DE CALLBACK INVOCADA NA RECEÇÃO DA TRAMA .............................................................. 67
FIGURA 62: FUNÇÃO DE CALLBACK INVOCADA NO TÉRMINO DO TIMER .............................................................. 67
FIGURA 63: PREPARAÇÃO DA TRAMA A SER ENVIADA .................................................................................... 68
FIGURA 64: PREPARAÇÃO DO PINO DE LEITURA DO SENSOR DE PRESENÇA .......................................................... 69
FIGURA 65: DELEGATE PARA LEITURA DO SENSOR DE PRESENÇA ....................................................................... 69
FIGURA 66: LEITURA DO SENSOR DE PRESENÇA............................................................................................ 69
FIGURA 67: FUNÇÃO DE CALLBACK PARA A LEITURA DO ESTADO DO SENSOR DE PRESENÇA ...................................... 70
FIGURA 68: DELEGATE DO TIMER............................................................................................................. 71
FIGURA 69: FUNÇÃO DE CALLBACK PARA O ENVIO DA TRAMA ......................................................................... 71
xiv
Lista de Tabelas
Tabela 1: Tabela das bandas de frequências e taxas de transmissão
xv
xvi
GLOSSÁRIO
Empresas:
IBM
International Business Machines
Organizações:
IEEE
Institute of Electrical and Electronics Engineers
ISO
International Organization for Standardization
ITU
International Telecommunication Union
Protocolos:
ARP
Address Resolution Protocol
DNS
Domain Name System
EBCDIC
Extended Binary Coded Decimal Interchange Code
FDDI
Fiber Data Distributed Interface
FTP
File Transfer Protocol
ICMP
Internet Control Message Protocol
IMAP
Internet Message Access Protocol
I2C
Inter-Integrated Circuit
IP
Internet Protocol
IPX
Internetwork Packet Exchange
IRC
Internet Relay Chat
HTTP
Hypertext Transfer Protocol
NDR
Non-Delivery Report/Receipt
PCI
Protocol Control Information
POP3
Post Office Protocol 3
xvii
RARP
Reverse Address Resolution Protocol
RCP
Rich Client Platform
RDP
Remote Desktop Protocol
SCP
Session Control Protocol
SIP
Session Initiation Protocol
SMTP
Simple Mail Transfer Protocol
SNMP
Simple Network Management Protocol
SPI
Serial Peripheral Interface
SSH
Secure Shell
TCP
Transmission Control Protocol
TWI
Two Wire Interface
UDP
User Datagram Protocol
USART
Universal Synchronous Asynchronous Receiver Transmitter
USB
Universal Serial Bus
Redes de dados:
LAN
Local Area Network
LR-WPAN
Low Rate Wireless Personal Area Network
MAN
Metropolitan Area Network
PAN
Personal Area Network
POS
Personal Operating Space
RSSF
Redes de Sensores Sem Fio
WAN
Wide Area Network
WPAN
Wireless Personal Area Network
WSN
Wireless Sensor Network
Tecnologias:
xviii
ASIC
Application Specific Integrated Circuit
CPU
Central Processing Unit
DSP
Digital Signal Processing
EEPROM
Electrically-Erasable Programmable Read-Only Memory
FPGA
Field Programmable Gate Array
LCD
Liquid Cristal Display
LED
Light Emitting Diode
LPT
Line Print Terminal
MCU
Microcontroller Unit
MEMS
Micro-Eletro-Mechanical Systems
PDA
Personal Digital Assistants
RAM
Random Access Memory
Unidades:
Gbps
Giga bits por segundos
GHz
Giga Hertz
KB/s
Quilo Bytes por segundo
km
Quilómetros
m
Metros
MHz
Mega Hertz
ms
Mili Segundos
uW
Micro Watts
Outros:
ACK
Acknowlegment
ADC
Analog-to-Digital Converter
xix
xx
API
Application Programming Interface
APL
Application Layer
APS
Aplication Support Sublayer
BPSK
Binary Phase Shit Keying
BSP
Board Support Package
CCA
Clear Channel Assessment
CSMA-CA
Carrier Sense Multiple Access with Collision Avoidance
DLL
Dynamic-link library
ED
Energy Detection
FFD
Full Function Device
GPIO
General Purpose Input/Output
HAL
Hardware Abstraction Layer
I/O
Input/Output
IDE
Integrated Development Environment
IRQ
Interrupt Request
LLC
Logical Link Control
LQI
Link Quality Indication
MAC
Medium Access Control
MFR
MAC Footer
MHR
MAC Header
MPDU
MAC protocol data unit
NWK
Network layer
O-QPSK
Offset Quadrature Phase-shift keying
OSI
Open Systems Interconnection
PANID
Personal Area Network identifier
PDU
Protocol Data Unit
PHR
Physical layer Header
PHY
Physical layer
PPDU
Physical layer Protocol Data Unit
PSDU
Physical layer Service Data Unit
QoS
Quality Of Service
RF
Radio Frequência
RM-OSI
Reference Model Open Systems Interconnection
RX
Receive
SAP
Service Access Point
SDU
Service Data Unit
SDK
Software Development Kit
SFD
Start Frame Delimiter
SHR
Synchronization Header
SIL
Saguaro Intermediate Language
SSCS
Service Specific Convergence Sublayer
TX
Transmission
VM
Virtual Machine
ZDO
ZigBee Device Object
ZDP
ZigBee Device Profile
xxi
xxii
CAPÍTULO 1 - INTRODUÇÃO
Capítulo 1
Introdução
Neste capítulo é feito uma introdução genérica desta dissertação. São
apresentados o contexto onde o trabalho se insere assim como a motivação e os
objetivos a serem atingidos. No final é apresentado a estrutura deste documento,
descrevendo os temas abordados em cada capítulo.
1
1.1 Enquadramento
Porque as redes de sensores se tornaram cada vez mais imprescindíveis em
inúmeras áreas, o desenvolvimento de soluções se tornaram cada vez mais
complexas aumentando assim a sua dificuldade de desenvolvimento.
Devido a essas dificuldades, vários fabricantes de dispositivos de rede criaram
plataformas de desenvolvimento para auxiliar os profissionais da área na elaboração
das redes de sensores.
Os ambientes de desenvolvimento para redes de sensores sem fios se baseiam em
diferentes abordagens o que faz com que os profissionais da área sejam obrigados a
possuir um elevado grau de conhecimento em relação aos distintos métodos de
desenvolvimentos.
1.2 Motivação e Objetivos do trabalho
A motivação central deste trabalho vai ao encontro de um estudo aprofundado
sobre ambientes de desenvolvimento de sistemas baseados em redes de sensores sem
fios.
O principal objetivo desta dissertação consiste no estudo e na análise de duas
abordagens de desenvolvimento de sistemas de comunicação entre dispositivos sem
fio criadas pela Atmel e IBM e fazer posteriormente a comparação. Para isso nessa
dissertação foi desenvolvida uma aplicação utilizando as diferentes plataformas
estudadas e analisadas previamente. Como ponto de partida se sabe que a principal
diferença entre os dois sistemas utilizados se encontra ao nível de abstração da
linguagem e da biblioteca de API fornecida por cada uma das plataformas de
desenvolvimento, se pretende conhecer até que ponto é vantajoso trabalhar com um
ambiente dotado de ferramentas sofisticadas e com poderosas bibliotecas e quais as
limitações que esse ambiente impõe.
2
CAPÍTULO 1 - INTRODUÇÃO
1.3 Organização da Tese
Esta dissertação está estruturada em 5 capítulos que são aqui descritos.
No primeiro capítulo se faz uma breve introdução à tese referindo o
enquadramento do trabalho, os seus objetivos, motivação e a sua estrutura.
No segundo capítulo se apresentam os conceitos estudados mais importantes sobre
as redes de dados, redes de sensores sem fios e da plataforma computacional
utilizada neste trabalho.
No
terceiro
capítulo
se apresentam detalhadamente
os ambientes de
desenvolvimento utilizados na elaboração das respetivas aplicações. Se faz referência
ao tipo de programações que podem ser usadas, às bibliotecas de API e as
plataformas computacionais passíveis de serem suportadas por cada sistema de
desenvolvimento.
No quarto capítulo é explicado os processos efetuados para o desenvolvimento e
testes experimentais das aplicações descrevendo as funções utilizadas.
Por último, no quinto capítulo se apresentam as conclusões retiradas do trabalho
desenvolvido bem como as perspetivas de projetos futuros.
3
4
CAPÍTULO 2 – CONCEITOS
Capítulo 2
Conceitos
No presente capítulo são apresentados os principais conceitos fundamentais para a
elaboração desta dissertação, com o objetivo de fornecer uma base teórica essencial
para melhor compreensão do projeto desenvolvido.
Inicialmente são introduzidos os conhecimentos fundamentais sobre as redes de
dados também conhecidas como redes de computadores. Posteriormente são
apresentadas as redes de sensores sem fios e as aplicações em que podem ser
inseridas. Para concluir este capítulo é apresentada a plataforma computacional que
foi escolhida para a execução do presente trabalho.
5
CAPÍTULO 2 - CONCEITOS
2.1 Redes de dados
Uma rede de dados consiste em dois ou mais dispositivos computacionais
interligados que trocam dados entre si. Um dos exemplos mais conhecido de uma
rede de dados é a Internet que interliga um vasto número de dispositivos.
2.1.1 Conceitos de redes de computadores
Existem vários tipos de redes de dados em que podem ser classificados segundo a
extensão geográfica, a topologia e segundo o meio de transmissão utilizado.
A extensão geográfica se refere às distâncias que separam os diferentes
dispositivos computacionais que integram numa rede de dados. Estas redes podem
ter diferentes designações consoante a área geográfica abrangente, as mais
conhecidas são:
- Rede Pessoal (PAN – Personal Area Network)
- Rede Local (LAN – Local Area Network)
- Rede Metropolitana (MAN – Metropolitan Area Network)
- Rede geograficamente distribuída (WAN – Wide Area Network)
As redes IEEE 802® PAN foram desenvolvidas para operar em ambiente POS
(Personal Operating Space). Os dispositivos deste tipo de rede são separados por
distâncias muito reduzidas que variam entre poucos centímetros a alguns metros. As
redes WPAN (Wireless Personal Area Network) foram criadas como uma versão sem
fio das redes PAN cablada, abrangendo um alcance de cerca de 10m para todas as
direções e cobrindo uma área circundante ao dispositivo, esteja este estacionário ou
em movimento. O principal objetivo das WPANs é oferecer uma rede de dados de
baixo custo, baixo consumo energético, curto alcance e com dispositivos de
6
CAPÍTULO 2 – CONCEITOS
complexidade reduzida. As WPANs podem ser encontradas em tecnologias como
ZigBee®, Z-Wave® e Bluetooth® apresentadas no capítulo seguinte.
As LAN permitem que distâncias de intercomunicação de dados entre os
equipamentos atingem uma pequena região como salas inteiras, imóveis ou até
campi. Este tipo de rede possui elevadas taxas de transmissão (até 10 Gbps)
acompanhadas de uma reduzida taxa de erro. A Ethernet e o Wi-Fi são exemplos
bem presentes de redes locais.
Por sua vez uma MAN é uma rede de dados que opera em vastas áreas como por
exemplo cidades. Normalmente as MANs ligam um número de redes locais
formando uma única de maior alcance. Tecnologias como fibra óticas fornecem
suporte para este tipo de rede que asseguram a qualidade de transmissão apesar das
grandes distâncias que separam os equipamentos.
Por último, as redes WANs representam as redes de dados de maior extensão
permitindo a intercomunicação de dados entre cidades, países e continentes.
Como foi referido, as redes podem ser classificadas igualmente conforme a
topologia que apresentam. Quando se fala em topologia de rede, se refere à forma
como os dispositivos estão interligados entre eles. As topologias mais comuns são as
redes em barramento, as redes em anel, as redes em estrela e as redes em malha.
As redes em barramento são um tipo de topologia em que todos os dispositivos
estão interligados através de um cabo partilhado denominado de barramento.
Cada dispositivo que faz parte de uma rede com topologia em anel está conectada
a dois outros dispositivos formando assim um único caminho para o tráfego dos
dados atravessando os vários nós que integram a rede.
A topologia em estrela é das configurações mais utilizadas nas redes de dados.
Aqui todos os dispositivos da rede estabelecem uma única linha de comunicação com
um dispositivo central principal em que tem como principal tarefa retransmitir os
dados recebidos.
As redes em malha são um género de redes em que cada dispositivo presente
estabelece comunicações com os dispositivos vizinhos fazendo não só o papel de
emissor ou/e recetor mas também de reencaminhador de dados.
7
CAPÍTULO 2 - CONCEITOS
Como já foi referido as redes são um aglomerado de dispositivos que enviam,
recebem e reencaminham dados, mas para que tal seja possível, é necessário que
cada máquina da rede recorra a protocolos de comunicação. Os protocolos de
comunicação permitem que haja troca de dados entre os diferentes dispositivos que
constituem uma rede, pois especificam o formato e o significado das mensagens
trocadas. Em termos de organização, os protocolos são estruturados em camadas para
que cada camada lide com as diferentes fases da comunicação.
2.1.2 Modelo OSI
Inicialmente, cada fabricante relacionado com a produção de computadores e
outros dispositivos de rede tinha a sua própria tecnologia, topologia e protocolos de
comunicação o que provocava muitos problemas ao nível de compatibilidade entre os
diversos aparelhos oriundos de diferentes fabricantes. Com o progresso e ascensão
das tecnologias de rede de informação, os fabricantes optaram se basearem em
normas com finalidade de limitar os problemas de compatibilidade.
De todas as organizações relacionadas com a normalização se evidenciam as
seguintes:
-
IEEE (Institution of Electrical and Electronics Engineers)
-
ISO (International Organization for Standardization)
-
ITU (International Telecommunication Union)
É importante referir que o modelo OSI não é um protocolo propriamente dito mas
sim uma abstração genérica.
O modelo OSI é constituído por 7 camadas e em que cada uma das camadas
realiza funções específicas, Figura 1.
8
CAPÍTULO 2 – CONCEITOS
Figura 1: Modelo OSI
No topo da pilha (camada 7) se encontra a camada de Aplicação referente aos
protocolos utilizados por aplicações como os browsers. Nesta camada são
disponibilizados os recursos necessários ao nível das aplicações para que a
comunicação utilizador/máquina possa ocorrer. Alguns protocolos utilizados nesta
camada são: HTTP, SMTP, FTP, SSH, Telnet, SIP, RDP, IRC, SNMP, NNTP,
POP3, IMAP, BitTorrent, DNS, Ping, NFS entre outros.
Na camada seguinte (camada 6), a camada de Apresentação ou de Tradução é
convertido o formato dos dados provenientes da camada de Aplicação para um
formato independente de maneira a ser utilizado na transmissão. Além de preparar os
dados para a transmissão, a camada de Apresentação trata também, quando
necessário, da criptografia e da compressão dos dados. Um dos protocolos utilizados
nesta camada é o XDR que transforma os dados num formato prório antes de
reencaminhar para a rede, na receção o processo é inverso.
É na camada 5, camada de Sessão, que se estabelece a sessão entre dois processos
em máquinas distintas. Em caso de falha, a camada de Sessão disponibiliza serviços
que permitem o restabelecimento eficaz da rede. Protocolos utilizados nesta camada
são: RCP, SCP, NetBios, entre outros.
Na camada 4 ou camada de Transporte, no caso da máquina transmissora, os
dados recebidos pela camada superior são segmentados e enviados para a próxima
camada (camada de Rede). No caso da máquina recetora, o processo é inverso, a
camada de Transporte recebe os dados segmentados da camada de Rede, junta os
segmentos e reenvia para a camada de Sessão. Como é ilustrado na Figura 2, esta
camada é o elo de ligação entre as camadas superiores e as camadas inferiores tendo
9
CAPÍTULO 2 - CONCEITOS
como principal objetivo garantir o transporte seguro, confiável dos dados
independentemente dos aspetos físicos da rede. Protocolos utilizados nesta camada
são: TCP, UDP, entre outros.
Figura 2: Níveis de aplicação e físico do modelo OSI
A camada 3 ou camada de Rede é a primeira das camadas que tem como
responsabilidade gerir o modo como os dados serão enviados para a máquina de
destino. Esta camada decide qual o caminho que os dados devem tomar ao se basear
nas condições físicas da rede assim como prioridades e outros eventuais fatores.
Resumindo, se pode dizer que é nesta camada que é tratado o encaminhamento
(routing) e o esquema de endereçamento lógico. Os protocolos utilizados nesta
camada são: IP, IPX, entre outros.
A camada 2 ou camada de Ligação de Dados é responsável pela
transmissão/receção das tramas, assim como pelo controlo de fluxo. Na receção, os
erros que possam ocorrer na camada Física são detetados e necessariamente
corrigidos pela camada de Ligação de Dados. Em algumas redes como é o caso de
redes do padrão IEEE 802, esta camada se divide em duas subcamadas chamadas de
LLC (Logical Link Control) e MAC (Media Access Control) como é representado na
Figura 3. A subcamada LLC fornece uma interface para a camada logo acima
(camada de Rede) enquanto a camada MAC tem a responsabilidade de aceder o meio
físico e controlar as transmissões de dados. Os protocolos utilizados nesta camada
são: Ethernet, FDDI, Frame Relay, entre outros.
10
CAPÍTULO 2 – CONCEITOS
Figura 3: Camada de Enlace
Por fim, a primeira camada ou camada física, é a camada mais próxima à rede
propriamente dita. Por ela, passam todo o fluxo de dados brutos através de interfaces
físicas tais como fibras óticas, cabos coaxiais ou antenas.
Contudo, apesar do modelo de referência OSI possuir 7 camadas distinta, não
implica que todas as redes de dado sejam iguais. De facto, o número, o nome, o
conteúdo e a função de cada camada varia de rede para rede. Porém, o objetivo de
cada camada em qualquer rede é oferecer determinados serviços para a camada
situada acima [1], [2] e [3].
2.1.3 Conceito de serviço
A comunicação entre dispositivos de rede ocorre através das diferentes camadas
de protocolos contidos em cada dispositivo, isto é, uma determinada camada n de um
dispositivo de rede que estabelece comunicação com a mesma camada n de outro
dispositivo da mesma rede se baseia numa série de regras que gerem esta mesma
comunicação chamadas de protocolos da camada n, Figura 4.
11
CAPÍTULO 2 - CONCEITOS
Figura 4: Comunicação entre sistemas de rede [F1]
Uma determinada informação que transite de um dispositivo para outro é
modificada por cada camada. Inicialmente no dispositivo de origem, cada camada
adiciona um cabeçalho aos dados e reenvia para a camada imediatamente abaixo até
atingir o meio físico e ser enviado. Por outro lado, o dispositivo que recebe os dados
faz precisamente o oposto, ou seja, cada camada retira o cabeçalho respetivo e
reenvia os dados para a camada imediatamente acima até atingir o destino pretendido
com a informação original. Por exemplo os dados entregues à camada de aplicação
(camada de mais alto nível do modelo OSI) são denominados de SDU (Service Data
Unit), posteriormente é acrescentado aos dados um cabeçalho nomeado de PCI
(Protocol Control Information) relativa à camada de aplicação. Os dados resultantes
desta união recebem o nome de PDU (Protocol Data Unit) correspondente à unidade
de dados do protocolo da camada de aplicação.
Entre cada par de camadas adjacentes existe uma interface que permite a
transferência das operações e serviços que a camada inferior oferece à camada
superior. Um conjunto de camadas que compõem uma rede de dados tem o nome de
arquitetura da rede ou pilha protocolar da rede.
Os serviços de rede são operações implementadas por um protocolo e servindo as
necessidades da camada imediatamente acima através da interface comum a partir de
um ponto de acesso ao serviço (SAP – Service Access Point) e em que cada SAP é
suportada primitivas de serviço necessárias à ativação da funcionalidade solicitada.
Os serviços podem ser orientados a conexão ou não. Segundo a norma IEEE as
primitivas de serviço descrevem os serviços de forma abstrata existindo 4 tipos
utilizadas para a transferência de dados entre camadas.
- Pedido (Request): Esta primitiva é enviada inicialmente pela camada superior à
camada imediatamente abaixo para efetuar uma solicitação ou ativação de um
determinado serviço.
- Indicação (Indication): Primitiva que informa a ocorrência de um determinado
pedido no sistema remoto, isto é, uma primitiva é recebida pela camada superior
proveniente da camada inferior que informa a ativação do serviço pretendido ou de
um evento iniciado pela camada inferior.
12
CAPÍTULO 2 – CONCEITOS
- Resposta (Response): Resposta a um determinado pedido. Primitiva com origem na
camada superior do sistema remoto que em resposta à primitiva Indicação pode
reconhecer ou terminar o evento invocado anteriormente.
- Confirmação (Confirm): Primitiva recebida pela camada superior proveniente da
camada imediatamente abaixo que confirma a execução do serviço solicitado.
As primitivas de serviço possuem parâmetros de entrada e saída que especificam
informações importantes para caracterizar um determinado evento. Por exemplo,
para estabelecer uma comunicação, os parâmetros indicam a máquina alvo, o tipo de
serviço pretendido e o tamanho máximo da mensagem a ser enviada [4], [5], [6], [7]
e [8].
2.2 Redes de Sensores Sem Fios (RSSF/WSN)
Com o avanço da tecnologia, tanto a nível de software como a nível de hardware,
surgiram novas técnicas de transmissão de dados por radiofrequência que
possibilitam que as comunicações se realizem com cada vez menos consumo de
energia e a utilização de micro sistemas eletromecânicos (MEMS – Micro-EletroMechanical Systems), permitiu o surgimento de sensores compactos, confiáveis, de
baixo custo capazes serem aplicados em locais onde era impossível anteriormente e
oferecendo potenciais inovações em vários sectores.
Uma Rede de Sensores Sem Fios (RSSF) ou em inglês Wireless Sensor Network
(WSN) consiste num conjunto de dispositivos autónomos distribuídos num
determinado local onde predomina a troca de dados sem o recurso de ligação por
cabos. Estes dispositivos, denominados de motes têm como componentes principais
os sensores e os atuadores para a monitorização e controlo de sistemas físicos. Além
dos sensores e atuadores, os motes possuem ainda um microcontrolador, memória,
interface de comunicação e uma fonte de alimentação como é ilustrado na Figura 5.
13
CAPÍTULO 2 - CONCEITOS
Figura 5: Esquema de um mote e os seus principais componentes
Os motes que constituem uma rede de sensores sem fios são equipados por um
microcontrolador (MCU) constituído fundamentalmente por processador e memória.
Como alternativa à unidade de processamento, existe ainda o processador genérico, o
processador de sinal digital (DSP), o Field-programmable gate array (FPGA) e o
circuito integrado para aplicações específicas (ASIC - Application Specific
Integrated Circuit). Os microcontroladores permitem o armazenamento das
aplicações através do software implementado, o que permite uma flexibidade em
termos de aplicações, isto é, basta a reprogramação do MCU sem haver necessidade
de o substituir consoante a solução exigida. Além do mais, os microcontroladores são
muito económicos e de fácil conectividade com outros dispositivos.
Os sensores recolhem dados fornecidos do mundo exterior, tal como temperatura,
luminosidade, pressão e humidade. Depois de recolhidos, os dados são convertidos e
processados pelo MCU e enviados para a rede pelo transmissor.
Os atuadores ao contrário dos sensores atuam diretamente sobre o mundo exterior,
isto é, sendo dispositivos ativos interagem e controlam o ambiente em estudo, tal
como válvulas, motores, fontes de aquecimento entre outros.
As atuais redes projetadas para à recolha de dados para a monitorização, têm
demonstrado cada vez mais a sua importância no controlo em tempo real de sistemas
físicos. Baseadas neste conceito, as aplicações mais generalizadas das RSSFs se
tornaram cada vez mais evidentes. As categorias de aplicações mais abrangentes
envolvem a recolha de informações ambientais e físicas, aumentando assim o
número de sensores e atuadores que por sua vez são digitalmente habilitados ou
desabilitados para a coleta de dados e o controlo dos processos.
14
CAPÍTULO 2 – CONCEITOS
Outro componente determinante num mote é o transmissor que é constituído por
um emissor (TX) e um recetor (RX) de dados. Para a comunicação sem fio existem
duas tecnologias disponíveis: comunicação por infravermelho e radiofrequência. Na
primeira tecnologia enunciada, a comunicação por infravermelho despende o uso de
antena, mas a capacidade de difusão para o meio torna-a muito limitada. Por último a
comunicação por rádio frequência, apesar de ser uma tecnologia um pouco mais
complexa e necessitar de antena de transmissão/receção, torna-a a melhor opção para
os motes, não apresentando as desvantagens ao nível de difusão pelo meio como
anteriormente referenciadas.
A fonte de alimentação pode ser representada por baterias (recarregáveis ou não)
ou por condensadores. Para aumentar a autonomia, a fonte de alimentação pode
ainda ser recarregada à partir de painéis solares ou à partir de qualquer outra fonte de
energia proveniente do exterior ao mote.
Os motes utilizam geralmente a transmissão via radiofrequência como meio de
comunicação que normalmente constituem uma rede sem fio ad-hoc, ou seja, uma
rede em que não é necessário existir um ponto de acesso, o que permite que cada
mote consiga suportar o “multi-hop” pelo reencaminhamento de pacotes de dados
provenientes de e para outros motes. Como estes são alimentados por pilhas, é de
extrema importância encontrar soluções para prolongar o seu tempo de vida útil, ou
seja, é exigido que a transmissão via rádio seja efetuada de forma eficiente
consumindo um mínimo de potência possível e para tal cada dispositivo se ativa
periodicamente para receber ou transmitir dados ligando a aparelhagem de rádio e
desabilitando-o logo de seguida quando não necessita de utiliza-lo conservando
assim energia. Igualmente, o processador contido no mote também deve se ativar em
momentos oportunos e entrar em modo “dormir” quando ficar desocupado obtendo
um consumo de apenas 1 a 50uW dependendo do tipo de processador.
Por se tratar de redes ad-hoc, uma típica rede de sensores sem fio utiliza não só os
motes mas também routers e um gateway para a interligação à uma estação principal
(host), onde dados recolhidos são medidos, analisados, processados e apresentados,
assim como os comandos a serem enviados para um eventual processo a ser
executado.
Na Figura 6 é representado um esquema simples da interligação de uma rede de
sensores sem fios com um host.
15
CAPÍTULO 2 - CONCEITOS
Figura 6: Esquema simplificado da interligação de uma rede de sensores sem fios com um host
As RSSF são classificadas como LR-WPAN (Low-Rate Wireless Personal Area
Network), projetadas para pequenas distâncias, operam com taxas de transferências
muito baixas, o custo do equipamento é relativamente mais reduzido assim como o
consumo energético. Ao contrário das redes WLANs, as ligações efetuadas via
WPANs envolvem quase nenhuma infraestrutura de suporte. Isto permite reduzir a
complexidade da instalação, uma maior eficiência energética e uma diminuição de
custo da solução a ser implementada para uma vasta gama de dispositivos [9] [10].
2.2.1 IEEE 802.15.4TM
O Institute of Electrical and Electronics Engineers (IEEE) é responsável por
vários padrões de comunicação. A fim de responder às necessidades do mercado, o
IEEE decidiu formar um grupo de trabalho dedicado às redes pessoais sem fios
denominado IEEE 802.15TM.
O grupo de trabalho especializado IEEE 802.15 definiu três classes de redes
WPANs que podem ser distinguidas pelo débito de dados, consumo energético e
QoS (Quality Of Service). O high-data rate WPAN (IEEE Std. 802.15.3TM) é mais
adequado para aplicações multimédia que requerem um elevado quociente de QoS.
Os medium-data rate WPANs (IEEE Std. 802.15.1TM/Bluetooth®) são designados
como substitutos de cabos para dispositivos de consumo, como telemóveis e PDAs
(Personal Digital Assistants), com um QoS adequado para aplicações de voz. Por
último, a classe LR-WPAN (IEEE Std. 802.15.4TM), é projetada para servir
aplicações de baixo consumo energético e oferecer custos mais acessíveis ao
16
CAPÍTULO 2 – CONCEITOS
contrário das anteriores, pelo que as aplicações que utilizam LR-WPAN não têm
dependência crítica das taxas de transferência e do QoS.
Como o IEEE 802.15.4TM opera em baixas taxas de transferência de dados se
torna possível a redução significativa do consumo e do custo dos equipamentos o que
torna este protocolo adequado em aplicações industriais, médicas ou domésticas. Os
dispositivos baseados no padrão presentemente em análise comunicam com taxa de
transmissão até 250 KB/s e com alcance que pode alcançar os 10m em linha de vista.
Em seguida são apresentadas as características dos sistemas baseados no padrão
IEEE 802.15.4:
 Dois modos de endereçamento: 16-bit short e 64-bit IEEE addressing;
 Acesso aos canais através do mecanismo CSMA-CA (Carrier Sense Multiple
Access with Collision Avoidance);
 Garantia da confiabilidade na transmissão da mensagem;
 Estabilização automática da rede pelo coordenador;
 Protocolo handshaked para transferência segura de dados;
 Gestão energética para garantir o baixo consumo;
 Alcance máximo de 10 m (Linha de vista).
 Suporta tipologias de rede em estrela, ponto-a-ponto e árvore;
 16 canais na banda de 2,4 GHz e débito de 250 KB/s (uso global, modulação
O-QPSK - Offset Quadrature Phase-shift keying), 10 canais na banda de 915
MHz e débito de 40 KB/s (América e Austrália, modulação BPSK) e um
canal na banda de 868 MHz com débito de 20 KB/s (Europa, modulação
BPSK);
Na Tabela 1, se apresenta uma comparação sumária das bandas de frequências
que o padrão IEEE 802.15.4 opera.
17
CAPÍTULO 2 - CONCEITOS
PHY
Banda de
(MHz)
Frequência
Parâmetros de
propagação de sinal
Parâmetros de dados
(MHz)
Modulação
Taxa de transferência (KB/s)
868-868.6
BPSK
20
902-928
BPSK
40
O-QPSK
250
868/915
2450
24002483.5
Tabela 1: Tabela das bandas de frequências e taxas de transmissão
Na Figura 7, se apresenta uma visão geral das diferentes frequências e respetivos
canais operacionais do padrão IEEE 802.15.4.
Figura 7: Bandas de frequências operacionais nas diferentes frequências [F2]
A nível de arquitetura o padrão IEEE 802.15.4 é definido por duas camadas, a
camada física (PHY) e a subcamada de Controlo de Acesso ao Meio (MAC) como é
ilustrado na Figura 8.
18
CAPÍTULO 2 – CONCEITOS
Figura 8: Arquitetura do padrão IEEE 802.15.4 [F3]
A camada física (PHY) é composta pelo transmissor de rádio frequência (RF).
Possui como principais características a ativação/desativação do transmissor,
deteção de energia (ED – Energy Detection), indicação da qualidade de ligação (LQI
– Link Quality Indication), seleção de canal, acesso ao canal (CCA - Clear Channel
Assessment) e transmissão/receção de pacotes de dados (PPDU – Physical Protocol
Data Unit) que atravessam o meio físico.
As tramas PPDU representam os dados transmitidos para o meio de comunicação
e são constituídos pelos seguintes componentes:
 SHR permite que o dispositivo recetor sincronize
- Preâmbulo (32 bits) – Símbolo de sincronização
- SFD (Start Frame Delimiter) (8 bits) – Campo relativo à sincronização,
indica o fim do preâmbulo e início do pacote de dados
 PHR (Physical Header Header) (8 bits) - Especifica o tamanho da trama
PSDU (Physical layer Service Data Unit)
 PHY payload armazena o PSDU (até 127 bytes) – Dados
A Figura 9 representa a estrutura das tramas PPDU trocadas entre as camadas
físicas (PHY).
19
CAPÍTULO 2 - CONCEITOS
Octeto: 4
Octeto: 1
Octeto: 1
Variável
(32 bits)
(8 bits)
Preamble
SFD
(8 bits)
Frame length
Reserved
(7 bits)
(1 bit)
PSDU
SHR
PHR
PHY payload
Figura 9: Formato do PPDU
A subcamada MAC fornece mecanismos de controlo para o acesso dos canais
de comunicação tornando assim possível que diversos nós da rede possam
comunicar através de múltiplos acessos.
Actua ainda como uma interface entre a subcamada LLC e a camada física.
Tipos de nós
Esta subcamada define dois tipos de nós presentes nas redes baseadas no padrão
IEEE 802.15.4, os FFDs (Full-Function Devices) e os RFDs (Reduced-Function
Devices). Estes se diferenciam pela quantidade de tarefas que a pilha de instruções
poderá executar em cada MCU. Os FFDs são destinados para operar como
coordenadores da WPAN, coordenadores de clusteres, routers ou como dispositivos
finais. Estes dispositivos são aptos para implementar protocolos completos e
comunicar com qualquer outro dispositivo seja ele RFD ou FFD.
Por outro lado, os RFDs, sendo estes dispositivos mais limitados em relação à
memória e aos recursos de comunicação, são destinados somente a operar como
dispositivos finais que se encontram nas bordas das WPAN. Estes dispositivos
implementam versões simplificadas dos protocolos permitindo-lhes apenas
comunicar com dispositivos FFDs.
Topologias
Em qualquer rede de comunicação de dados os dispositivos constituintes podem
formar várias topologias de rede. No caso das redes baseadas no padrão IEEE
802.15.4 existem três tipos de tipologias de rede: estrela, peer-to-peer e árvore.
20
CAPÍTULO 2 – CONCEITOS

Topologia em Estrela
Na topologia em estrela, o coordenador da PAN estabelece várias ligações com
outros dispositivos que estejam no seu alcance de transmissão, Figura 10. Este
coordenador se torna o núcleo central em que todos os outros dispositivos da PAN
têm permissão para comunicar. Por ser o coordenador e estar na maioria das vezes a
transmitir dados via radiofrequência, este dispositivo possui elevados consumos de
energia elétrica relativamente aos outros da mesma rede, por isso, é normal este ser
alimentado pela rede elétrica, enquanto os demais por bateria. Para que se forme uma
rede desta topologia, o coordenador inicialmente escolhe um PAN ID e de seguida
permite que outros dispositivos circundantes se conectem à sua rede. Qualquer que
seja a topologia formada, todos os motes terá um único endereço estendido de 64 bits
(8 bytes). Quando estes se associam a rede, o endereço estendido pode ser trocado
por um endereço curto fornecido pelo coordenador.
Figura 10: Exemplo de uma rede com topologia em estrela.

Topologia ponto-a-ponto (peer-to-peer)
A topologia peer-to-peer, como na topologia em estrela, possui um coordenador
PAN responsável pela formação e caracterização da rede, porém neste caso qualquer
dispositivo FFD que esteja ligado ao coordenador pode comunicar com qualquer
outro dispositivo que se encontra no seu raio de transmissão, Figura 11. Esta
topologia permite a implementação de redes sem fio mais complexas.
Neste tipo de rede é permitido o encaminhamento de dados entre os motes que
constituem a rede.
21
CAPÍTULO 2 - CONCEITOS
Figura 11: Exemplo de uma rede com topologia peer-to-peer.

Topologia em árvore
Por último, a topologia em árvore, é uma variante da topologia peer-to-peer, em
que os dispositivos FFDs predominam na rede e os RFDs se encontram nas
extremidades, Figura 12. Neste caso, qualquer FFD pode funcionar como um
coordenador que tem como responsabilidade fornecer serviços de sincronização e
gerir um pequeno grupo de dispositivos para formar uma sub-rede ou “cluster” mas
só um dispositivo permanece como coordenador da rede. O coordenador de rede tem
como principal objetivo a formação da rede estabelecendo um identificador da rede
(PANID) e convidando os dispositivos existentes na periferia a se juntar à rede.
Figura 12: Exemplo de uma rede com topologia em árvore.
Tramas MAC
As tramas MPDU (MAC Protocol Data Unit) relativas à subcamada MAC são
constituídas principalmente pelos seguintes componentes:
22
CAPÍTULO 2 – CONCEITOS
- MAC Header (MHR) – Representa o cabeçalho da trama onde ficam
armazenado as informações relativas à própria trama como a origem, o destino e o
tipo.
- MAC payload – Aqui é guardado os dados concretos para serem processados ou
transmitidos.
- MAC Footer (MFR) – Este campo representa o check sequence da trama.
A Figura 13 representa a estrutura genérica das tramas MPDU trocadas entre as
subcamadas MAC.
Figura 13: Estrutura genérica das tramas MPDU [F4]
Existem 4 tipos de tramas criadas pela subcamada MAC: trama de dados, a trama
de sinalização (Beacon), a trama de reconhecimento (Acknowledge) e a trama de
comando de MAC.
 Trama de dados
Na trama de dados residem os dados a serem transmitidos para a rede
(armazenados no campo Data Payload) representada na Figura 14.
23
CAPÍTULO 2 - CONCEITOS
Figura 14: Formato da trama de dados [F5]
 Trama Beacon
A trama Beacon ilustrado na Figura 15 contém informações da rede e é
transmitida periodicamente pelo coordenador ou routers para indicar a
existência da rede. A trama Beacon transporta ainda notificações sobre
mensagens pendentes de nós da rede.
Figura 15: Formato da trama Beacon [F6]
 Trama de Confirmação (Acknowledgment)
Esta trama ilustrada na Figura 16 é utilizada pelo dispositivo para reconhecer
a boa receção de um pacote.
24
CAPÍTULO 2 – CONCEITOS
Figura 16: Formato da trama de confirmação [F7]
 Trama de Comando MAC
A trama de comando representada na Figura 17 é usada para controlo dos nós
clientes
Figura 17: Formato da trama de comando MAC [F8]
Acima da camada MAC existe uma subcamada superior SSCS (service specific
convergence sublayer) que fornece às camadas de maior nível, incluindo a
subcamada LLC (logical link control) o acesso ao MAC [11], [12], [13], [14] e [15].
25
CAPÍTULO 2 - CONCEITOS
2.2.2 Tecnologias WPANs
Atualmente, a maioria dos dispositivos eletrónicos, tem aumentado as suas
capacidades de processamento, o que motivou que esses dispositivos necessitem de
estar sempre em comunicação entre si, promovendo assim a proliferação das redes
pessoais de dispositivos sem fios (WPANs). O padrão IEEE 802.15.4 serve de base
para outros protocolos como o ZigBee® e o 6LoWPAN®. Porém, existem outras
tecnologias de redes WPANs que surgiram tais como o Bluetooth® apoiado no
padrão IEEE 802.15.1 e o UWB - Ultra-Wideband no padrão IEEE 802.15.3.
Uma outra tecnologia é o Z-Wave, desenvolvida pela Zensys, não seguindo
nenhum dos padrões físicos acima, usa um protocolo proprietário, é no entanto um
concorrente direto do ZigBee para o ambiente doméstico.
ZigBee®
Do ponto de vista da arquitetura, o padrão ZigBee® se traduz nas camadas
protocolares de rede, segurança e de suporte à aplicação definidas pela ZigBeeTM
Alliance.
Na Figura 18 é representado o enquadramento da pilha protocolar ZigBee® e as
suas camadas genéricas.
Figura 18: Enquadramento da pilha Zigbee [F9]
26
CAPÍTULO 2 – CONCEITOS
Como se verifica, a pilha Zigbee ® é implementada diretamente a seguir ao padrão
IEEE 802.15.4 já apresentado anteriormente e agora representado abrigando as
camadas de acesso ao meio (MAC) e física (PHY).
O padrão ZigBee se caracteriza também pelo facto de permitir que cada rede
possa gerir uma rede que contenha até 65535 dispositivos. A tecnologia ZigBee foi
desenvolvida com o objetivo principal de realizar monitorização e sensorização de
sistemas, sendo apropriado para aplicações que envolvam dispositivos remotos
alimentados por baterias, nomeadamente sensores e atuadores, já que permite baixos
consumos, débitos aceitáveis e possui uma pilha protocolar mais simples que
possibilita a sua implementação em sistemas com recursos limitados [16] [17] [18].
Numa rede ZigBee® se podem encontrar três tipos de dispositivos lógicos: o
coordenador, router e dispositivo final. Os coordenadores e os routers são
obrigatoriamente dispositivos físicos classificados pela norma IEEE 802.15.4 como
FFD (Full Function Device) enquanto os dispositivos finais podem ser da classe FFD
ou RFD (Reduced Function Device).
O coordenador (C) tem a responsabilidade de inicializar a rede ZigBee com as
características pretendidas e cuidar da sua respetiva manutenção ao armazenar a
informação de gestão interna para o seu bom funcionamento. O coordenador pode
igualmente funcionar como router e como bridge entre outras redes ZigBee. Depois
de uma rede ser formada, outros nós podem se registar através do coordenador ou de
um router que pertença à mesma rede. Existe um único coordenador por cada rede
ZigBee geralmente alimentado por uma fonte de energia permanente (rede elétrica).
O router (R) executa funções de controlo e/ou monitorização o que permite a
comunicação entre os outros nós circundantes, efetuando a retransmissão de dados
provenientes de outros nós para o endereço de destino. Os routers são igualmente
úteis para que outros nós externos possam se juntar à rede, expandindo o alcance
físico da mesma, passando os routers a serem os nós-pais destes novos elementos.
Também funciona como um nó regular, recolhendo dados pelos seus meios e
transmitindo-os para o destino pretendido. A sua existência é opcional.
O dispositivo final (ED) é o dispositivo com menores recursos relacionados com
as funcionalidades de rede. Comunica somente com a rede a partir de um único nópai (coordenador ou router), ou seja, efetua ações de monitorização e/ou de controlo
27
CAPÍTULO 2 - CONCEITOS
não possuindo nenhuma função de gestão como é o caso do coordenador e do router.
Os dispositivos finais são únicos dispositivos na rede que podem entrar em modo
sleep para economizar energia.
2.2.3 Tecnologias WLANs
O Wi-Fi® é uma marca registrada da Wi-FiTM Alliance, utilizada como tecnologia
de transmissão de dados sem fios, suportando altas taxas de transferência. Uma rede
Wi-Fi® é classificada como WLAN e baseada no padrão IEEE 802.11.
À semelhança do padrão IEEE 802.15.4 o padrão IEEE 802.11 abrange a camada
física (PHY) e a subcamada MAC associado a um equipamento wireless LAN. Este
tipo de rede ainda se subdivide em diferentes padrões.

IEEE 802.11a: Padrão Wi-Fi direcionado para frequências de 5 e 6 GHz com
uma taxa de transmissão de 54 Mbps no máximo;

IEEE802.11b: Padrão Wi-Fi direcionado para frequências de 2,4 GHz com
uma taxa de transmissão de 11 Mbps. Este padrão utiliza mecanismos para
diminuição de interferência, o DSSS (Direct Sequency Spread Spectrum);

IEEE 802.11g: Padrão Wi-Fi direcionado para frequências de 2,4 GHz com
uma taxa de transmissão de até 54 Mbps;

IEEE 802.11n: Padrão Wi-Fi direcionado para frequências de 2.4 GHz e 5.8
GHz com uma taxa de transmissão de até 248 Mbps.
A Figura 19 ilustra o padrão IEEE 802.11, comparando-o com o modelo padrão
de redes de computadores, o OSI da ISO.
28
CAPÍTULO 2 – CONCEITOS
Figura 19: Arquitetura do padrão IEEE 802.11 [F11]
Para concluir esta breve apresentação das tecnologias de rede sem fios é
repesentado graficamente na Figura 20 os padrões das redes sem fios mais
importantes, se observando a relação existente entre o alcance e a taxa de
transmissão de dados [19].
Figura 20: Representação gráfica das diferentes redes de transmissão sem fio [F20]
29
CAPÍTULO 2 - CONCEITOS
2.3 Plataforma Computacional
2.3.1 ATMEL RZRAVEN
Figura 21: Módulos do kit RZRAVEN [F12]
O RZRAVEN é um kit de desenvolvimento constituído por um módulo
RZUSBSTICK e dois módulos AVRRAVEN, representado na Figura 21 baseado no
transciever de rádio AT86RF230 e nos microcontroladores AVR Atmega3290P,
Atmega1284P e AT90USB1287. É utilizada como uma plataforma versátil para o
desenvolvimento e depuração de diferentes tipos de aplicações relacionadas com
comunicação por radiofrequência, desde simples comunicações ponto a ponto até
redes com vários nós contendo pilhas de comunicações complexas. Além das
potencialidades de comunicação, o kit ainda fornece interfaces úteis para o utilizador,
tais como conectividade com computadores, LCD e áudio.
Cada
módulo
AVRRAVEN
contém dois
microcontroladores
AVR,
o
Atmega1284P e o Atmega3290P. O Atmega1284P é conectado ao transciever rádio
AT86RF230 e o Atmega3290P é responsável pelo controlo do LCD. Os dois
microcontroladores fazem parte da família AVR picoPower o que garante a
minimização do consumo energético (até 1,8V em operação).
30
CAPÍTULO 2 – CONCEITOS
As comunicações entre os dois microcontroladores são efetuadas através da
transmissão série USART (Universal Synchronous and Asynchronous serial
Receiver and Transmitter).
O AT86RF230 é um transciever rádio de 2.4GHz que é apto para uma ampla
gama
de
aplicações
sem
fios.
Apoio
às
aplicações
IEEE
802.15.4TM
(Reconhecimento automático de pacotes, filtragem de endereço e acesso ao canal
automático) através de uma camada adicional no topo das funcionalidades básicas do
transciever de rádio.
O módulo RZUSBSTICK contém um único microcontrolador, o AT90USB1287.
O microcontrolador AT90USB1287 é conectado ao transciever de rádio AT86RF230
e é responsável pela comunicação via USB ao computador [20].
31
32
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO
Capítulo 3
Interface de programação
Neste capítulo são apresentados os ambientes de desenvolvimento de aplicações
para redes de sensores sem fio utilizados para a realização da dissertação.
Inicialmente é apresentado em detalhe a implementação ZigBeeTM da ATMEL, o
BitCloud. Esta implementação foi desenvolvida e direcionada para ser executada em
plataformas wireless da Atmel. De igual forma, é apresentado detalhadamente o
sistema desenvolvido pela IBM, o Mote Runner.
33
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO
3.1 BitCloud
Desenvolvido pela ATMEL, o BitCloud é uma implementação da pilha ZigBee®.
Possui uma plataforma de desenvolvimento de aplicações relacionadas com
comunicações RF com recursos flexíveis e com ferramentas de fácil utilização para o
utilizador incluindo uma biblioteca em linguagem C.
3.1.1 Introdução do BitCloud
O BitCloud da Atmel é uma pilha protocolar bastante completa do ZigBee TM PRO
que suporta aplicações sem fios seguras, escaláveis e fiáveis que são executáveis em
plataformas wireless da Atmel listadas na Figura 22.
ATAVRRZRAVEN
ZigBit / ZigBit Amp / ZigBit 900
megaRF
UC3
XMEGA
SAM7X
SAM3S
Figura 22: Lista de plataformas AVR passíveis de executar o BitCloud
Sendo uma implementação do protocolo ZigBee® a arquitetura interna do
BitCloud é estruturada de igual forma, isto é, existe uma divisão da pilha de
comunicações em camadas lógicas comuns ao ZigBee®.
O conjunto principal destas camadas lógicas constituído pelas camadas APS
(Aplication Support Sublayer), NWK (Network), MAC (Media acess control) e ZDO
(Zigbee device object) representa o núcleo da pilha que possui a implementação do
34
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO
protocolo de comunicação enquanto as camadas restantes são responsáveis pela
implementação de serviços partilhados (gestão de tarefas, segurança e gestão de
energia) e pela abstração do hardware como as camadas Hardware Abstraction
Layer (HAL) e Board Support Package (BSP).
Na Figura 23 se pode observar a arquitetura por camadas do sistema BitCloud.
Figura 23: Pilha Protocolar BitCloud [F13]
O BitCloud utiliza um conjunto de ferramentas, toolchain, fornecida pela Atmel
(WINAVR), é uma toolchain genérica que não é exclusiva à plataforma em análise.
O WINAVR é dotado de um compilador C, assembler, linker e debugger. A
finalidade do uso deste conjunto de ferramentas visa apoiar o desenvolvimento tendo
em vista a criação de ficheiros executáveis.
3.1.2 Ambiente de programação
O BitCloud fornece uma API para aceder às camadas superiores da pilha de
comunicação, ou seja, o APS e ZDO. Não é possível para o utilizador aceder as
camadas NWK e MAC diretamente pois são camadas de mais baixo nível para que
35
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO
se possa intervir através dos meios fornecidos pela implementação. Em alternativa, é
possível aceder às funcionalidades indiretamente a partir da API fornecida da camada
superior APS.
A camada mais acima no núcleo da pilha BitCloud é o APS (Aplication Support
Sublayer) que fornece a API de mais alto-nível, responsável pelo funcionamento em
rede, à camada de aplicação (APL).
A camada ZDO (ZigBee Device Object) contém o protocolo que constitui a pilha
protocolar ZigBee e é responsável por toda a gestão dos mecanismos interno do
dispositivo. O ZDO fornece um conjunto de API que permite funcionalidades
importantes na gestão da rede como o arranque, o reinício, a formação, juntar ou o
abandonar da rede. Adicionalmente, ainda existem mais três serviços como o gestor
de tarefas, o gestor de energia e o gestor de configuração que podem ser
disponibilizadas não só à aplicação mas igualmente às camadas inferiores do núcleo
da pilha protocolar BitCloud.
Como em qualquer modelo de comunicação é crucial a existência de mecanismos
que sejam responsáveis pelo encaminhamento de dados para que a informação
chegue ao destino pretendido. Estes mesmos mecanismos são fornecidos no ZigBee
pela camada NWK camada de rede ou camada três do modelo OSI.
A camada inferior referente ao núcleo do BitCloud é o MAC. Este permite que
vários dispositivos possam compartilhar o mesmo meio para a transmissão. A
camada MAC é o que controla o acesso ao meio de transmissão e responsável pela
deteção de colisões nas transmissões. Caso um dispositivo entre numa determinada
rede é-lhe atribuído um endereço MAC exclusivo que é armazenado nesta mesma
camada.
O BitCloud fornece também camadas lógicas relacionadas com os diferentes
níveis de abstração do hardware do dispositivo. Entre estas camadas se destacam o
Board Support Package (BSP) e o Hardware Abstraction Layer (HAL). O BSP
fornece um conjunto de drivers para uma gestão dos periféricos presentes na placa de
desenvolvimento como sensores, botões, joysticks, LCD e outros demais. O HAL
inclui um conjunto de APIs para o acesso dos recursos do microcontrolador do
módulo como por exemplo as memórias EEPROMs, timers, portos I/O.
36
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO
Programação BitCloud
O desenvolvimento de aplicações BitCloud se apoia num modelo de programação
baseado em eventos. Os sistemas controlados por eventos são muito utilizados nos
sistemas de baixo processamento e grandes limitações a nível de memória como é o
caso dos sistemas embebidos utilizados em dispositivos de redes sensoriais. Este
estilo de programação implica que a cada invocação de uma função de API seja
associada a uma notificação assíncrona da conclusão ativada através de uma função
de callback. Contudo, a maioria do código criado pelo utilizador para interagir com o
dispositivo continua a ser síncrono retornando assim imediatamente o valor
requerido das funções.
O BitCloud contém dois modos de controlar o fluxo do código das aplicações
usando o conceito de resposta por callback: através de confirmação de pedidos e
através de notificações de eventos assíncronos. O controlo de fluxo do código pode
ainda ser efetuado através do pedido do escalonador.
A Figura 24 apresenta os diferentes tipos de resposta existentes num sistema
baseado em eventos: resposta síncrona e resposta assíncrona.
Figura 24: Resposta síncrona e assíncrona [F14]
Ao nível de programação a camada referente à aplicação do utilizador, isto é, na
camada APL são utilizadas funções de apontadores fornecidas pela API do BitCloud
37
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO
que permitem o acesso às funcionalidades das camadas inferiores que posteriormente
respondem aos pedidos através de funções dedicadas para o efeito.
Em aplicações de sistemas não embebidos, a gestão dos recursos do sistema é
normalmente efetuado a partir de um sistema operativo. Porque várias aplicações
podem ser executadas simultaneamente, os sistemas operativos deste género são por
norma muito mais complexos comparando com sistemas de tarefa única ou singletask como é o caso do BitCloud.
Porém, o BitCloud possui mecanismos para superar esta limitação tal como o
timeslicing usado em sistemas preemptivos, isto é, na presença de múltiplas threads
de controlo, a execução de uma função pode ser interrompida pelo escalonador do
sistema num determinado ponto do tempo e dar o controlo a outra thread executando
outra função na mesma aplicação. No caso das funções de callback estas não podem
ser interrompidas para que outra seja executada, cada callback é executada como um
bloco de código atómico.
3.1.3 API de comunicações
A arquitetura BitCloud se apoia na estrutura da especificação ZigBee ® PRO
permitindo que a comunicação entre as aplicações e núcleo da pilha protocolar seja
efetuada diretamente e unicamente através dos componentes ZDO e APS,
simplificando significativamente o desenvolvimento das aplicações bem como
salvaguardar a segurança no protocolo de rede o que garante sempre a
compatibilidade com a especificação ZigBee® PRO.
3.1.3.1 ZDO
O ZDO representa a camada relativa à comunicação ZigBee ® que fornece uma
interface entre a aplicação, o dispositivo e a camada adjacente APS.
O ZDO é responsável pelo seguinte:
38
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO

Inicializar a subcamada APS, a camada de rede (NWK) e o Security Service
Provider.

Fornecer um conjunto completo de funções compatíveis com o protocolo
ZigBee® o que permite obter funcionalidades de gestão de rede (arranque,
restart, formação e união) e de gestão de energia (sleep e wakeup).

Define comandos de busca de dispositivos e serviços, tipos de ZigBee Device
Profile (ZDP) e fornece ainda APIs para transmissões de dados unicast,
multicast e em broadcast.
As funções de busca de dispositivos e serviços do ZDO são operações que
permitem os dispositivos responderem a determinados pedidos efetuados pela
camada ZDO. A operação de busca por dispositivos (device discovery) proporciona a
autorização do dispositivo de reconhecer a existência de outros dispositivos que se
encontram na rede. A operação de busca de serviços (service discovery) proporciona
por sua vez a autorização para determinar serviços fornecidos por outros dispositivos
da rede.
As funções da API direcionadas para a gestão de rede são divididas em dois
grupos. O primeiro grupo é responsável pela configuração dos parâmetros utilizados
para o controlo da rede. O segundo grupo de funções é vocacionado para a leitura da
informação relativa aos dispositivos que constituem a rede.
As funções de controlo da rede são:
- Start network: Arranque da rede;
- Reset network: Reinício da rede;
- Leave network: Abandono da rede;
- Permit joining: Autorização de união à rede;
- Network update and fault notification: Notificação de rede
- Set transmitter power: Configura potência de propagação dos dados
As funções de leitura de dados da rede são:
- Network status: informa o estado da rede;
- Network parameters: informa os parâmetros da rede;
39
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO
- Node address: indica o endereço do nó;
- Energy detection scan results: indica a energia detetada num determinado canal;
- Link quality to neighbor nodes: informa da qualidade de ligação com outros nós;
- Neighbor table contents: Descreve a tabela relativa aos nós da rede;
- Neighbor nodes amount: Indica o número de nós constituintes da rede;
Devido à existência de aplicações que envolvem dispositivos alimentados por
baterias existe a necessidade de aumentar o tempo de vida das mesmas. As funções
do ZDO relativas à gestão energética dos dispositivos vêm ao encontro desta
problemática. Para isso existem mecanismos que colocam os dispositivos que não
estão a ser utilizados num estado de baixo consumo (sleep);
As funções responsáveis pela gestão energética dos dispositivos são:
- Sleep Request: Commando que coloca o dispositivo em modo sleep;
- Wake Up Request: Este comando faz com o dispositivo saia do modo sleep;
- Wake Up Indication: Função que indica a aplicação que a pilha está preparada
para sair do modo sleep;
3.1.3.2 APS
Para as operações relacionadas com a troca de dados entre os diferentes
dispositivos a API respetiva é fornecida pela camada APS, que como anteriormente
mencionado é a camada responsável pela funcionalidade dos dispositivos em rede.
Existem um vasto número de funções fornecidas pela camada lógica APS os quais
são divididas em grupos consoante as suas áreas de atuação.
Os grupos das funções da camada APS são:
- Aps;
Funções principais do APS em que fornecem o controlo do estado interno e das
variáveis intervenientes.
- ApsAIB;
40
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO
Funções relativas às configurações de segurança do dispositivo como a atribuição
do centro de segurança.
- ApsCryptoKeys;
Funções associadas à encriptação de dados.
- ApsdeData;
Funções relativas à transmissão de dados.
- ApsdeEndpoint;
Funções associadas ao registro de pontos terminais.
- ApsmeGroup;
Funções de agrupamento de dispositivos.
- ApsmeRemoveDevice;
Funções de remoção de dispositivos da rede.
Na Figura 25 são apresentadas como exemplo as funções principais fornecidas
pela camada APS.
void APS_Init (void)
Inicialização interna do estado e das variáveis principais da camada APS.
void APS_ResetReq (APS_ResetReq_t *const req)
Reset do APS para o estado de defeito.
void APS_StartReq (APS_StartReq_t *const req)
Faz o pedido ao APS para processar os pacotes recebidos
void APS_StopReq (APS_StopReq_t *const req)
Faz o pedido ap APS para desabilitar o processamento de pacotes recebidos.
bool APS_IsStarted (void)
41
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO
Verifica se o APS está iniciado.
bool APS_IsActiveTransaction (void)
Verifica se existe algum pedido ativo em progresso.
Figura 25: Lista de funções relativas à camada APS
Numa rede ZigBee, os dados das aplicações são trocados entre as aplicações
terminais dos diferentes nós. Cada nó configura pelo menos um ponto terminal
usando a função APS_RegisterEndPointReq() com o argumento do tipo
APS_RegisterEndpointReq_t o que permite as comunicações ao nível das aplicações.
Através do campo simpleDescriptor, o argumento especifica o descritor do ponto
terminal que detém os parâmetros como o identificador do terminal, o identificador
do perfil, o número e as listas de entradas e saídas admitidas.
Para comunicarem entre si, as aplicações dos diversos dispositivos que constituem
uma rede trocam pacotes com um formato padrão denominado de ASDU
(Application-layer Service Data Unit). Em relação à configuração do ASDU a
aplicação tem de inicialmente criar um pedido de transmissão do tipo
APS_DataReq_t que descreve o Payload do ADSU, configura vários parâmetros e
define a função de callback respectiva. A Figura 26 representa o formato típico do
ADSU.
Figura 26: Formato típico do ADSU [F15]
Em relação à transmissão de dados, depois do pedido ter sido criado e todos os
parâmetros serem configurados, a aplicação envia o pedido para o núcleo da pilha
42
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO
protocolar (na camada APS) para efectuar a transmissão por radiofrequência
utilizando a função APS_DataReq() como é representado na Figura 27.
Figura 27: Transmissão de dados [F16]
Para que uma aplicação envie dados para um determinado destino, é invocada a
função APS_DataReq () para pedir à pilha de comunicação, uma rota e que envie os
dados através do caminho mais confiável para o destino pretendido. A pilha mantém
o caminho enquanto for necessário e atualiza-o se existir alguma mudança física na
rede (alteração da topologia ou alteração na qualidade de ligação). Como as
comunicações são bidirecionais, a aplicação pode exigir uma confirmação de receção
da trama de dados (APS ACK).
Numa rede ZigBee®, o dispositivo final se encontra grande parte do tempo em
modo sleep impossibilitando qualquer tipo comunicação com a rede nomeadamente a
receção de tramas. Por isso, para efetuar receções de tramas, um mecanismo de
polling é utilizado por parte do dispositivo final direcionado ao dispositivo no qual
estabelece a comunicação (coordenador ou router). Este processo de polling é
transparente ao utilizador e efetuado ao nível da pilha de comunicação como é
ilustrado na Figura 28.
43
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO
Figura 28: Receção de dados [F17]
Depois de sair do modo sleep, o dispositivo final verifica através do mecanismo
de polling se existe algum dado no buffer do nó emissor (coordenador ou router) e
pronto para ser recebido. Do outro lado, o nó emissor retém a trama no buffer até
receber um pedido do nó recetor. Ao receber o pedido para a transmissão dos dados,
é enviado uma única trama para o dispositivo final com a notificação se existem mais
tramas a serem transmitidas ou não. No momento que deixe de existir tramas no
buffer para ser enviadas, o dispositivo final volta a entrar em modo “sleep” durante
um período pré-estabelecido.
3.1.4 APIs de interface com o hardware
Juntamente com as funcionalidades das redes ZigBee®, a API do BitCloud fornece
também um vasto leque de funcionalidade de interfaces com o hardware.
Este suporte ao hardware se divide em duas APIs fundamentais: o HAL
(Hardware Abstraction Layer) referente unicamente ao hardware do
microprocessador (USART, TWI, SPI, ADC, GPIO, IRQ, etc.) e o BSP (Board
Support Package) referente aos periféricos pertencentes ao mote (sensores, LEDs,
botões e sliders).
44
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO
3.1.4.1 HAL
Esta camada do BitCloud é responsável por todas as interações existentes entre os
módulos Atmel e os seus periféricos. Esta secção apresenta os principais interfaces
de hardware fornecidos pelo BitCloud ao nível do microcontrolador.
O HAL fornece um vasto conjunto de funções que permite um determinado nível
de abstração ao utilizador perante vários detalhes de hardware.
Esta API pode ser dividida em diferentes grupos:

Barramento USART
Estas funções auxiliam na configuração e execução de mecanismos de troca
de dados pelo barramento série USART.

Barramento de interface série two-wire (TWI)
Estas funções auxiliam na configuração e execução de um mecanismo de troca
de dados pelo barramento série TWI.

Barramento SPI
Estas funções auxiliam na configuração e execução mecanismos de troca de
dados pelo barramento SPI.

Interface de GPIO
Fornece um conjunto de funções para gerir o interface GPIO.

Interface de ADC
Fornece um conjunto de funções para gerir o ADC.
É importante referir que grande parte das funcionalidades fornecidas não é
compatível com a placa de desenvolvimento ATAVRRZRAVEN. Se o utilizador
tiver necessidade de utilizar alguma desta funcionalidade terá que fazer um porting
da respetiva função.
45
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO
3.1.4.2 BSP
Esta camada do BitCloud inclui um conjunto de drivers para uma gestão
padronizada dos periféricos já instalados na placa de desenvolvimento (botões,
LEDs, entre outros).
Esta API pode ser dividida igualmente em diferentes grupos:

Interface de botões
Fornece um leque de funções para aceder aos botões da plataforma.

Interface de LEDs
Fornece um conjunto de funções para controlar os LEDs da plataforma.

Interface de sensores
Fornece um leque de funções para aceder aos sensores da plataforma.

Interface de sliders
Fornece um conjunto de funções para controlar os sliders da plataforma.
3.2 Mote Runner
3.2.1 Introdução do Mote Runner
O Mote Runner da IBM, atualmente desenvolvimento na IBM Zurich Research
Laboratory, aborda igualmente o problema do desenvolvimento de redes. De um
modo geral, o Mote Runner além de possuir uma máquina virtual é sobretudo um
ambiente runtime para plataformas de sensores e um SDK (Software Development
Kit) que dispões de ferramentas e fornece serviços para o desenvolvimento de
aplicações que interagem diretamente com os motes que por sua vez procedem a
troca de dados com outros motes da vizinhança através de redes de comunicação sem
fios, isto é, redes de sensores sem fios.
46
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO
Na atualidade, a plataforma Mote Runner se encontra disponível para as
plataformas computacionais da Microsoft, Linux e Mac na versão Beta 3.0
3.2.2 Ambiente de programação
Na Figura 29 é apresentada a arquitetura do Mote Runner.
Figura 29: Arquitetura do sistema Mote Runner [F18]
O Mote Runner tem como estrutura base, o hardware (mote) equipado com os
diversos dispositivos tais como o CPU, controlador de rádio, sensores, atuadores,
fonte de alimentação e sistema de comunicação. Estes recursos são utilizados através
de uma estreita camada de abstração de hardware (HAL) escrita em linguagem C e
em assembler abstraindo as camadas superiores de qualquer funcionalidade
específica da parte física. Na camada que se segue, se encontra a máquina virtual
(VM) que por sua vez também desempenha uma tarefa crucial para a abstração do
hardware que é igualmente desenvolvida em C. Se pode igualmente encontrar uma
biblioteca runtime dedicada à implementação de funções de entrada, saída e de
processamento de dados assim como a gestão de espaço na memória (escrita em C e
47
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO
C#) e o protocolo 802.15.4 igualmente escrita na linguagem C. Por cima destas
últimas, são implementadas as restantes camadas relacionadas com a comunicação
que fornece por sua vez, a API do módulo de rádio necessária à camada de
aplicações posteriormente desenvolvidas.
A plataforma Mote Runner é ao mesmo tempo “um ambiente runtime de
especificação e de implementação para pequenos dispositivos que constituem uma
RSSF” [24].
O ambiente de desenvolvimento suporta uma programação baseada em eventos
com a particularidade que as aplicações podem ser desenvolvidas utilizando
linguagens de programação orientadas a objetos. As linguagens de programação
utilizadas são o Java e o C# com a possibilidade de serem utilizadas
simultaneamente.
Depois de desenvolvidos os códigos das aplicações são compilados e convertidos
em código máquina dando origem aos ficheiros correspondentes aos executáveis
denominados de assemblies que posteriormente são implementados nos motes. O
assembly é a unidade de gestão a ser carregada ou eliminada do dispositivo
embebido. Cada assembly é um recipiente vocacionado para bibliotecas e aplicações
e todos os Assemblies são dependentes de forma implícita do assembly do sistema
que contém os serviços básicos.
Por um lado, é fornecido diretamente um ambiente de execução unificado e
virtualizado, por outro lado é fornecida indiretamente uma estrutura e mecanismos
para a implementação de mais alto nível no mote alvo. Neste caso a eficiência e a
escabilidade, sendo duas características diretamente relacionadas, se referem ao facto
de que as RSSFs ser geralmente constituídas por vários dispositivos, os quais diferem
do poder de processamento e da quantidade de memória disponível, em que aqueles
que são equipados com mais recursos são utilizados como hubs ou gateways,
interconectando clusters de dispositivos com menos recursos. Assim, se exige que os
ambientes runtime para as RSSFs, como acontece com o Mote Runner, devem ser
concebidos de raiz para serem executados de forma eficiente em dispositivos com
recursos muito escassos, isto é, com microcontroladores de 8 bits e com as
memórias, permanente e volátil, bastante limitadas. Com isto, se torna mais fácil
escalar o sistema a ser desenvolvido sem sacrificar a eficiência, fazendo o máximo
proveito dos recursos fornecidos. Quanto à portabilidade, se encontra estruturada em
48
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO
várias escalas. Em primeiro lugar, a existência de uma máquina virtual permite que
as aplicações desenvolvidas sejam de alguma forma separadas das particularidades
da parte física de um vasto conjunto de diferentes motes. Porém, características
específicas de determinados dispositivos podem ser acessíveis através de interfaces
opcionais. O desenvolvimento das aplicações se torna então independente de motes
individuais. Isto garante portabilidade, sendo uma das propriedades requeridas às
aplicações desenvolvidas pelos projetistas, isto é, o desenvolvimento de aplicações
sem ser detalhado o hardware do mote a ser configurado.
Juntamente com o ambiente de desenvolvimento, o Mote Runner fornece um
ambiente gráfico de simulação acessível somente através de um browser específico
(Mozilla Firefox). Este ambiente de simulação oferece várias ferramentas relativas à
criação e gestão de motes virtuais assim como depuração de aplicações, teste e a
análise de redes RSSF incluindo os consumos e a simulação de leituras dos sensores
também virtuais. Apesar de existir poucas plataformas disponíveis para serem
simuladas os dispositivos ATAVRRAVEN se encontram disponíveis para tal.
IRIS (Memsic), RZUSBSTICK e AVRRAVEN (Atmel) são exemplos de
plataformas que suportam atualmente o ambiente de execução Mote Runner.
Máquina Virtual Mote Runner
De um modo geral, a falta de homogeneidade de redes de sensores sem fios
constituídas por motes com enormes restrições de recursos torna operações
importantes como a distribuição dinâmica, o carregamento e eliminação de
aplicações, praticamente impossível de se concretizar sem o auxílio de uma abstração
de alto nível que separa as aplicações dos detalhes específicos do hardware. A
introdução de uma máquina virtual (VM) oferece a desejada camada de abstração.
Como as máquinas virtuais existentes, como as muitas variantes JAVA, não
respondem as exigências impostas pelas redes de sensores sem fio, surgiu então a
necessidade de projetar uma VM de raiz. Esta nova máquina virtual como as demais
foi projetada a partir da linguagem de alto-nível e da remoção dos serviços que são
difíceis de implementar de forma eficiente com recursos limitados como é o caso dos
sistemas embebidos. Além disso, para um uso eficiente dos recursos, a máquina
virtual e o seu código binário têm que ser projetados de acordo com o modelo de
49
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO
programação reativa imposta pelos motes. No desenvolvimento de aplicações, a
máquina virtual necessita de ser capaz de suportar mais que uma linguagem de altonível como o Java e o C# e alavancar ambientes de desenvolvimento (IDEs) como o
Eclipse, Visual Studio e o MonoDevelop.
A máquina virtual do Mote Runner utiliza aproximadamente 2KB de memória
RAM e 23KB de memória permanente o que se enquadra nas configurações do
hardware alvo.
Toolchain
Por detrás da arquitetura apresentada, o Mote Runner dispõe de uma toolchain
que visa apoiar o desenvolvimento tendo em vista a criação de ficheiros executáveis.
Na Figura 30 estão representadas todas as etapas desde o código fonte desenvolvido
em linguagem de alto-nível até o código binário pronto para ser executado. Qualquer
linguagem de alto-nível, compatível com o Mote Runner, está associada a um
compilador específico, por exemplo, para uma aplicação escrita em Java é normal
utilizar o compilador javac enquanto uma aplicação escrita em C# utiliza um
compilador como o Mono C#. Os ficheiros gerados por estes compiladores, ou seja,
os arquivos de classe e DLL (Dynamic-link library) pelo Java e C# respetivamente,
são lidos por um conversor e traduzidos para um código com linguagem intermédia
de mais baixo nível (SIL – Saguaro Intermediate Language) e comum aos códigos
desenvolvidos em linguagens de alto nível. Com os ficheiros SIL gerados, o
assembler processa-os e juntamente com ficheiros de bibliotecas externas (.sxp),
gerando então um assembly de debug (.sda) para a depuração, um assembly binário
(.sba) para a distribuição e um novo arquivo de troca (.sxp). Este último é gerado
para servir de referência à outras aplicações, o que permite updates ao código criado
anteriormente. Por outro lado, o gerador stub, ao contrário dos assemblers e
compiladores, a partir dos ficheiros (.sxp) geram ficheiros de saída (ficheiros stub)
que possuem código com linguagem de alto nível como java e C#. Assim, é fechado
o círculo entre as linguagens de alto nível e as linguagens intermédias de mais baixo
nível, o que evita a necessidade de header files específicos de linguagem.
50
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO
Figura 30: Modelo da toolchain do sistema Mote Runner [F19]
3.2.3 API Mote Runner
Nesta secção é apresentada de forma detalhada a API fornecida pela plataforma
Mote Runner. Como se pode verificar na Figura 31 a API é principalmente
constituída pelas classes que atuam em várias áreas de interesse como as
comunicações e o hardware.
51
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO
Figura 31: Classes do sistema Mote Runner

Assembly – Esta é a superclasse de todas os assemblies carregados no
dispositivo. Permite recolher informações sobre os assemblies como por
exemplo o número de identificação atribuído ou o número da versão.

CDev – Subclasse da classe Device associada às comunicações entre os
dispositivos da rede.

Device – Classe básica para os sensores e os dispositivos de comunicação.

LED – Classe associada aos LEDs existentes no dispositivo.

LIP – Esta classe repesenta o protocolo de ligação do mote a um host.

Mote – Classe que representa o mote.

Radio – Subclasse da classe CDev associada ao acesso ao dispositivo de radio.

SDev – Subclasse da classe Device associada aos sensores do dispositivo.

Time – Classe que fornece o acesso ao tempo do sistema do mote.

Timer – Classe referente ao timer.

Util – Classe associada a utilitários, ferramentas de apoio ao utilizador.

WLIP – Classe referente ao protocolo LIP por rádio.
Além das classes, como o Mote Runner se apoia numa filosofia de programação
baseada em eventos, existe a necessidade de conter uma coleção de delegates para
gerir os eventos relacionados com as típicas redes de sensores invocando a respetiva
callback. Cada delegate corresponde à uma única função de callback que é invocada
52
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO
quando ocorre um determinado evento externo à aplicação de se encontra em
execução.
Existem quatro tipos de delegates, nomeadamente o DataHandler, o DevCallback,
o SystemInfo e o TimerEvent em que cada um se dedica a diferentes eventos, Figura
32.
Figura 32: Delegates do sistema Mote Runner

DataHandler(int,byte[],int) – Corresponde à uma função de callback usada
para a notificação de alguma receção/transmissão de algum dado.

DevCallback(int,byte[],int,int,long) – Função de callback usada para reportar
vários tipos de eventos relacionados com o dispositivo em questão.

SystemInfo(int,int) – Callback do gestor de informação do sistema. Os
eventos notificados informam sobre certas mudanças de estados.

TimerEvent(byte,long) – Esta função de callback é invocada no momento em
que o timer expirar.
Para finalizar, a API do Mote possui igualmente um conjunto de mecanismos para
sinalizar eventuais problemas que possam ocorrer no decorrer das aplicações. Estes
mecanismos são chamados de exceções e correspondem à ativação de flags
relacionadas com o erro ocorrido, Figura 33 [21], [22], [23], [24], [25] e [26].
53
CAPÍTULO 3 – INTERFACE DE PROGRAMAÇÃO
Figura 33: Exceções do sistema Mote Runner
54
CAPÍTULO 4 – ESTUDO DO CASO
Capítulo 4
Estudo do caso
No capítulo aqui exposto são apresentados as implementações realizadas nos
diferentes ambientes de desenvolvimentos anteriormente apresentados: IBM
BitCloud e Mote Runner. No final são apresentadas as comparações identificadas de
cada uma das implementações estudadas.
55
CAPÍTULO 5 – CONCLUSÃO
4.1 Descrição das aplicações
As aplicações foram criadas com a finalidade de conceber dois sistema de deteção
de presença que poderá futuramente ser aplicada numa divisão doméstica. Um dos
sistemas foi baseado na pilha BitCloud da Atmel e outro baseado na plataforma Mote
Runner.
Ambos os sistemas de comunicação são constituídos por duas placas
AVRRAVEN da ATMEL que representam um sensor de presença e uma fonte
luminosa respetivamente.
A placa que representa a fonte luminosa executa a aplicação correspondente ao
recetor e a placa que representa o sensor executa a aplicação correspondente ao
atuador.
Na Figura 34 é apresentado o fluxograma correspondente à aplicação do atuador.
Trama
recebida
Início
Inicialização de
variáveis
SIM
Configuração do
mecanismo de
comunicação
Configuração e
ativação de funções
de callbacks
NÃO
Trama para
ligar a luz?
Ligar
luz
Arranque
do timer
Estado de espera
das tramas
Timer
expirado
Desligar
luz
Figura 34: Fluxograma da aplicação do atuador
56
CAPÍTULO 4 – ESTUDO DO CASO
Na Figura 35 é apresentado o fluxograma correspondente à aplicação sensor.
Início
Inicialização inicial
Configuração do
mecanismo de
comunicação
Leitura do sensor de
presença
Sim
Leitura do
sensor efetuada?
Não
Armazenamento
do dado
Envio da trama
com o dado
Sim
Não
Trama enviada?
Figura 35: Fluxograma da aplicação emissora
57
CAPÍTULO 5 – CONCLUSÃO
4.2 Implementação BitCloud
4.2.1 Atuador
No desenvolvimento da aplicação do atuador que representa a plataforma
associada a uma fonte luminosa se escolheu configurar a placa como coordenador de
rede. Como nas redes ZigBee® o coordenador é responsável pela formação da rede se
achou o mais acertado atribuir a tarefa de atuador luminoso deixando assim a terefa
de sensoriamento aos dispositivos periféricos (dispositivos finais) como o sensor de
presença podendo ser estes numerosos.
Para a elaboração da solução foram efetuados os seguintes passos:
 Inicialização
São declaradas as variáveis globais e locais utilizados na aplicação assim
como protótipos de funções. Nesta secção é igualmente inicializada o estado da
aplicação.
 Configuração do mecanismo de comunicação
Formação de uma rede: Para formar a rede aplicação BitCloud tem que
executar
uma
série
de
procedimentos
de
inicialização
nomeadamente
configuração dos parâmetros do nó apresentado na Figura 36, especificação dos
parâmetros da rede alvo, inicialização do pedido do arranque da rede e respetiva
confirmação.
DeviceType_t deviceType = DEVICE_TYPE_COORDINATOR;
CS_WriteParameter(CS_DEVICE_TYPE_ID,&deviceType);
Figura 36: Configuração do dispositivo
Especificação dos parâmetros da rede alvo
58
CAPÍTULO 4 – ESTUDO DO CASO
Antes do coordenador formar uma rede, ou um router/dispositivo final se juntar a
uma rede existente é necessário que cada dispositivo configure uma série de
parâmetros importantes relativos à caracterização da rede desejada.
1 - Inicialmente é requerido que o parâmetro de configuração do esquema de
modulação seja definido para as bandas de frequências 868/915MHz e 780MHz a
partir do parâmetro CS_CHANNEL_PAGE. Para frequências de 2.4GHz este
parâmetro é ignorado como foi neste caso.
2 - A partir do componente CS_CHANNEL_MASK é determinado a frequência
do canal em que este nó irá operar.
#define CS_CHANNEL_MASK (1L<<0x0f)
3 - O parâmetro CS_EXT_PANID armazena um valor de 64 bits identificador da
rede, o PAN ID, que posteriormente é verificado durante o processo de
união/formação da rede. Todos os dispositivos que queiram fazer parte de uma rede
devem possuir o mesmo valor PANID do coordenador dessa mesma rede. Ao
configurar o valor de PANID em 0x0 de algum dispositivo que não seja coordenador,
o dispositivo irá se unir a qualquer rede nas proximidades. Além do PANID
mencionado, existe o PANID de 16 bits (reduzido) que é utilizado como cabeçalho
das tramas trocadas dentro da rede reduzindo de forma significativa a sobrecarga das
transmissões de dados.
4 - Por último, para completar a caracterização da rede alvo, são configurados os
parâmetros de segurança. A especificação BitCloud fornece dois níveis de segurança
para uma rede ZigBee: nível de segurança de rede padronizada e nível sem
segurança. A escolha do tipo de segurança é feita a partir da inicialização do
parâmetro SECURITY_MODE. No caso de se optar pelo nível de segurança de rede
padronizada,
os
componentes
CS_ZDO_SECURITY_STATUS
e
CS_NETWORK_KEY devem de ser configurados de modo que a rede funcione
conforme o pretendido. Se o parâmetro CS_ZDO_SECURITY_STATUS for
configurado com o valor zero, o dispositivo em questão terá que obrigatoriamente
possuir uma chave de rede retida no parâmetro CS_NETWORK_KEY, assim como
todos os dispositivos presentes na rede. Por outro lado, se o parâmetro
CS_ZDO_SECURITY_STATUS for configurado com o valor três, um dos
dispositivos da rede tem que ser nomeado como Centro de Confiança e possuir uma
59
CAPÍTULO 5 – CONCLUSÃO
chave de rede. Em geral, é nomeado o coordenador como Centro de Confiança mas
não é obrigatório. Assim, todos os restantes dispositivos pertencentes à rede têm que
ser
referenciados
pelo
Centro
de
Confiança
através
do
parâmetro
CS_APS_TRUST_CENTER_ADDRESS para estabelecer a respetiva conectividade,
porém não podem possuir qualquer chave de rede.
Uma vez concluída a caraterização de todos os parâmetros é possível
seguidamente efetuar o pedido à pilha o arranque da rede como é ilustrado na Figura
37.
ZDO_StartNetworkReq(&networkParams);
Figura 37: Pedido de arranque da rede
Completado o procedimento de criação da rede o componente ZDO informa a
aplicação do sucesso da operação através de uma função de callback
ZDO_StartNetworkConf().
 Configuração e ativação de funções de callbacks
Para permitir a receção das tramas ao nível da aplicação o nó Coordenador terá
que criar um registro de endpoint associada à função de callback que irá gerir a
trama recebida como se mostra na Figura 38.
endpointParams.APS_DataInd = APS_DataIndCoord;
APS_RegisterEndpointReq(&endpointParams);
Figura 38: Registro de endpoint associada à uma função callback
No momento da receção da trama pelo transceiver, a pilha verifica a existência
do endpoint correspondente.
Antes da configuração do timer é necessário inicializar a variável
correspondente ao próprio timer do tipo HAL_AppTimer_t correspondente à API
do HAL e outra variável correspondente à função de callback como é mostrado na
Figura 39.
60
CAPÍTULO 4 – ESTUDO DO CASO
static HAL_AppTimer_t meuTimer;
static void meuTimerFired(void);
Figura 39: Inicialização das variáveis relativas ao timer
Para a configuração do timer é necessário indicar o valor correspondente ao
intervalo de tempo associado ao timer assim como o modo de operação e a
atribuição da função de callback como é descrito na Figura 40.
meuTimer.interval = 15000;
meuTimer.mode
= TIMER_ONE_SHOT_MODE;
meuTimer.callback = meuTimerFired;
Figura 40: Configuração do timer
Por último, a ativação do timer com os parâmetros previamente configurados,
Figura 41.
HAL_StartAppTimer(&meuTimer);
Figura 41: Arranque do timer
 Aguarda Trama via wireless
Aqui o escalonador TaskManager fica responsável pela controlo da aplicação
até ser interrompido por algum evento. Neste caso o TaskManager aguarda a
receção de uma eventual trama.
Após a receção de uma trama é automaticamente invocada a função de
callback responsável pela operação.
61
CAPÍTULO 5 – CONCLUSÃO
Rotinas de callback:
 Trama recebida
Na Figura 42 é apresentada a função de callback invocada na receção de uma
trama via wireless.
No momento da receção da trama, a função invocada procede a leitura do
dado pretendido processando-o em seguida.
void APS_DataIndCoord(APS_DataInd_t *indData)
{
msg = *indData->asdu;
if (msg ==1 || msg != 0)
appDeviceState = LIGAR_LUZ;
else
{
if (msg =='B')
appSendLcdMsg(" OFF ");
}
}
Figura 42: Função de callback de receção de tramas
 Timer expirado
Quando a temporização do timer termina é invocada a função de callback
atribuída a este mesmo timer. Esta função tem como objetivo desligar a fonte
luminosa ao fim de um intervalo de tempo pré-estipulado pelo timer aqui
referenciado.
Na Figura 43 é apresentada a função de callback associada ao timer.
static void meuTimerFired()
{
MyLEDoff();
}
Figura 43: Função de callback do término do timer
62
CAPÍTULO 4 – ESTUDO DO CASO
4.2.2 Emissor
No desenvolvimento da aplicação do emissor que representa a plataforma
associada a um sensor de presença a placa foi configurada como um típico end
device de rede.
Para a elaboração da solução foram efetuados os seguintes passos:
 Inicialização
São declaradas as variáveis globais e locais utilizados na aplicação assim como
protótipos de funções. Nesta secção é igualmente inicializada o estado da
aplicação.
 Configuração do mecanismo de comunicação
De igual modo à aplicação respetiva ao coordenador, para formar a rede a
aplicação end device tem que executar uma série de procedimentos de
inicialização nomeadamente configuração dos parâmetros do nó como é
apresentado na Figura 44Figura 36, especificação dos parâmetros da rede alvo,
inicialização do pedido do arranque da rede e respetiva confirmação.
DeviceType_t deviceType = DEVICE_TYPE_END_DEVICE;
CS_WriteParameter(CS_DEVICE_TYPE_ID,&deviceType);
Figura 44: Configuração do dispositivo end device
 Leitura do sensor de presença e armazena dado
O sensor de presença se encontra conectado no pino 0 do porto A e é
verificado periodicamente por polling como é representado na Figura 45.
O pino 0 é verificado e a aplicação armazena um dado numérico ‘0’ ou ‘1’
consoante o valor do sensor de presença.
63
CAPÍTULO 5 – CONCLUSÃO
if((PINA & 0x01) == 0x00)
{
appSendLcdCmd(LCD_CMD_LED_OFF);
messageParams.asdu =0;
}
else
if((PINA & 0x01) == 0x01)
{
appSendLcdCmd(LCD_CMD_LED_ON);
messageParams.asdu = 1;
}
Figura 45: Leitura do estado do sensor de presença
 Envio da trama com o dado recolhido
Após o armazenamento do dado os parâmetros de rede se encontram
atualizados e preparados para efetuar o envio da trama através do transciever
como é representado na Figura 46.
APS_DataReq(&messageParams);
Figura 46: Envio da trama
4.3 Implementação Mote Runner
4.3.1 Recetor
Para o desenvolvimento da aplicação do recetor que representa a plataforma
associada a uma fonte luminosa se efetuou os seguintes passos:
 Inicialização inicial
São declaradas as variáveis utilizadas na aplicação assim como os objectos
intervenientes.
64
CAPÍTULO 4 – ESTUDO DO CASO
 Configuração do mecanismo de comunicação
Por se tratar de uma solução baseada numa linguagem orientada a objetos, foi
criada uma instância do objeto radio previamente declarado assim como a sua
respetiva ativação como é representado na Figura 47.
// Cria uma nova instância Radio
radio = new Radio();
// Ativação do radio
radio.open(Radio.DID, null, 0, 0);
Figura 47: Inicialização do dispositivo de rádio
Em seguida, se procede à configuração da rede de comunicação e do
dispositivo. A Figura 48 representa os parâmetros necessários como a atribuição
de um identificador da rede (PANID) e atribuição do endereço de rede do
dispositivo.
// Configuração do PAN ID
radio.setPanId(0x22, true);
// Configuração do endereço de rede
byte[] myAddrBytes = new byte[8];
Mote.getParam(Mote.EUI64,myAddrBytes,0);
radio.setShortAddr(Util.get16le(myAddrBytes, 0));
Figura 48: Atribuição dos parâmetros de rede e do dispositivo
 Configuração e ativação de funções de callbacks
Para configurar e ativar funções de callback é necessário criar “delegates”,
isto é, um género de apontadores para a função invocada em resposta a eventos
ocorridos.
Na aplicação foram criados dois delegates, o primeiro direcionado para
responder ao evento relativo à receção das tramas como mostra a Figura 49
enquanto o segundo delegate é responsável pela invocação da respetiva função em
resposta ao evento da finalização do timer como é representado na Figura 50.
65
CAPÍTULO 5 – CONCLUSÃO
radio.setRxHandler(
// delegate do tipo “DevCallback"
new DevCallback(null) {
public int invoke (int flags, byte[] data, int len, int info, long time) {
// Acção a ser tomada quando uma trama for recebida.
return AppFinalLed2.onRxPDU(flags, data, len, info, time);
}} );
Figura 49: Delegate de receção das tramas
tsend.setCallback(
// delegate do tipo “TimerEvent"
new TimerEvent(null) {
public void invoke(byte param, long time) {
// Acção a ser tomada quando o alarme do timer disparar
AppFinalLed2.turnOFF(param, time);
}});
Figura 50: Delegate de alarme do timer
Funções de callback:
 Trama recebida
Na receção da trama é invocada uma função de callback chamada onRxPDU()
que verifica o dado e interpreta-o.
Caso o dado verificado seja de valor ‘1’ a aplicação decide ligar a fonte
luminosa associada à placa e caso seja de valor ‘0’ a aplicação ativa o timer que
por sua vez irá invocar outra função de callback no momento do final da
contagem. A Figura 51representa a função de callback invocada no momento da
receção de uma trama.
//Função de callback invocada na receção das tramas
private static int onRxPDU (int flags, byte[] data, int len, int info, long time)
{
if (data == null)
{
// Reinicia a receção das tramas
radio.startRx(Device.ASAP, 0, Time.toTickSpan(Time.MILLISECS,50));
66
CAPÍTULO 4 – ESTUDO DO CASO
return 0;
}
if (data[2] == 1)
{
LED.setState((byte)0,(byte)1); // Liga o LED do Display
gpio.setPin(AVRRAVEN.PIN_PA0,(byte)1); // Liga luz
}
if (data[2] == 0)
{
// Arranque do timer
tsend.setAlarmBySpan(tempo);
}
return 0;
}
Figura 51: Função de callback invocada na receção da trama
 Timer expirado
Quando o timer expirar, isto é, terminar a contagem é invocada uma função
chamada turnOFF() que tem como objetivo desligar a fonte luminosa como é
mostrado na Figura 52.
//Função de callback invocada no final da contagem do timer
public static void turnOFF(byte param, long time)
{
LED.setState((byte)0,(byte)0); ); // Desliga o LED do Display
gpio.setPin(AVRRAVEN.PIN_PA0,(byte)0); // Desliga luz
}
Figura 52: Função de callback invocada no término do timer
4.3.2 Emissor
No desenvolvimento da aplicação do emissor que representa a plataforma
associada ao sensor de presença foram efetuados os seguintes passos:
67
CAPÍTULO 5 – CONCLUSÃO
 Inicialização inicial
São declaradas as variáveis globais e locais utilizados na aplicação assim como
protótipos de funções. Nesta secção é igualmente inicializada o estado da
aplicação.
 Configuração do mecanismo de comunicação
Assim como a aplicação recetor, a configuração dos parâmetros de
comunicação é necessária e feita de igual modo. Logo, é criada uma instância do
objeto rádio e posteriormente ativado. Em seguida é configurado o identificador
de rede e o endereço de rede do dispositivo em questão.
Além dos parâmetros de rede é necessário igualmente a preparação da trama a
ser enviada. Visto ser um dado relativamente pequeno se utilizou a trama beacon
para a transmissão da informação em que será armazenado no campo dedicado ao
número de sequência da trama. A Figura 53 apresenta o fragmento de código
relativo à preparação da trama beacon.
// Prepare beacon frame with source addressing
xmit = new byte[7];
xmit[0] = Radio.FCF_BEACON;
xmit[1] = Radio.FCA_SRC_SADDR;
Util.set16le(xmit, 3, 0x22);
Util.set16le(xmit, 5, 0x1234);
Figura 53: Preparação da trama a ser enviada
 Leitura do sensor de presença
O sensor de presença se encontra conectado no pino 0 do porto A e é
verificado periodicamente a cada intervalo de tempo previamente estipulado.
Para aceder ao hardware foi utilizado a API gpio cedido pela plataforma Mote
Runner.
68
CAPÍTULO 4 – ESTUDO DO CASO
Antes de realizar a leitura é necessário declarar e habilitar o pino pretendido
que se utilizará. A Figura 54 representa o trecho executado para a preparação do
pino I/O da placa RAVEN.
// Declaração de um array de bytes
byte[] gp = csr.allocaByteArray((byte)1);
gp[0] = AVRRAVEN.PIN_PA0;
// Habilita o pino 0
gpio.open(AVRRAVEN.DID_GPIO,gp,0,1);
Figura 54: Preparação do pino de leitura do sensor de presença
Se procede a criação de um delegate que é responsável pela invocação de uma
função de callback no momento da leitura do sensor como mostra a Figura 55.
gpio.setReadHandler(
// Delegate do tipo "DevCallback"
new DevCallback(null){
public int invoke (int flags, byte[] data, int len, int
info, long time) {
return AppFinalSensor.onRead(flags, data, len, info,
time);
}});
Figura 55: Delegate para leitura do sensor de presença
O processo da leitura é efetuada a partir da linha de código apresentada na
Figura 56.
gpio.read(Device.TIMED,0,Time.currentTicks() +
Time.toTickSpan(Time.MILLISECS,80));
Figura 56: Leitura do sensor de presença
69
CAPÍTULO 5 – CONCLUSÃO
Por fim, é apresentado a função de callback invocada no momento da leitura
do estado do sensor de presença na Figura 57. Nesta função a o dado é
interpretado e enviado numa trama via wireless. Consoante o valor do estado do
sensor o LED do display é aceso ou apagado, guardado o respetivo valor e
posteriormente enviado numa trama via wireless.
public static int onRead (int flags, byte[] data, int len,
int info, long time)
{
if(data[AVRRAVEN.PIN_PA0] != 0)
{
// Liga o LED do Display
LED.setState((byte)0, (byte)1);
// Guarda o dado
xmit[2] = 1;
}
else
{
// Desliga o LED do Display
LED.setState((byte)0, (byte)0);
// Guarda o dado
xmit[2] = 0;
}
// Inicio da temporização para envio da trama
tsend.setAlarmBySpan(Time.toTickSpan(Time.MILLISECS, 800));
return 0;
}
Figura 57: Função de callback para a leitura do estado do sensor de presença
 Envio da trama com o dado recolhido
O envio das mensagens é efetuado recorrendo à um timer. Após a leitura do
dado sensorial, é invocada uma função de callback invocada pelo final do timer
para proceder ao envio do dado através de uma trama. O recurso do timer serve
unicamente para fazer um tempo de atraso (delay) entre a leitura e o envio do
dado utilizando o transmissor wireless. Na Figura 58 é criado o delegate do timer
utilizado para o envio da trama.
tsend.setCallback(
70
CAPÍTULO 4 – ESTUDO DO CASO
// Delegate do tipo “TimerEvent"
new TimerEvent(null) {
public void invoke(byte param, long time) {
// Acção a ser tomada quando o alarme do timer disparar
AppFinalSensor.periodicSend(param, time);
}});
Figura 58: Delegate do timer
Na Figura 59 é representado a função de callback invocada pelo final da
contagem do timer para efetuar o envio da trama com o dado recolhido do sensor
de presença. Depois de enviada a trama é ordenada uma nova leitura do pino 0 do
porto A.
public static void periodicSend(byte param, long time)
{
// Envio da trama
radio.transmit(Device.ASAP|Radio.TXMODE_CCA, xmit, 0, 7, 0);
// Volta a ler o sensor
gpio.read(Device.TIMED,0,Time.currentTicks() +
Time.toTickSpan(Time.MILLISECS,80));
}
Figura 59: Função de Callback para o envio da trama
4.4 Comparação/Discussão
Depois de concluídas as implementações é possível comparar, do ponto de vista
do programador, as abordagens utilizadas para a implementação de uma rede de
sensores sem fios.
No que toca ao desenvolvimento das aplicações utilizando o BitCloud
desenvolvida pela Atmel a necessidade prévia de conhecer bem o dispositivo que irá
ser integrado na rede, isto é, antes do desenvolvimento de qualquer aplicação, o
programador tem obrigatoriamente de estudar bem os periféricos existentes assim
como os recursos disponíveis no microcontrolador, tal como os tipos de
comunicações internas por exemplo. Devido a esta condicionante, se chega à
71
CAPÍTULO 5 – CONCLUSÃO
conclusão que a plataforma BitCloud tem uma curva de aprendizagem muito baixa
dada a dificuldade. Ainda, além da questão da arquitetura do hardware, é importante
que o utilizador possua alguma experiência na elaboração de software utilizando a
linguagem C ou de mais baixo nível, pois o BitCloud não oferece grandes
possibilidades de escolha em relação a este assunto. É de referir igualmente, que a
solução desenvolvida é baseada numa programação orientada a eventos, um tipo de
programação muito utilizada em sistemas embebidos o que pode alimentar
dificuldades aos profissionais menos habilitados.
Por outro lado, um utilizador que tenha bastante experiencia consegue tirar o
máximo partido de vários aspetos oferecidos pela plataforma mencionada se
apresentando bastante flexível e disponível para alterações na própria pilha
protocolar visto que se encontra desenvolvida na mesma linguagem de programação
abrindo a possibilidade de criar novos serviços e ferramentas de apoio ou mesmo
eliminar partes que não são necessárias dando lugar a mais espaço na memória.
Resumindo, profissionais altamente habilitados, podem desenvolver qualquer tipo de
aplicação apoiados na tecnologia ZigBee® sem grandes dificuldades e moldar a pilha
protocolar fornecida consoante as necessidades. Por outro lado, o facto de possuir
uma grande disponibilidade para alterações, a pilha se torna vulnerável, pouco segura
e até instável sendo pouco recomendável fazer qualquer tipo de modificação, sendo
neste caso útil uma ferramenta de parametrização da pilha.
Em relação à ocupação da memória, o ficheiro correspondente à aplicação
criada juntamente com a estrutura da pilha protocolar BitCloud ocupa cerca de
246KBytes.
Para o processo de programação das aplicações nas placas RAVEN é
necessário o auxílio de um programador compatível. Neste caso foi utilizado a
plataforma ATAVRDRAGON, desenvolvida igualmente pela Atmel, para se
proceder ao upload das aplicações. Este processo se revelou uma tarefa um pouco
morosa e a obrigar a efetuar ligações físicas ao computador a cada vez que se
pretendesse realizar testes das aplicações desenvolvidas. É sabido que outras
plataformas AVR suportam um mecanismo intitulada de OTAU (Over The Air
Upgrade) que permite a atualização do programa nos motes através do transmissor
de rádio, porém visto não ser suportado pela ATAVRRAVEN utilizada neste
trabalho, o mecanismo não explorado.
72
CAPÍTULO 4 – ESTUDO DO CASO
O Mote Runner da IBM é um sistema de maior complexidade que permite a
utilização de programação de mais alto nível e orientada a objetos podendo utilizar
vertentes de Java e/ou de C Sharp (C#). O facto de aplicações serem desenvolvidas
em linguagens de maior nível permite ao utilizador se abstrair de determinados
pormenores de programação e diminuir substancialmente o tempo despendido.
Apesar de utilizar linguagens de programação de alto nível, o conceito de
“programação baseado em eventos” continua presente também nesta plataforma.
Ainda assim, o Mote Runner oferece ferramentas que facilitam a gestão dos eventos
ocorridos.
A plataforma de execução oferece um nível de abstração relativamente alto o
que permite ao utilizador prescindir dos detalhes técnicos do hardware. Esta
particularidade é bastante útil para utilizadores mais inexperientes ou que pretendem
fazer aplicações rápidas e/ou não desejam se aprofundar em detalhes físicos e
técnicos. Por outro lado, a pilha protocolar é estática do ponto de vista de
possibilidade de alterações, o que torna o sistema praticamente inviolável, sólido e
seguro. Isso acontece porque as aplicações desenvolvidas pelo utilizador são
separadas da máquina virtual existente.
Cada aplicação desenvolvida corresponde ao que é chamado de assembly que é
posteriormente adicionado ao firmware que por sua vez deve ser previamente
gravado na memória do microcontrolador em que cada mote pode albergar vários
assemblies em simultâneo.
Em relação à ocupação da memória, o ficheiro correspondente à aplicação
criada ocupa cerca de 8 KBytes enquanto o firmware ocupa 130 KBytes. É de notar
que o firmware é imprescindível logo o existe no mínimo 130 KBytes de memória
ocupada.
A programação das aplicações nas placas RAVEN é feito unicamente por
radiofrequência, isto é, utilizando o módulo RZUSBSTICK conectado ao
computador se realiza o upload das aplicações via wireless prescindindo qualquer
tipo de ligação física com o mote a ser programado.
73
74
CAPÍTULO 5 – CONCLUSÃO
Capítulo 5
Conclusão
Neste capítulo são apresentadas as conclusões obtidas desta dissertação, são
também apresentadas algumas sugestões de trabalhos que podem ser realizados no
futuro com objetivo de otimizar e melhorar o estudo das plataformas de execução em
questão.
75
CAPÍTULO 5 – CONCLUSÃO
5.1 Aplicações em ambiente de redes de sensores sem fios
O desenvolvimento das aplicações utilizando o ambiente de execução BitCloud
mostrou que é determinante possuir um conhecimento prévio e aprofundado das
placas de desenvolvimento a ser utilizadas como motes da rede. Significa portanto,
que não é de todo aconselhável para utilizadores inexperientes e que queiram se
iniciar nesta área. Por outro lado, um utilizador experiente consegue realizar projetos
de maior complexidade com elevada eficiência. Para aplicações que exigem
dinamismo de parametrização o par BitCloud – ATAVRRAVEN não se torna muito
interessante devido a obrigação de ser necessário interligar fisicamente cada um dos
motes a um programador e computador cada vez que é atualizado o software
residente de um dispositivo. Devido a esta característica enunciada, se conclui que as
soluções criadas pela plataforma de execução BitCloud devem ser de longo período
de funcionamento.
O desenvolvimento das aplicações utilizando o ambiente de execução Mote
Runner mostrou ser mais acessível em relação ao ambiente BitCloud, por prescindir
de conhecimentos prévios sobre o hardware do mote. Significa portanto, que dos
ambientes estudados é o mais indicado para utilizadores com pouca experiencia e
queiram se iniciar nesta área. Por outro lado, um utilizador experiente consegue tirar
maior partido das ferramentas disponibilizadas. Para aplicações que exigem
dinamismo de parametrização o par Mote Runner/ATAVRRAVEN se encontra
bastante indicado à necessidade devido a possibilidade de atualizar o software dos
motes via wireless. Devido a esta característica enunciada, se concluiu que as
soluções criadas pela plataforma de execução Mote Runner são flexíveis de fácil
manutenção.
76
CAPÍTULO 5 – CONCLUSÃO
5.2 Trabalho futuro
Para futuros trabalhos se propõe a otimização das aplicações desenvolvidas de
forma a prolongar a autonomia da solução. Seria também importante repetir o estudo
com diferentes placas de desenvolvimento de diferentes fabricantes. Outra opção
seria criar uma aplicação mais complexa utilizando ambas as tecnologias. Por último,
desenvolver uma solução completa de uma situação real utilizando uma das
plataformas de execução.
77
78
Bibliografia
[1] Romildo Martins Bezerra, CEFET/BA, “Redes de Computadores II”.
[2] Edmar José do Nascimento, Universidade Federal do Vale do São Francisco.
“Redes
de
Computadores”.
Disponível
em:
www.univasf.edu.br/~edmar.nascimento/redes/redes_20112_aula02.pdf.
[3] Sérgio Sobral Nunes, Computadores e Redes de Comunicação, Mestrado em
Gestão de Informação, FEUP 2004/07, “Redes de Comunicação”.
[4] Microsoft, “Definição das Sete Camadas do Modelo OSI e Explicação de suas
funções”. Disponível em support.microsoft.com/kb/103884/pt.
[5] Raj Jain, Washington University, “Data Communications and Networking
Overview”.
Disponível
em
www.cse.wustl.edu/~jain/cse473-
05/ftp/i_2int.pdf.
[6] Wikiversity, “Introdução às Redes de Computadores/Protocolos e serviços de
rede”
Disponível
em
http://pt.wikiversity.org/wiki/Introdu%C3%A7%C3%A3o_%C3%A0s_Redes
_de_Computadores/Protocolos_e_servi%C3%A7os_de_rede.
[7] Gorry Fairhurst - Date: 14/01/2004 EG3557, “Service Primitives”. Disponível
em http://www.erg.abdn.ac.uk/~gorry/course/intro-pages/service-prim.html.
[8] Ricardo Rhomberg Martins, Universidade Federal do Rio de Janeiro,
“Apostila
de
Telefonia”.
Disponível
em
http://pt.scribd.com/doc/50826788/123/Primitivas-de-Servicos.
[9] Linnyer Beatrys Ruiz, Luiz Henrique A. Correia, Luiz Filipe M. Vieira,
Daniel F. Macedo, Eduardo F. Nakamura, Carlos M. S. Figueiredo, Marcos
Augusto M. Vieira, Eduardo Habib Mechelane, Daniel Camara, Antonio A.F.
Loureiro, José Marcos S. Nogueira, Diógenes C. da Silva Jr., “Arquiteturas
para
Redes
de
Sensores
Sem
Fio”.
Disponível
em
http://homepages.dcc.ufmg.br/~mmvieira/publications/04mc-sbrc.pdf.
[10] Departamento de Ciência da Computação – Universidade do Estado de Mato
Grosso, “Introdução a Redes de Sensores sem Fio (RSSF)”. Disponível em
79
http://www.sucesumt.org.br/mtdigital/anais/files/IntroducaoaRedesdeSensore
ssemFio.pdf.
[11] Chun-Yi Chen, “Wireless Medium Access Control (MAC) and Physical
Layer (PHY) Specifications for Low-Rate Wireless Personal Area Networks
(LR-WPANs)”. Disponível em
http://researcher.nsc.gov.tw/public/8905780/Attachment/791017365871.pdf
[12] Atmel, User Guide, “IEEE 802.15.4 MAC”. Disponível em
http://www.atmel.com/Images/doc5182.pdf.
[13] Sinem Coleri Ergen, “ZigBee/IEEE 802.15.4 Summary”, September 10,
2004.
[14] IEEE 802, “IEEE 802.15 WPAN™ Task Group 4 (TG4)”, Monday, 12
November 2012. Disponível em http://www.ieee802.org/15/pub/TG4.html.
[15] Almerindo Rehem, “Wireless Sobre Controle: Usando o Padrão 802.15.4 no
Gerenciamento de Appliances em Rede - O Padrão IEEE 802.15.4”.
Disponível em
http://almerindo.devin.com.br/index.php?option=com_content&view=article
&id=86%3Awireless-sobre-controle-usando-o-padrao-802154-nogerenciamento-de-appliances-em-rede&catid=43%3Atrabalhos-dealunos&Itemid=18&limitstart=1.
[16] Hugo Malafaya, Luís Tomás, João Paulo Sousa, Departamento de Engenharia
Electrotécnica e de Computadores, Faculdade de Engenharia da Universidade
do Porto, “Sensorização sem fios sobre ZigBee e IEEE 802.15.4”.
[17] Jennic, “ ZigBee Device Profile (ZDP) APIs Reference Manual”, JN-RM2017 Revision 1.5 3-Aug-2007.
[18] http://www.zigbee.org/
[19] Luis Guilherme Uzeda Garcia, “REDES 802.11 (Camada de Enlace) Redes
locais sem fio que atendem ao ao padrão IEEE 802.11”. Disponível em
http://www.gta.ufrj.br/grad/01_2/802-mac/index.html.
[20] ATMEL, AVR2016: RZRAVEN Hardware User's Guide
[21] ATMEL, AVR2052: BitCloud Quick Start Guide
[22] ATMEL, AVR2050: BitCloud Developers Guide
[23] BitCloud Stack API Reference
80
[24] T Kramp, M Baentsch, T Eirich, M Oestreicher, I Romanov, A Caracas, IBM
Zurich Research LaboratoryMote Runner WP. Disponível em
http://www.zurich.ibm.com/pdf/csc/Mote_Runner_WP.pdf
[25] Alessandro Redondi, “Moterunner slides - First Steps”, 2010-2011.
[26] P. Dünser/A. Grünbaum, “IBM Mote Runner: MR-Timeline Manual”, June
17, 2011.
81
82
Bibliografia de Figuras
[F1]
http://pt.wikiversity.org/wiki/Introdu%C3%A7%C3%A3o_%C3%A0s_Redes_de_C
omputadores/Protocolos_e_servi%C3%A7os_de_rede
[F2]
ZigBee/IEEE 802.15.4 Summary, Sinem Coleri Ergen, September 10, 2004-pág.8,
Figure 3.2: Operating frequency bands.
[F3]
http://www.ifn.et.tu-dresden.de/~marandin/ZigBee/ZigBeeTutorial.html
[F4]
ZigBee/IEEE 802.15.4 Summary, Sinem Coleri Ergen, September 10, 2004-pág.23,
Figure 4.10: General MAC frame format.
[F5]
ZigBee/IEEE 802.15.4 Summary, Sinem Coleri Ergen, September 10, 2004-pág.24,
Figure 4.12: Schematic view of the data frame.
[F6]
ZigBee/IEEE 802.15.4 Summary, Sinem Coleri Ergen, September 10, 2004-pág. 24,
Figure 4.11: Schematic view of the beacon frame.
[F7]
ZigBee/IEEE 802.15.4 Summary, Sinem Coleri Ergen, September 10, 2004-pág. 24,
Figure 4.13: Schematic view of the acknowledgement frame.
[F8]
ZigBee/IEEE 802.15.4 Summary, Sinem Coleri Ergen, September 10, 2004-pág. 25,
Figure 4.14: Schematic view of the MAC command frame.
[F9]
http://paginas.fe.up.pt/~ee99207/Tecnologias/WPAN/Zigbee.html
83
[F10]
http://en.wikipedia.org/wiki/ZigBee
[F11]
http://www.gta.ufrj.br/grad/01_2/802-mac/R802_11-2.htm
[F12]
http://www.em.avnet.com/en-us/design/drc/Pages/Atmel-RZRAVEN-Evaluationand-Starter-Kit.aspx
[F13]
BitCloud - User Guide, pág. 2-1, Figure 2-1. Software Stack Architecture.
[F14]
BitCloud - User Guide, pág. 3-1, Figure 3-1. Synchronous vs. Asynchronous calls.
[F15]
BitCloud - User Guide, pág. 5-10, Figure 5-6. ASDU format.
[F16]
BitCloud - User Guide, pág. 5-11, Figure 5-7. Data transmission.
[F17]
BitCloud - User Guide, pág. 5-13, Figure 5-8. End device polling mechanism.
[F18]
http://blog.memsic.com/2009/07/beep-beep-mote-runner-has-arrived.html
[F19]
IBM Mote Runner—Executive Summary, Fig. 2: The Mote Runner tool chain from
source code to binary applications.
[F20] Dr. Pramode Verma “802.15.4” — Samer Shammaa Telecommunications
Eng. Dept., Wireless Protocols Comparison.
84
ANEXO A
Anexo A:
ZDO Functions
void ZDO_StartNetworkReq (ZDO_StartNetworkReq_t *req)
O coordenador utiliza esta função para iniciar uma rede ou no caso de um
router ou dispositivo final esta função serve para se unir à uma rede já
existente.
void ZDO_ResetNetworkReq (ZDO_ResetNetworkReq_t *req)
Reinicia a pilha de comunicação do dispositivo sem recurso de comandos
para a rede.
void ZDO_MgmtNwkUpdateNotf (ZDO_MgmtNwkUpdateNotf_t *nwkParams)
Indicação sobre atualizações de parâmetros da rede.
void ZDO_ZdpReq (ZDO_ZdpReq_t *zdpReq)
Envio de um pedido ZDP (ZigBee Divice Profile). ZDP é um conjunto de
comandos relacionados com o papel desempenhado pelo nó em questão.
void ZDO_GetLqiRssi (ZDO_GetLqiRssi_t *lqiRssi)
Pedido dos parâmetros LQI e RSSI.
void ZDO_GetParentAddr (NodeAddr_t *parentAddr)
Pedido de informações do nó pai.
void ZDO_GetChildrenAddr (ZDO_GetChildrenAddr_t *childrenAddr)
Pedido de informação do nó filho.
void ZDO_SetTxPowerReq (ZDO_SetTxPowerReq_t *req)
Ativação da alimentação de transmissão.
85
ZDO_NwkStatus_t ZDO_GetNwkStatus (void)
Recolha do estado da rede.
void ZDO_GetNeibAmount (ZDO_GetNeibAmount_t *amount)
Recolha da quantidade de routers e respetivos filhos na vizinhança.
void ZDO_GetNeibTable (ZDO_Neib_t *table)
Recolha de tabela da vizinhança.
void ZDO_SleepReq (ZDO_SleepReq_t *req)
Ordena o dispositivo entrar no modo sleep.
void ZDO_WakeUpInd (void)
Função invocada depois do dispositivo “acordar”.
void ZDO_WakeUpReq (ZDO_WakeUpReq_t *req)
Ordena à pilha de sair do modo sleep.
ZDO_Status_t ZDO_StartSyncReq (void)
Inicia os pedidos síncronos (polling ao dispositivo pai).
ZDO_Status_t ZDO_StopSyncReq (void)
Para os pedidos síncronos (polling ao dispositivo pai).
void ZDO_BindIndication (ZDO_BindInd_t *bindInd)
Indicação ZDO Binding.
void ZDO_UnbindIndication (ZDO_UnbindInd_t *unbindInd)
Indicação ZDO Unbinding.
86
ANEXO B
Anexo B:
Código principal do Recetor em C utilizando o BitCloud
// Aplicação Recetor
#include <WSNDemoApp.h>
#include <WSNVisualizer.h>
#include <taskManager.h>
#include <zdo.h>
#include <configServer.h>
#include <aps.h>
#include <mac.h>
#define APP_TIMER_STARTING_NETWORK 500 // Period of blinking during starting
network
#define TIMER_WAKEUP 50 // Wakeup period
/*********************************************************************************
Prototypes
*********************************************************************************/
// Esta função de Callback será futuramente invocada na recepção de tramas
void APS_DataIndCoord(APS_DataInd_t *indData);
// Ambas as funções invocam a função "SYS_PostTask(APL_TASK_ID);"
// Por sua vez responsável pelo gerenciamento de tarefas da pilha
void appPostSubTaskTask(void);
void appPostGlobalTask(void);
/*********************************************************************************
Global variables
*********************************************************************************/
//meu
char msg;
// Variável de Estado da aplicação
AppState_t appState
= APP_INITING_STATE;//application state
// Variável de Estado do dispositivo
DeviceState_t appDeviceState = INITIAL_DEVICE_STATE;
// As seguintes variáveis têm como campos: header, data e footer.
// As seguintes variáveis correspondem ao ASDU de uma trama enviada ou recebida
AppMessageRequest_t appMessage, dirtyAppMessage;
//request parameters for APS_DataReq primitive
APS_DataReq_t messageParams; // Pedido para transmissão de dados
HAL_AppTimer_t deviceTimer; // Timer da aplicação
uint8_t failedTransmission = 0; // Variável de indicação da falha de transmição
/*********************************************************************************
Local variables
*********************************************************************************/
// Destinado para especificar o papel do dispositivo (Coordenador/Router/EndDevice)
static DeviceType_t deviceType;
// Destinado a armazenar o pedido de arranque da rede.
87
ANEXO B
static ZDO_StartNetworkReq_t networkParams; //request params for ZDO_StartNetworkReq
//endpoint parameters
SimpleDescriptor_t simpleDescriptor; // Specify endpoint descriptor
static APS_RegisterEndpointReq_t endpointParams; // Register endpoint
// Timer indicating starting network
static HAL_AppTimer_t startingNetworkTimer;
// Destinado para armazenar o pedido de abandono da rede
static ZDO_ZdpReq_t leaveReq;
/*********************************************************************************
Local functions
*********************************************************************************/
// Função de Callback de confirmação de pedido de arranque da rede
static void ZDO_StartNetworkConf(ZDO_StartNetworkConf_t *confirmInfo);
// Visualização de tempo esgotado para iniciar a rede
static void startingNetworkTimerFired(void);
// Função de Callback de resposta de pedido de abandono da rede
static void zdpLeaveResp(ZDO_ZdpResp_t *zdpResp);
// Função de invocação da rotina correspondente ao tipo de dispositivo em questão,
// isto é, neste caso o Coordenador
static void initSubStateMachine(void);
// Função "Main"
static void appTaskHandler(AppEvent_t event, void *param);
/*********************************************************************************
Implementation
*********************************************************************************/
//Função invocada pelo SYS_RunTask();
void APL_TaskHandler(void)
{
// Rotina principal
appTaskHandler(APP_PROCESS, NULL);
}
static void appTaskHandler(AppEvent_t event, void *param)
{
bool rxOnWhenIdleFlag = true;
uint8_t sliders;
switch (appState) // Inicialmente o appState tem o valor "APP_INITING_STATE"
{
// O nó entrou na rede
case APP_IN_NETWORK_STATE:
{
switch (event)
{
case APP_PROCESS:
{
// Rotina relativa ao coordenador
appCoordinatorTaskHandler(APP_PROCESS, NULL);
break; }
case APP_NETWORK_STATE_UPDATED:
{
88
ANEXO B
ZDO_MgmtNwkUpdateNotf_t *updateParam = param;
switch (updateParam->status)
{
case ZDO_NETWORK_LOST_STATUS:
appState = APP_STOP_STATE;
break;
case ZDO_NETWORK_LEFT_STATUS:
appState = APP_STARTING_NETWORK_STATE;
failedTransmission = 0;
appPostGlobalTask();
break;
default:
break;
}
}
default:
break;
}
break;
}
case APP_INITING_STATE: //Estado inicial
{
switch (event)
{
case APP_PROCESS:
{
visualizeAppStarting();
// Inicialização da comunicação série
appStartUsartManager();
// Configuração do endpoint do dispositivo
simpleDescriptor.endpoint = WSNDEMO_ENDPOINT; //1
simpleDescriptor.AppProfileId = WSNDEMO_PROFILE_ID;
simpleDescriptor.AppDeviceId = WSNDEMO_DEVICE_ID;
simpleDescriptor.AppDeviceVersion = WSNDEMO_DEVICE_VERSION;
// Atribuição das configurações
endpointParams.simpleDescriptor = &simpleDescriptor;
// Coordinator
//-------------------------------------------------------------------#ifdef _SECURITY_
// Coordenador como centro de confiança
uint64_t tcAddr;
CS_ReadParameter(CS_APS_TRUST_CENTER_ADDRESS_ID, &tcAddr);
CS_WriteParameter(CS_UID_ID, &tcAddr);
#endif
//-------------------------------------------------------------------// Atribibuição do papel de coordenador ao nó em questão
appMessage.data.nodeType = DEVICE_TYPE_COORDINATOR;
// Configuração do Callback de recepção de tramas
endpointParams.APS_DataInd = APS_DataIndCoord;
89
ANEXO B
// Pedido de registro de endpoint
APS_RegisterEndpointReq(&endpointParams);
deviceType = appMessage.data.nodeType;
CS_WriteParameter(CS_DEVICE_TYPE_ID, &deviceType);
rxOnWhenIdleFlag = true;
CS_WriteParameter(CS_RX_ON_WHEN_IDLE_ID, &rxOnWhenIdleFlag);
// Preenchimento dos campos da frame "appMessage"
appMessage.data.messageType = APP_DATA_MESSAGE_TYPE;
appMessage.data.channelMask = CPU_TO_LE32(CS_CHANNEL_MASK);
appMessage.data.softVersion = CPU_TO_LE32(0x01010100);
appMessage.data.boardType
= MESHBEAN_SENSORS_TYPE;
appMessage.data.sensorsSize = sizeof(appMessage.data.meshbean);
startingNetworkTimer.interval = APP_TIMER_STARTING_NETWORK;
startingNetworkTimer.mode = TIMER_REPEAT_MODE;
startingNetworkTimer.callback = startingNetworkTimerFired;
//------------------------------------------------------------------------------#ifdef _SECURITY_
#ifdef _HIGH_SECURITY_
// HIGH SECURITY
//Coordenador
uint8_t linkKey[16] = LINK_KEY;
ExtAddr_t extAddr = CCPU_TO_LE64(DEVICE1_EXT_ADDR);
APS_SetLinkKey(&extAddr, linkKey);
ExtAddr_t extAddr1 = CCPU_TO_LE64(DEVICE2_EXT_ADDR);
APS_SetLinkKey(&extAddr1, linkKey);
#endif // _HIGH_SECURITY_
#endif // _SECURITY_
//------------------------------------------------------------------------------//Actualização da variável de estado
appState = APP_STARTING_NETWORK_STATE; // Estado em que arranca a rede
appPostGlobalTask(); // Passa o controlo ao TaskManager
break;
}
default:
break;
}
break;
}
//--------------------------------------------------------------------------------case APP_STARTING_NETWORK_STATE:
{
switch (event)
{
// Arranque da rede
case APP_PROCESS:
failedTransmission = 0; // Reset da variável de falha da transmissão
90
ANEXO B
networkParams.ZDO_StartNetworkConf = ZDO_StartNetworkConf; // Registo do
Callback
ZDO_StartNetworkReq(&networkParams); // Pedido para iniciar a rede
break;
// Rede inicializada
case APP_NETWORK_STARTING_DONE:
{
ZDO_StartNetworkConf_t *startInfo = param;
// Se a rede arrancou com sucesso
if (ZDO_SUCCESS_STATUS == startInfo->status)
{
// Actualiza a variável estado
appState = APP_IN_NETWORK_STATE;
failedTransmission = 0; // Variável de falha de transmissão a zero
visualizeNwkStarted(); // Actualização da informação visual
// Network parameters, such as short address, should be saved
// Armazena dados da rede no appMessage
appMessage.data.panID
= startInfo->PANId;
appMessage.data.shortAddr
= startInfo->shortAddr;
appMessage.data.parentShortAddr = startInfo->parentAddr;
appMessage.data.workingChannel = startInfo->activeChannel;
// Rotina de inicialização do dispositivo
initSubStateMachine();
}
else
// Retorna o controlo ao TaskManager
appPostGlobalTask();
break;
}
case APP_NETWORK_STATE_UPDATED:
{
ZDO_MgmtNwkUpdateNotf_t *updateParam = param;
switch (updateParam->status)
{
case ZDO_NETWORK_STARTED_STATUS:
// Network parameters, such as short address, should be saved
appMessage.data.panID
= updateParam->nwkUpdateInf.panId;
appMessage.data.shortAddr
= updateParam->nwkUpdateInf.shortAddr;
appMessage.data.parentShortAddr = updateParam->nwkUpdateInf.parentShortAddr;
appMessage.data.workingChannel = updateParam->nwkUpdateInf.currentChannel;
appState = APP_IN_NETWORK_STATE;
failedTransmission = 0;
initSubStateMachine();
break;
default:
break;
}
}
default: break;
91
ANEXO B
}
break;
}
//--------------------------------------------------------------------------------case APP_LEAVING_NETWORK_STATE:
{
ZDO_MgmtLeaveReq_t *zdpLeaveReq = &leaveReq.req.reqPayload.mgmtLeaveReq;
switch(event)
{
case APP_PROCESS:
visualizeNwkLeaving();
leaveReq.ZDO_ZdpResp = zdpLeaveResp;
leaveReq.reqCluster = MGMT_LEAVE_CLID;
leaveReq.dstAddrMode = EXT_ADDR_MODE;
leaveReq.dstExtAddr = 0;
zdpLeaveReq->deviceAddr = 0;
zdpLeaveReq->rejoin = 0;
zdpLeaveReq->removeChildren = 1;
zdpLeaveReq->reserved = 0;
ZDO_ZdpReq(&leaveReq);
break;
case APP_LEAVE_DONE:
if (ZDO_SUCCESS_STATUS == ((ZDO_ZdpResp_t *)param)->respPayload.status)
appState = APP_STOP_STATE;
appPostGlobalTask();
break;
case APP_NETWORK_STATE_UPDATED:
{
ZDO_MgmtNwkUpdateNotf_t *updateParam = param;
switch (updateParam->status)
{
case ZDO_NETWORK_LOST_STATUS:
appState = APP_STOP_STATE;
break;
case ZDO_NETWORK_LEFT_STATUS:
appState = APP_STARTING_NETWORK_STATE;
appPostGlobalTask();
break;
default:
break;
}
break;
}
default:
break;
}
break;
}
case APP_STOP_STATE:
{
switch(event)
{
92
ANEXO B
case APP_NETWORK_STATE_UPDATED:
{
ZDO_MgmtNwkUpdateNotf_t *updateParam = param;
switch (updateParam->status)
{
case ZDO_NETWORK_STARTED_STATUS:
appState = APP_IN_NETWORK_STATE;
appMessage.data.shortAddr
= updateParam->nwkUpdateInf.shortAddr;
appMessage.data.panID
= updateParam->nwkUpdateInf.panId;
appMessage.data.parentShortAddr = updateParam->nwkUpdateInf.parentShortAddr;
appMessage.data.workingChannel = updateParam->nwkUpdateInf.currentChannel;
appPostGlobalTask();
break;
case ZDO_NETWORK_LEFT_STATUS:
appState = APP_STARTING_NETWORK_STATE;
appPostGlobalTask();
break;
default:
break;
}
}
default:
break;
}
break;
}
default:
break;
}
}
// The response means that the command has been received successfully but not precessed yet
static void zdpLeaveResp(ZDO_ZdpResp_t *zdpResp)
{
appTaskHandler(APP_LEAVE_DONE, zdpResp);
}
// Callback de confirmação do arranque da rede
static void ZDO_StartNetworkConf(ZDO_StartNetworkConf_t *confirmInfo)
{
// Retorna a função principal com novos parâmetros
appTaskHandler(APP_NETWORK_STARTING_DONE, confirmInfo);
}
void ZDO_MgmtNwkUpdateNotf(ZDO_MgmtNwkUpdateNotf_t *nwkParams)
{
if (ZDO_NO_KEY_PAIR_DESCRIPTOR_STATUS == nwkParams->status)
{
#ifdef _HIGH_SECURITY_
ExtAddr_t addr
= nwkParams->childInfo.extAddr;
uint8_t linkKey[16] = LINK_KEY;
APS_SetLinkKey(&addr, linkKey);
#endif
}
else
93
ANEXO B
appTaskHandler(APP_NETWORK_STATE_UPDATED, nwkParams);
}
void ZDO_WakeUpInd(void)
{
}
static void startingNetworkTimerFired(void)
{
visualizeNwkStarting();
}
void initSubStateMachine(void)
{
appInitDeviceCoordinator();
}
void appReadLqiRssi(void)
{
ZDO_GetLqiRssi_t lqiRssi;
lqiRssi.nodeAddr = appMessage.data.parentShortAddr;
ZDO_GetLqiRssi(&lqiRssi);
appMessage.data.lqi = lqiRssi.lqi;
appMessage.data.rssi = lqiRssi.rssi;
}
void appPostGlobalTask(void)
{
SYS_PostTask(APL_TASK_ID);
}
void appPostSubTaskTask(void)
{
SYS_PostTask(APL_TASK_ID);
}
void appLeaveNetwork(void)
{
if (APP_IN_NETWORK_STATE == appState)
{
appState = APP_LEAVING_NETWORK_STATE;
appPostGlobalTask();
}
}
#ifdef _BINDING_
void ZDO_BindIndication(ZDO_BindInd_t *bindInd)
{
(void)bindInd;
}
void ZDO_UnbindIndication(ZDO_UnbindInd_t *unbindInd)
{
(void)unbindInd;
}
#endif
int main(void)
{
94
ANEXO B
SYS_SysInit();
for(;;)
{
SYS_RunTask();
}
}
95
96
ANEXO C
Anexo C:
Código Coordenador do Recetor em C utilizando o
BitCloud
// Este ficheiro é relativo ao coordenador
#ifdef _COORDINATOR_
#include <WSNDemoApp.h>
#include <WSNVisualizer.h>
extern AppMessageRequest_t appMessage;
extern HAL_AppTimer_t deviceTimer;
extern bool subTaskRequested;
static void deviceTimerFired(void);
static void appSensorsesGot(void);
void appInitDeviceCoordinator(void);
//--------------------------------------------------------------//MEU
extern msg;
static void APS_DataConf(APS_DataConf_t *confInfo);
extern APS_DataReq_t messageParams;
// Timer
static HAL_AppTimer_t meuTimer;
// Meu Timer handler.
static void meuTimerFired(void);
//--------------------------------------------------------------void appCoordinatorTaskHandler(AppEvent_t event, void *param)
{
param = param; // warning prevention
switch (appDeviceState)
{
//------------------------------------------------------------------------//MEU
case WAITING_DEVICE_STATE:
switch (event)
{
case APP_SENDING_DONE:
if (APS_SUCCESS_STATUS == ((APS_DataConf_t *)param)->status)
{
failedTransmission = 0;
}
else
{
if (APP_THRESHOLD_FAILED_TRANSMISSION < ++failedTransmission)
{
appDeviceState = INITIAL_DEVICE_STATE;
failedTransmission = 0;
appLeaveNetwork();
return;
}
else
97
ANEXO C
appDeviceState = SENDING_DEVICE_STATE;
}
appPostSubTaskTask();
break;
case APP_READING_DONE:
appDeviceState = SENDING_DEVICE_STATE;
appPostSubTaskTask();
break;
default:
break;
}
break;
//------------------------------------------------------------------------case LIGAR_LUZ:
{
MyLEDon();
appSendLcdMsg(" ON ");
appSendLcdCmd(LCD_CMD_LED_ON);
HAL_StartAppTimer(&meuTimer); // Start timer
appDeviceState = INITIAL_DEVICE_STATE;
appPostSubTaskTask();
}
//-----------------------------------------------------------// Estado do Dispositivo depois de entrar na rede
case INITIAL_DEVICE_STATE:
switch (event)
{
case APP_PROCESS:
//Meu Timer
// Configure timer
meuTimer.interval = 15000; // Timer interval
meuTimer.mode = TIMER_ONE_SHOT_MODE; // Repeating mode
(TIMER_ONE_SHOT_MODE)
meuTimer.callback = meuTimerFired; // Callback function for timer fire event
//--------------------------------------------------------------HAL_StopAppTimer(&deviceTimer); // Para o Timer do sistema
deviceTimer.interval = APP_TIMER_SENDING_PERIOD;
deviceTimer.mode = TIMER_ONE_SHOT_MODE;
deviceTimer.callback = deviceTimerFired;
// Devolve o controlo ao TAskManager
appPostSubTaskTask();
break;
default:
break;
}
break;
default:
break;
}
}
void appInitDeviceCoordinator(void)
{
appDeviceState = INITIAL_DEVICE_STATE;
appPostSubTaskTask();
98
ANEXO C
}
static void appSensorsesGot(void)
{
appCoordinatorTaskHandler(APP_READING_DONE, NULL);
}
static void deviceTimerFired(void)
{
appCoordinatorTaskHandler(APP_TIMER_FIRED, NULL);
}
//------------------------------------------------------------------------------//Meu timer callback
static void meuTimerFired()
{
MyLEDoff();
appLeaveNetwork();
}
void APS_DataIndCoord(APS_DataInd_t *indData)
{
msg = *indData->asdu;
if (msg =='A' || msg != 'B')
{
appDeviceState = LIGAR_LUZ; //SENDING_DEVICE_STATE;
}
else
{
if (msg =='B')
appSendLcdMsg(" OFF ");
}
}
#endif
99
100
ANEXO D
Anexo D:
Código principal do Emissor em C utilizando o BitCloud
// Aplicação Emissor
#include <WSNDemoApp.h>
#include <WSNVisualizer.h>
#include <taskManager.h>
#include <zdo.h>
#include <configServer.h>
#include <aps.h>
#include <mac.h>
#define APP_TIMER_STARTING_NETWORK 500 // Period of blinking during starting network
#define TIMER_WAKEUP 50 // Wakeup period
/***********************************************************************************
Types
***********************************************************************************/
typedef enum
{
START_BLINKING,
STOP_BLINKING
} BlinkingAction_t;
/***********************************************************************************
Prototypes
***********************************************************************************/
// Esta função de Callback será futuramente invocada na recepção de tramas
void APS_DataIndDevice(APS_DataInd_t *indData);
// Ambas as funções invocam a função "SYS_PostTask(APL_TASK_ID);"
// Por sua vez responsável pelo gerenciamento de tarefas da pilha
void appPostSubTaskTask(void);
void appPostGlobalTask(void);
/***********************************************************************************
Global variables
***********************************************************************************/
// Variável de Estado da aplicação
AppState_t appState
= APP_INITING_STATE;//application state
// Variável de Estado do dispositivo
DeviceState_t appDeviceState = INITIAL_DEVICE_STATE;
// As seguintes variáveis correspondem ao ASDU de uma trama enviada ou recebida
AppMessageRequest_t appMessage, dirtyAppMessage;
APS_DataReq_t messageParams; // Pedido para transmissão de dados
HAL_AppTimer_t deviceTimer; // Timer da aplicação
uint8_t failedTransmission = 0; // Variável de indicação da falha de transmição
/***********************************************************************************
Local variables
***********************************************************************************/
// Destinado para especificar o papel do dispositivo (EndDevice)
static DeviceType_t deviceType;
// Destinado a armazenar o pedido de arranque da rede.
101
ANEXO D
static ZDO_StartNetworkReq_t networkParams; //request params for ZDO_StartNetworkReq
//endpoint parameters
SimpleDescriptor_t simpleDescriptor; // Specify endpoint descriptor
static APS_RegisterEndpointReq_t endpointParams; // Register endpoint
// Timer indicating starting network
static HAL_AppTimer_t startingNetworkTimer;
// Destinado para armazenar o pedido de abandono da rede
static ZDO_ZdpReq_t leaveReq;
/***********************************************************************************
Local functions
***********************************************************************************/
// Função de Callback de confirmação de pedido de arranque da rede
static void ZDO_StartNetworkConf(ZDO_StartNetworkConf_t *confirmInfo);
// Visualização de tempo esgotado para iniciar a rede
static void startingNetworkTimerFired(void);
// Função de Callback de resposta de pedido de abandono da rede
static void zdpLeaveResp(ZDO_ZdpResp_t *zdpResp);
// Função de invocação da rotina correspondente ao tipo de dispositivo em questão,
// isto é endDevice
static void initSubStateMachine(void);
// Função "Main"
static void appTaskHandler(AppEvent_t event, void *param);
// Função responsável pela intermitência de Led
static void manageBlinkingDuringRejoin(BlinkingAction_t action);
/***********************************************************************************
Implementation
***********************************************************************************/
//Função invocada pelo SYS_RunTask();
void APL_TaskHandler(void)
{
// Rotina principal
appTaskHandler(APP_PROCESS, NULL);
}
static void appTaskHandler(AppEvent_t event, void *param)
{
bool rxOnWhenIdleFlag = true;
uint8_t sliders;
switch (appState) // Inicialmente o appState tem o valor "APP_INITING_STATE"
{
//--------------------------------------------------------------------------------// o nó está na rede
case APP_IN_NETWORK_STATE:
{
switch (event)
{
case APP_PROCESS:
{
// Rotina relativa ao EndDevice
appEndDeviceTaskHandler(APP_PROCESS, NULL);
break;
}
case APP_NETWORK_STATE_UPDATED:
102
ANEXO D
{
ZDO_MgmtNwkUpdateNotf_t *updateParam = param;
switch (updateParam->status)
{
case ZDO_NETWORK_LOST_STATUS:
appState = APP_STOP_STATE;
break;
case ZDO_NETWORK_LEFT_STATUS:
appState = APP_STARTING_NETWORK_STATE;
failedTransmission = 0;
appPostGlobalTask();
break;
case ZDO_NWK_UPDATE_STATUS:
case ZDO_NETWORK_STARTED_STATUS:
// Update parameters being sent to coordinator
appMessage.data.shortAddr
= updateParam->nwkUpdateInf.shortAddr;
appMessage.data.panID
= updateParam->nwkUpdateInf.panId;
appMessage.data.parentShortAddr = updateParam->nwkUpdateInf.parentShortAddr;
appMessage.data.workingChannel = updateParam->nwkUpdateInf.currentChannel;
break;
default:
break;
}
}
default:
break;
}
break;
}
case APP_INITING_STATE: // Estado inicial
{
switch (event)
{
case APP_PROCESS:
{
// Configuração do endpoint do dispositivo
simpleDescriptor.endpoint = WSNDEMO_ENDPOINT; //1
simpleDescriptor.AppProfileId = WSNDEMO_PROFILE_ID;
simpleDescriptor.AppDeviceId = WSNDEMO_DEVICE_ID;
simpleDescriptor.AppDeviceVersion = WSNDEMO_DEVICE_VERSION;
// Atribuição das configurações
endpointParams.simpleDescriptor = &simpleDescriptor;
// Setting device type
sliders = appReadSliders();
#ifdef _SECURITY_
// Coordenador como centro de confiança
uint64_t tcAddr = CCPU_TO_LE64(COORDINATOR_EXT_ADDR);
CS_WriteParameter(CS_APS_TRUST_CENTER_ADDRESS_ID, &tcAddr);
#endif
appMessage.data.nodeType = DEVICE_TYPE_END_DEVICE;
endpointParams.APS_DataInd = APS_DataIndDevice;
//-----------------------------------------------------------------------// For not coordinator CS_UID is set to equal UID chip by ZDO before
{ // To remove unalignment access warning for ARM.
ExtAddr_t extAddr;
CS_ReadParameter(CS_UID_ID, &extAddr); // Leitura do endereço extendido
103
ANEXO D
appMessage.data.extAddr = extAddr;
// Armazenamento do endereço extendido
}
//-----------------------------------------------------------------------// Pedido de registro de endpoint
APS_RegisterEndpointReq(&endpointParams);
deviceType = appMessage.data.nodeType;
CS_WriteParameter(CS_DEVICE_TYPE_ID, &deviceType);
//-----------------------------------------------------------------------rxOnWhenIdleFlag = false;
CS_WriteParameter(CS_RX_ON_WHEN_IDLE_ID, &rxOnWhenIdleFlag);
// Preenchimento dos campos do appMessage
appMessage.data.messageType = APP_DATA_MESSAGE_TYPE;
appMessage.data.channelMask = CPU_TO_LE32(CS_CHANNEL_MASK);
appMessage.data.softVersion = CPU_TO_LE32(0x01010100);
appMessage.data.boardType
= MESHBEAN_SENSORS_TYPE;
appMessage.data.sensorsSize = sizeof(appMessage.data.meshbean);
startingNetworkTimer.interval = APP_TIMER_STARTING_NETWORK;
startingNetworkTimer.mode = TIMER_REPEAT_MODE;
startingNetworkTimer.callback = startingNetworkTimerFired;
//------------------------------------------------------------------------------#ifdef _SECURITY_
#ifdef _HIGH_SECURITY_
uint8_t linkKey[16] = LINK_KEY;
ExtAddr_t extAddr = CCPU_TO_LE64(COORDINATOR_EXT_ADDR);
APS_SetLinkKey(&extAddr, linkKey);
#endif // _HIGH_SECURITY_
#endif // _SECURITY_
//------------------------------------------------------------------------------//Actualização da variável de estado
appState = APP_STARTING_NETWORK_STATE; // Estado em que arranca a rede
appPostGlobalTask(); // Passa o controlo ao TaskManager
break;
}
default:
break;
}
break;
}
case APP_STARTING_NETWORK_STATE:
{
switch (event)
{
// Arranque da rede
case APP_PROCESS:
manageBlinkingDuringRejoin(START_BLINKING);
visualizeNwkStarting(); // Amostragem da informação que a rede está a inicializar
failedTransmission = 0; // Reset da variável de falha da transmissão
// Start network
networkParams.ZDO_StartNetworkConf = ZDO_StartNetworkConf; // Registo do
Callback
ZDO_StartNetworkReq(&networkParams); // Pedido para iniciar a rede
break;
104
ANEXO D
// Rede inicializada
case APP_NETWORK_STARTING_DONE:
{
ZDO_StartNetworkConf_t *startInfo = param;
manageBlinkingDuringRejoin(STOP_BLINKING);
// Se a rede arrancou com sucesso
if (ZDO_SUCCESS_STATUS == startInfo->status)
{
// Actualiza a variável estado
appState = APP_IN_NETWORK_STATE;
failedTransmission = 0; // Variável de falha de transmissão a zero
// Network parameters, such as short address, should be saved
// Armazena dados da rede no appMessage
appMessage.data.panID
= startInfo->PANId;
appMessage.data.shortAddr
= startInfo->shortAddr;
appMessage.data.parentShortAddr = startInfo->parentAddr;
appMessage.data.workingChannel = startInfo->activeChannel;
// Rotina de inicialização do dispositivo
initSubStateMachine();
}
else
// Retorna o controlo ao TaskManager
appPostGlobalTask();
break;
}
case APP_NETWORK_STATE_UPDATED:
{
ZDO_MgmtNwkUpdateNotf_t *updateParam = param;
switch (updateParam->status)
{
case ZDO_NETWORK_STARTED_STATUS:
// Network parameters, such as short address, should be saved
appMessage.data.panID
= updateParam->nwkUpdateInf.panId;
appMessage.data.shortAddr
= updateParam->nwkUpdateInf.shortAddr;
appMessage.data.parentShortAddr = updateParam->nwkUpdateInf.parentShortAddr;
appMessage.data.workingChannel = updateParam->nwkUpdateInf.currentChannel;
manageBlinkingDuringRejoin(STOP_BLINKING);
appState = APP_IN_NETWORK_STATE;
failedTransmission = 0;
visualizeNwkStarted();
initSubStateMachine();
break;
default:
break;
}
}
default: break;
}
break;
}
case APP_LEAVING_NETWORK_STATE:
{
ZDO_MgmtLeaveReq_t *zdpLeaveReq = &leaveReq.req.reqPayload.mgmtLeaveReq;
switch(event)
{
case APP_PROCESS:
visualizeNwkLeaving();
leaveReq.ZDO_ZdpResp = zdpLeaveResp;
105
ANEXO D
leaveReq.reqCluster = MGMT_LEAVE_CLID;
leaveReq.dstAddrMode = EXT_ADDR_MODE;
leaveReq.dstExtAddr = 0;
zdpLeaveReq->deviceAddr = 0;
zdpLeaveReq->rejoin = 0;
zdpLeaveReq->removeChildren = 1;
zdpLeaveReq->reserved = 0;
ZDO_ZdpReq(&leaveReq);
break;
case APP_LEAVE_DONE:
if (ZDO_SUCCESS_STATUS == ((ZDO_ZdpResp_t *)param)->respPayload.status)
appState = APP_STOP_STATE;
appPostGlobalTask();
break;
case APP_NETWORK_STATE_UPDATED:
{
ZDO_MgmtNwkUpdateNotf_t *updateParam = param;
switch (updateParam->status)
{
case ZDO_NETWORK_LOST_STATUS:
appState = APP_STOP_STATE;
break;
case ZDO_NETWORK_LEFT_STATUS:
appState = APP_STARTING_NETWORK_STATE;
appPostGlobalTask();
break;
default:
break;
}
break;
}
default:
break;
}
break;
}
case APP_STOP_STATE:
{
switch(event)
{
case APP_NETWORK_STATE_UPDATED:
{
ZDO_MgmtNwkUpdateNotf_t *updateParam = param;
switch (updateParam->status)
{
case ZDO_NETWORK_STARTED_STATUS:
appState = APP_IN_NETWORK_STATE;
appMessage.data.shortAddr
= updateParam->nwkUpdateInf.shortAddr;
appMessage.data.panID
= updateParam->nwkUpdateInf.panId;
appMessage.data.parentShortAddr = updateParam->nwkUpdateInf.parentShortAddr;
appMessage.data.workingChannel = updateParam->nwkUpdateInf.currentChannel;
appPostGlobalTask();
break;
case ZDO_NETWORK_LEFT_STATUS:
appState = APP_STARTING_NETWORK_STATE;
appPostGlobalTask();
break;
default:
break;
106
ANEXO D
}
}
default:
break;
}
break;
}
default:
break;
}
}
// The response means that the command has been received successfully but not precessed yet
static void zdpLeaveResp(ZDO_ZdpResp_t *zdpResp)
{
appTaskHandler(APP_LEAVE_DONE, zdpResp);
}
// Callback de confirmação do arranque da rede
static void ZDO_StartNetworkConf(ZDO_StartNetworkConf_t *confirmInfo)
{
// Retorna a função principal com novos parâmetros
appTaskHandler(APP_NETWORK_STARTING_DONE, confirmInfo);
}
void ZDO_MgmtNwkUpdateNotf(ZDO_MgmtNwkUpdateNotf_t *nwkParams)
{
if (ZDO_NO_KEY_PAIR_DESCRIPTOR_STATUS == nwkParams->status)
{
#ifdef _HIGH_SECURITY_
ExtAddr_t addr
= nwkParams->childInfo.extAddr;
uint8_t linkKey[16] = LINK_KEY;
APS_SetLinkKey(&addr, linkKey);
#endif
}
else
appTaskHandler(APP_NETWORK_STATE_UPDATED, nwkParams);
}
void ZDO_WakeUpInd(void)
{
#ifdef _ENDDEVICE_
if (APP_IN_NETWORK_STATE == appState)
{
appEndDeviceTaskHandler(APP_WOKEUP, NULL);
}
#endif
}
static void startingNetworkTimerFired(void)
{
visualizeNwkStarting();
}
void initSubStateMachine(void)
{
#ifdef _COORDINATOR_
if (deviceType == DEVICE_TYPE_COORDINATOR)
appInitDeviceCoordinator();
#endif
#ifdef _ROUTER_
if (deviceType == DEVICE_TYPE_ROUTER)
appInitDeviceRouter();
#endif
#ifdef _ENDDEVICE_
107
ANEXO D
if (deviceType == DEVICE_TYPE_END_DEVICE)
appInitDeviceEndDevice();
#endif
}
void appReadLqiRssi(void)
{
ZDO_GetLqiRssi_t lqiRssi;
lqiRssi.nodeAddr = appMessage.data.parentShortAddr;
ZDO_GetLqiRssi(&lqiRssi);
appMessage.data.lqi = lqiRssi.lqi;
appMessage.data.rssi = lqiRssi.rssi;
}
static void manageBlinkingDuringRejoin(BlinkingAction_t action)
{
static bool run = false;
if (START_BLINKING == action)
{
if (!run)
{
HAL_StartAppTimer(&startingNetworkTimer);
run = true;
}
}
if (STOP_BLINKING == action)
{
run = false;
HAL_StopAppTimer(&startingNetworkTimer);
}
}
void appPostGlobalTask(void)
{
SYS_PostTask(APL_TASK_ID);
}
void appPostSubTaskTask(void)
{
SYS_PostTask(APL_TASK_ID);
}
void appLeaveNetwork(void)
{
if (APP_IN_NETWORK_STATE == appState)
{
appState = APP_LEAVING_NETWORK_STATE;
appPostGlobalTask();
}
}
#ifdef _BINDING_
void ZDO_BindIndication(ZDO_BindInd_t *bindInd)
{
(void)bindInd;
}
void ZDO_UnbindIndication(ZDO_UnbindInd_t *unbindInd)
{
(void)unbindInd;
}
#endif //_BINDING_
int main(void)
108
ANEXO D
{
SYS_SysInit();
for(;;)
{
SYS_RunTask();
}
109
110
ANEXO E
Anexo E:
Código EndDevice do Emissor em C utilizando o
BitCloud
#ifdef _ENDDEVICE_
#include <WSNDemoApp.h>
#include <WSNVisualizer.h>
//request parameters for APS_DataReq primitive
extern APS_DataReq_t messageParams;
extern AppMessageRequest_t appMessage;
extern AppState_t appState;
extern bool subTaskRequested;
extern void appLeaveNetwork(void);
static ZDO_SleepReq_t sleepReq;
static void APS_DataConf(APS_DataConf_t *confInfo);
static void ZDO_SleepConf(ZDO_SleepConf_t *conf);
static void appSensorsesGot(void);
void APS_DataIndDevice(APS_DataInd_t *indData);
void appInitDeviceEndDevice(void);
void appEndDeviceTaskHandler(AppEvent_t event, void *param)
{
switch (appDeviceState)
{
case WAITING_DEVICE_STATE:
switch (event)
{
case APP_SENDING_DONE:
if (APS_SUCCESS_STATUS == ((APS_DataConf_t *)param)->status)
{
visualizeAirTxFInished();
failedTransmission = 0;
//Meu
//appDeviceState = SLEEPPING_DEVICE_STATE;
//appDeviceState = READING_SENSORS_STATE;
appDeviceState = SENDING_DEVICE_STATE;
//-----------------------------------------}
else
{
if (APP_THRESHOLD_FAILED_TRANSMISSION < ++failedTransmission)
{
appDeviceState = INITIAL_DEVICE_STATE;
failedTransmission = 0;
appLeaveNetwork();
return;
}
else
appDeviceState = SENDING_DEVICE_STATE;
}
appPostSubTaskTask();
break;
111
ANEXO E
case APP_SLEEP_DONE:
if (ZDO_SUCCESS_STATUS == ((ZDO_SleepConf_t *)param)->status)
{
appDeviceState = SLEEPPING_DEVICE_STATE;
visualizeSleep();
}
else
{
appDeviceState = SLEEPPING_DEVICE_STATE;
appPostSubTaskTask();
}
break;
case APP_READING_DONE:
appStopSensorManager();
appDeviceState = SENDING_DEVICE_STATE;
appPostSubTaskTask();
break;
default:
break;
}
break;
case READING_SENSORS_STATE:
switch (event)
{
case APP_PROCESS:
appStartSensorManager();
appReadLqiRssi();
appDeviceState = WAITING_DEVICE_STATE;
appGetSensorData(appSensorsesGot);
uint8_t teste = PINA;
if (teste!=0)
appSendLcdCmd(LCD_CMD_SYMB_BELL_ON);
break;
default:
break;
}
break;
case SENDING_DEVICE_STATE:
switch (event)
{
case APP_PROCESS:
visualizeAirTxStarted();
//meu
if((PINA & 0x01) == 0x00)
{
appSendLcdCmd(LCD_CMD_LED_OFF);
messageParams.asdu = "B";
}
else
if((PINA & 0x01) == 0x01)
{
112
ANEXO E
appSendLcdCmd(LCD_CMD_LED_ON);
messageParams.asdu = "A";
}
APS_DataReq(&messageParams);
appDeviceState = WAITING_DEVICE_STATE;
appPostSubTaskTask();
break;
default:
break;
}
break;
case WAITING_VISUALIZER_STATE:
switch (event)
{
case APP_PROCESS:
if (!isVisualizerReadyToSleep())// Wait for Visualizer ready
{
appPostSubTaskTask();
}
else
{
appDeviceState = WAITING_DEVICE_STATE;
ZDO_SleepReq(&sleepReq);
}
break;
default:
break;
}
break;
//-----------------------------------------------------------//Estado do Dispositivo depois de entrar na rede
case INITIAL_DEVICE_STATE:
switch (event)
{
case APP_PROCESS:
//1º
sleepReq.ZDO_SleepConf = ZDO_SleepConf;
// Prefilling request parameters
messageParams.profileId
= simpleDescriptor.AppProfileId;
messageParams.dstAddrMode
= APS_SHORT_ADDRESS;
messageParams.dstAddress.shortAddress = CPU_TO_LE16(0);
messageParams.dstEndpoint
= 1;
messageParams.clusterId
= CPU_TO_LE16(1);
messageParams.srcEndpoint
= simpleDescriptor.endpoint;
messageParams.asduLength
= sizeof(appMessage.data);
messageParams.txOptions.acknowledgedTransmission = 1;
#ifdef _APS_FRAGMENTATION_
messageParams.txOptions.fragmentationPermitted = 1;
#endif // _APS_FRAGMENTATION_
113
ANEXO E
#ifdef _HIGH_SECURITY_
messageParams.txOptions.securityEnabledTransmission = 1;
#endif
messageParams.radius
= 0x0;
messageParams.APS_DataConf
= APS_DataConf;
appDeviceState = READING_SENSORS_STATE;
appPostSubTaskTask();
break;
default:
break;
}
break;
case REINITIAL_DEVICE_STATE:
switch (event)
{
case APP_PROCESS:
break;
default:
appDeviceState = INITIAL_DEVICE_STATE;
appPostSubTaskTask();
break;
}
default:
break;
}
}
// appEndDeviceTaskHandler must be called from main state machine after this function
void appInitDeviceEndDevice(void)
{
if (WAITING_DEVICE_STATE == appDeviceState)
appDeviceState = REINITIAL_DEVICE_STATE;
else
{
appDeviceState = INITIAL_DEVICE_STATE;
appPostSubTaskTask();
}
}
static void appSensorsesGot(void)
{
appEndDeviceTaskHandler(APP_READING_DONE, NULL);
}
void ZDO_SleepConf(ZDO_SleepConf_t *conf)
{
appEndDeviceTaskHandler(APP_SLEEP_DONE, conf);
}
static void APS_DataConf(APS_DataConf_t *confInfo)
{
appEndDeviceTaskHandler(APP_SENDING_DONE, confInfo);
}
void APS_DataIndDevice(APS_DataInd_t *indData)
{
indData = indData;
}
#endif
114
ANEXO F
Anexo F:
Código do Recetor em Java utilizando o Mote Runner
package appfinalled2;
import com.ibm.saguaro.system.*;
import com.ibm.avrraven.*;
public class AppFinalLed2
{
// Declaração de variáveis
private static byte[] xmit;
private static Timer tsend;
private static long
tempo;
static Radio radio = new Radio();
// Instância da classe GPIO
static GPIO gpio = new GPIO();
static
{
// Criar rádio
radio = new Radio();
// Habilitar radio
radio.open(Radio.DID, null, 0, 0);
// Configuração dos parâmetros de rede
radio.setPanId(0x22, true);
byte[] myAddrBytes = new byte[8];
Mote.getParam(Mote.EUI64,myAddrBytes,0);
radio.setShortAddr(Util.get16le(myAddrBytes, 0));
// Configuração da trama
xmit = new byte[7];
xmit[0] = Radio.FCF_BEACON;
xmit[1] = Radio.FCA_SRC_SADDR;
Util.set16le(xmit, 3, 0x22);
Util.set16le(xmit, 5, 0x1234);
// Colocar radio em modo “receber” no canal 0
// Cria um "delegate" no método chamado "radio.setRxHandler"
// "delegates" são basicamente apontadores para outros métodos
radio.setRxHandler(
// "delegate DevCallback"
new DevCallback(null) {
public int invoke(int flags,byte[] data, int len,int info,long
time) {
// Acção a ser tomada quando uma trama é recebida.
// É invocado o método "onRxPDU (int flags, byte[] data, int
// len, int info, long time)"
// definido mais abaixo.
return AppFinalLed2.onRxPDU(flags, data, len, info, time);
}
115
ANEXO F
}
);
radio.startRx(Device.ASAP, 0, Time.toTickSpan(Time.MILLISECS,80));
// Array de Bytes
byte gp[] = csr.allocaByteArray((byte)1);
// Inicialização do Byte
gp[0] = AVRRAVEN.PIN_PA0;
// Habilita pinos GPIO
gpio.open(AVRRAVEN.DID_GPIO,gp,0,1);
// Configuração do timer
tsend = new Timer();
// Cria um "delegate" no método chamado "tsend.setCallback"
// Alarme do timer
tsend.setCallback(
// "delegate TimerEvent"
new TimerEvent(null) {
public void invoke(byte param, long time) {
// Acção a ser tomada quando o alarme do timer disparar
// É invocado o método "periodicSend(byte param, long time)"
// definido mais abaixo
AppFinalLed2.turnOFF(param, time);
}
}
);
// Conversão do tempo para ticks
tempo = Time.toTickSpan(Time.SECONDS,15);
}
// Fim do static
// Função de Callback que é responsável de gerir a receção das tramas
private static int onRxPDU (int flags, byte[] data, int len, int info,
long time)
{
if (data == null)
{
// Re-habilita a receção das frames
radio.startRx(Device.ASAP, 0, Time.toTickSpan(Time.MILLISECS,500));
return 0;
}
if (data[2] == 1)
{
// Liga o LED do display da RAVEN
LED.setState((byte)0,(byte)1);
// Liga a fonte luminosa exterior à RAVEN
gpio.setPin(AVRRAVEN.PIN_PA0,(byte)1);
}
if (data[2] == 0)
{
116
ANEXO F
// Inicialização do timer
tsend.setAlarmBySpan(tempo);
}
return 0;
}
// Função de Callback invocada no final do timer
public static void turnOFF(byte param, long time)
{
// Desliga o LED do Display da RAVEN
LED.setState((byte)0,(byte)0);
// Desliga a fonte luminosa exterior à RAVEN
gpio.setPin(AVRRAVEN.PIN_PA0,(byte)0);
117
118
ANEXO G
Anexo G:
Código do emissor em Java utilizando o Mote Runner
package appfinalsensor;
import com.ibm.saguaro.system.*;
import com.ibm.avrraven.*;
public class AppFinalSensor
{
// Declaração de Variáveis
private static byte[] xmit;
private static Timer tsend;
static Radio radio = new Radio();
// Instância da classe GPIO
static GPIO gpio = new GPIO();
static
{
// Cria um "delegate" no método chamado "gpio.setReadHandler"
// "delegates" são basicamente apontadores para outros métodos
gpio.setReadHandler(
// delegate "DevCallback"
New DevCallback(null)
{
public int invoke (int flags, byte[] data, int len, int info,
long time)
{
return AppFinalSensor.onRead(flags, data, len, info, time);
}
}
);
// Array de Bytes
byte[] gp = csr.allocaByteArray((byte)1);
// Inicialização do Byte
gp[0] = AVRRAVEN.PIN_PA0;
// Habilita pino GPIO
gpio.open(AVRRAVEN.DID_GPIO,gp,0,1);
// Criar rádio
radio = new Radio();
// Habilitar radio
radio.open(Radio.DID, null, 0, 0);
// Configuração dos parâmetros de rede
radio.setPanId(0x22, true);
byte[] myAddrBytes = new byte[8];
Mote.getParam(Mote.EUI64,myAddrBytes,0);
radio.setShortAddr(Util.get16le(myAddrBytes, 0));
119
ANEXO G
// Configuração da trama
xmit = new byte[7];
xmit[0] = Radio.FCF_BEACON;
xmit[1] = Radio.FCA_SRC_SADDR;
Util.set16le(xmit, 3, 0x22);
Util.set16le(xmit, 5, 0x1234);
// Configuração do timer
tsend = new Timer();
// Cria um "delegate" no método chamado "tsend.setCallback"
// Alarme do timer
tsend.setCallback(
//"delegate TimerEvent"
new TimerEvent(null) {
public void invoke(byte param, long time) {
// Acção a ser tomada quando o alarme do timer disparar
// É invocado o método "periodicSend(byte param, long time)"
// definido mais abaixo
AppFinalSensor.periodicSend(param, time);
}
}
);
// Leitura do Sensor de presença
gpio.read(Device.TIMED,0,Time.currentTicks() +
Time.toTickSpan(Time.MILLISECS,80));
}
// Fim do static
// Função de Callback responsável pela leitura do sensor
public static int onRead (int flags, byte[] data, int len, int info,
long time)
{
if(data[AVRRAVEN.PIN_PA0] != 0)
{
// Acende LED do display da RAVEN
LED.setState((byte)0, (byte)1);
// Armazena o valor ‘1’ na trama a ser enviada
xmit[2] = 1;
}
else
{
// Apaga o LED do Display da RAVEN
LED.setState((byte)0, (byte)0);
// Armazena o valor ‘0’ na trama a ser enviada
xmit[2] = 0;
}
// Inicialização e arranque do timer
tsend.setAlarmBySpan(Time.toTickSpan(Time.MILLISECS, 800));
return 0;
}
// Called on a timer alarm
public static void periodicSend(byte param, long time)
{
// Envio da trama
120
ANEXO G
radio.transmit(Device.ASAP|Radio.TXMODE_CCA, xmit, 0, 7, 0);
// Volta a ler o sensor
gpio.read(Device.TIMED,0,Time.currentTicks() +
Time.toTickSpan(Time.MILLISECS,80));
}
}
121
Download

versão electrónica - Universidade do Minho