Title: TinyOS%20Tutorial
1TinyOS Tutorial
- Communication Networks I
- Wenyuan Xu
- Fall 2006
2Lecture Overview
- 1. Hardware Primer
- 2. Introduction to TinyOS
- 3. Programming TinyOS
- 4. Network Communication
3UC Berkeley Family of Motes
4Mica2 and Mica2Dot
- ATmega128 CPU
- Self-programming
- 128KB Instruction EEPROM
- 4KB Data EEPROM
- Chipcon CC1000
- Manchester encoding
- Tunable frequency
- 315, 433 or 900MHz
- 38K or 19K baud
- Lower power consumption
- 2 AA batteries
- Expansion
- 51 pin I/O Connector
1 inch
5MTS300CA Sensor Board
6Programming Board (MIB510)
7Hardware Setup Overview
8Lecture Overview
- 1. Hardware Primer
- 2. Introduction to TinyOS
- 3. Programming TinyOS
- 4. Network Communication
9What is TinyOS?
- An operation system
- An open-source development environment
- Not an operation system for general purpose, it
is designed for wireless embedded sensor network. - Official website http//www.tinyos.net/
-
- Programming language NesC (an extension of C)
- It features a component-based architecture.
- Supported platforms include Linux, Windows
2000/XP with Cygwin.
10Install TinyOS and the make
- Download
- http//www.tinyos.net/download.html
- Directory Structure
- /apps
- /Blink
- /Forwarder
- /contrib
- /doc
- /tools
- /java
- /tos
- /interfaces
- /lib
- /platform
- /mica
- /mica2
- /mica2dot
- /sensorboard
- From within the applications directory
- make (re)install.ltnode idgt ltplatformgt
- ltnode idgt is an integer between 0 and 255
- ltplatformgt may be mica2, mica2dot, or all
- Example make install.0 mica2
- make pc
- Generates an executable that can be run a pc for
11Build Tool Chain
Convert NesC into C and compile to exec
Modify exec with platform-specific options
Set the mote ID
Reprogram the mote
12Lecture Overview
- 1. Hardware Primer
- 2. Introduction to TinyOS
- 3. Programming TinyOS
- 4. Network Communication
13Characteristics of Network Sensors
- Small physical size and low power consumption
- Concurrency-intensive operation
- multiple flows, not wait-command-respond
- Limited Physical Parallelism and Controller
Hierarchy - primitive direct-to-device interface
- Diversity in Design and Usage
- application specific, not general purpose
- huge device variation
- gt efficient modularity
- gt migration across HW/SW boundary
- Robust Operation
- numerous, unattended, critical
- gt narrow interfaces
14A Operating System for Tiny Devices?
- Main Concept
- HURRY UP AND SLEEP!!
- Sleep as often as possible to save power
- provide framework for concurrency and modularity
- Commands, events, tasks
- interleaving flows, events - never poll, never
block - Separation of construction and composition
- Programs are built out of components
- Libraries and components are written in nesC.
- Applications are too -- just additional
components composed with the OS components - Each component is specified by an interface
- Provides hooks for wiring components together
- Components are statically wired together based on
their interfaces - Increases runtime efficiency
15Programming TinyOs
- A component provides and uses interfaces.
- A interface defines a logically related set of
commands and events. - Components implement the events they use and the
commands they provide - There are two types of components in nesC
- Modules. It implements application code.
- Configurations. It assemble other components
together, called wiring - A component does not care if another component is
a module or configuration - A component may be composed of other components
via configurations
Component Commands Events
Use Can call Must implement
Provide Must implement Can signal
16Component Syntax - Module
- A component specifies a set of interfaces by
which it is connected to other components - provides a set of interfaces to others
- uses a set of interfaces provided by others
module ForwarderM provides
interface StdControl uses
interface StdControl as CommControl
interface ReceiveMsg interface
SendMsg interface Leds
implementation // code implementing all
provided commands and used events
17Component Syntax - Configuration
Forwarder
18Configuration Wires
- A configuration can bind an interface user to a
provider using -gt or lt- - User.interface -gt Provider.interface
- Provider.interface lt- User.interface
- Bounce responsibilities using
- User1.interface User2.interface
- Provider1.interface Provider2.interface
- The interface may be implicit if there is no
ambiguity - e.g., User.interface -gt Provider ??
- User.interface -gt Provider.interface
19Interface Syntax- interface StdControl
- Look in lttosgt/tos/interfaces/StdControl.nc
- Multiple components may provide and use this
interface - Every component should provide this interface
- This is good programming technique, it is not a
language specification
interface StdControl // Initialize the
component and its subcomponents. command
result_t init() // Start the component and its
subcomponents. command result_t start() //
Stop the component and pertinent
subcomponents command result_t stop()
20Interface Syntax- interface SendMsg
- Look in lttosgt/tos/interfaces/SendMsg.nc
- Includes both command and event.
- Split the task of sending a message into two
parts, send and sendDone.
includes AM // includes AM.h located in
lttosgt\tos\types\ interface SendMsg // send a
message command result_t send(uint16_t address,
uint8_t length, TOS_MsgPtr msg) // an event
indicating the previous message was sent event
result_t sendDone(TOS_MsgPtr msg, result_t
success)
21Component implementation
module ForwarderM //interface
declaration implementation command result_t
StdControl.init() call CommControl.init()
call Leds.init() return SUCCESS
command result_t StdControl.start()
command result_t StdControl.stop()
event TOS_MsgPtr ReceiveMsg.receive(TOS_MsgPtr m)
call Leds.yellowToggle() call
SendMsg.send(TOS_BCAST_ADDR, sizeof(IntMsg), m)
return m event result_t
SendMsg.sendDone(TOS_MsgPtr msg, bool success)
call Leds.greenToggle() return
success
Command implementation (interface provided)
Event implementation (interface used)
22TinyOS Commands and Events
... status call CmdName(args) ...
command CmdName(args) ... return status
event EvtName)(args) ... return status
... status signal EvtName(args) ...
23TinyOs Concurrency Model
- TinyOS executes only one program consisting of a
set of components. - Two type threads
- Task
- Hardware event handler
- Tasks
- Time flexible
- Longer background processing jobs
- Atomic with respect to other tasks (single
threaded) - Preempted by event
- Hardware event handlers
- Time critical
- Shorter duration (hand off to task if need be)
- Interrupts task and other hardware handler.
- Last-in first-out semantics (no priority among
events) - executed in response to a hardware interrupt
24Tasks
- Provide concurrency internal to a component
- longer running operations
- Scheduling
- Currently simple FIFO scheduler
- Bounded number of pending tasks
- When idle, shuts down node except clock
- Uses non-blocking task queue data structure
- Simple event-driven structure control over
complete application/system graph - instead of complex task priorities and IPC
... post TaskName() ...
task void TaskName ...
25TinyOS Execution Contexts
- Events generated by interrupts preempt tasks
- Tasks do not preempt tasks
- Both essential process state transitions
26Event-Driven Sensor Access Pattern
command result_t StdControl.start() return
call Timer.start(TIMER_REPEAT, 200) event
result_t Timer.fired() return call
sensor.getData() event result_t
sensor.dataReady(uint16_t data)
display(data) return SUCCESS
SENSE
LED
Photo
Timer
- clock event handler initiates data collection
- sensor signals data ready event
- data event handler calls output command
- device sleeps or handles other activity while
waiting - conservative send/ack at component boundary
27Lecture Overview
- 1. Hardware Primer
- 2. Introduction to TinyOS
- 3. NesC Syntax
- 4. Network Communication
28Inter-Node Communication
- General idea
- Sender
- Receiver
Determine when message buffer can be reused
Fill message buffer with data
Specify Recipients
Pass buffer to OS
OS obtains free buffer to store next message
OS Buffers incoming message in a free buffer
Signal application with new message
29TOS Active Messages
- Message is active because it contains the
destination address, group ID, and type. - group group IDs create a virtual network
- an 8 bit value specified in lttosgt/apps/Makelocal
- The address is a 16-bit value specified by make
- make install.ltidgt mica2
- length specifies the size of the message .
- crc is the check sum
typedef struct TOS_Msg // the following are
transmitted uint16_t addr uint8_t
type uint8_t group uint8_t length int8_t
dataTOSH_DATA_LENGTH uint16_t crc // the
following are not transmitted uint16_t
strength uint8_t ack uint16_t time uint8_t
sendSecurityMode uint8_t receiveSecurityMode
TOS_Msg
30TOS Active Messages (continue)
31Sending a message
- Define the message format
- Define a unique active message number
- How does TOS know the AM number?
configuration Forwarder implementation
ForwarderM.SendMsg -gt Comm.SendMsgAM_INTMSG
ForwarderM.ReceiveMsg -gt Comm.ReceiveMsgAM_INTMSG
32Receiving a message
- Define the message format
- Define a unique active message number
- How does TOS know the AM number?
configuration Forwarder implementation
ForwarderM.SendMsg -gt Comm.SendMsgAM_INTMSG
ForwarderM.ReceiveMsg -gt Comm.ReceiveMsgAM_INTMSG
33Where exactly is the radio stuff?
34Spi bus interrupt handler
- Connection between Chipcon CC1000 radio and the
ATmega128 processor SPI bus. - Spibus interrupt handler SpiByteFifo.dataReady()
- SpiByteFifo.dataReady() will be called every 8
ticks.
fileCC1000RadioIntM.nc async event result_t
SpiByteFifo.dataReady(uint8_t data_in)
switch (RadioState) case RX_STATE
... case DISABLED_STATE case IDLE_STATE
... case PRETX_STATE ... case SYNC_STATE
... case RX_STATE ... return SUCCESS
35Receiving a message (1)
- IDLE_STATE ?SYNC_STATE
- Listen to the preamble, if the enough bytes of
preamble are received, entering SYCN_STATE
fileCC1000RadioIntM.nc async event result_t
SpiByteFifo.dataReady(uint8_t data_in)
switch (RadioState) case IDLE_STATE
if (((data_in (0xaa)) (data_in
(0x55)))) PreambleCount if
(PreambleCount gt CC1K_ValidPrecursor)
PreambleCount SOFCount 0
RxBitOffset RxByteCnt 0
usRunningCRC 0 rxlength
MSG_DATA_SIZE-2 RadioState
SYNC_STATE
36Receiving a message (2)
- SYNC_STATE ? RX_STATE
- look for a SYNC_WORD (0x33cc).
- Save the last received byte and current received
byte - Use a bit shift compare to find the byte boundary
for the sync byte - Retain the shift value and use it to collect all
of the packet data - SYNC_STATE ? IDLE_STATE
- didn't find the SYNC_WORD after a reasonable
number of tries, so set the radio state back to
idel - RadioState IDLE_STATE
fileCC1000RadioIntM.nc async event result_t
SpiByteFifo.dataReady(uint8_t data_in)
switch (RadioState) case SYNC_STATE if
( find SYCN_WORD)
RadioState RX_STATE else if ( too many
preamble) RadioState
IDLE_STATE
37Receiving a message (3)
- RX_STATE ?IDLE_STATE/SENDING_ACK
- Keep receiving bytes and calculate CRC until the
end of the packet. - The end of the packet are specified by the length
in the packet header - Pass the message to the application layer, no
matter whether the message passed the CRC check
fileCC1000RadioIntM.nc async event result_t
SpiByteFifo.dataReady(uint8_t data_in)
switch (RadioState) case RX_STATE
RxByteCnt if (RxByteCnt lt rxlength)
usRunningCRC crcByte(usRunningCRC,Byte)
if (RxByteCnt HEADER_LENGTH_OFFSET)
rxlength rxbufptr-gtlength else
if (RxByteCnt CRCBYTE_OFFSET) if
(rxbufptr-gtcrc usRunningCRC)
rxbufptr-gtcrc 1 else
rxbufptr-gtcrc 0
RadioState IDLE_STATE post
PacketRcvd()
38Error Detection CRC
- CRC Cyclic Redundancy Check
- Polynomial cods or checksums
- Procedure
- 1. Let r be the degree of the code polynomial.
Append r zero bits to the end of the transmitted
bit string. Call the entire bit string S(x) - 2. Divide S(x) by the code polynomial using
modulo 2 division. - 3. Subtract the remainder from S(x) using modulo
2 subtraction. - The result is the checksummed message
39Generating a CRC example
- Message 1011
- 1 x3 0 x2 1 x 1 x3 x 1
- Code Polynomial x2 1 (101)
40Decoding a CRC example
- Procedure
- 1. Let n be the length of the checksummed
message in bits - 2. Divide the checksummed message by the code
polynomial using modulo 2 division. If the
remaidner is zero, there is no error detected.
41CRC in TinyOS
- Calculate the CRC byte by byte
- crc0x0000
- while (more bytes)
- crccrcbltlt8
- calculate the high byte of crc
-
-
- Code Polynomial CRC-CCITT
- 0x1021 0001 0000 0010 0001
- x16 x12 x5 1
file system/crc.h uint16_t crcByte(uint16_t crc,
uint8_t b) uint8_t i crc crc b ltlt
8 i 8 do if (crc
0x8000) crc crc ltlt 1 0x1021
else crc crc ltlt 1 while (--i)
return crc
42Further Reading
- Go through the on-line tutorial
- http//www.tinyos.net/tinyos-1.x/doc/tutorial/inde
x.html - Search the help archive
- http//www.tinyos.net/search.html
- NesC language reference manual
- http//www.tinyos.net/tinyos-1.x/doc/nesc/ref.pdf
- Getting started guide
- http//www.xbow.com/Support/Support_pdf_files/Gett
ing_Started_Guide.pdf - Hardware manual
- http//www.xbow.com/Support/Support_pdf_files/MPR-
MIB_Series_Users_Manual.pdf
43Reference
- Programming TinyOS, David Culler, Phil Levis,
Rob Szewczyk, Joe Polastre University of
California, BerkeleyIntel Research Berkeley - TinyOS Tutorial, Chien-Liang Fok,
http//www.princeton.edu/wolf/EECS579/imotes/tos_
tutorial.pdf - Computer Networks, Badri Nath
http//www.cs.rutgers.edu/dataman/552dir/notes/wee
k2-one.pdf