Download presentation
Presentation is loading. Please wait.
1
Imote2 and TinyOS programming
Tomonori Nagayama Assistant Professor University of Tokyo 07/10/2009
2
Intel Imote2 Wireless sensor platform designed for data intensive applications (e.g. SHM) Processor: PXA271 13MHz – 416MHz Deep sleep (0.1mW) SRAM 256 KB Fixed point math SDRAM 32MB FLASH 32MB RF: ChipCon CC2420 ( ) 250 kbps Chip antenna & optional SMA antenna connector Mini-USB connector PMIC (Power Management IC) Sensor board connectors Basic connector (top) & advanced connector (bottom) OS: TinyOS, SOS, Linux etc.
3
Comparative advantage of Imote2
Wireless sensor node MicaZ IRIS Telos Imote2 Processor ATmega128L ATmega 1281 TIMSP430 XScalePXA271 Clock speed (MHz) 7.37 8 13-416 Bus size(bit) 16 32 Non-volatile memory (B) 512K 48K 32M Volatile memory (B) 4K 8k 1024K Potentially accurately synchronized sensing Data processing capability Open HW/SW
4
RF CPU Memory Sensor/ actuator Power data aggregation networking
SHM applications data aggregation Middleware networking sensing OS CPU Memory Sensor/ actuator RF Power Hardware
5
CC2420 RF chip on the Imote2 Single-chip 2.4 GHz compliant RF transceiver designed for low-voltage wireless application 250kbps data rate Low power consumption Rx: 18.8mA, Tx: ( V) Frequency range MHz Programmable in 1MHz steps, 16Ch Output power -24 to 0 dBm Receiver sensitivity -95 dBm
6
Imote 2 Antenna Options 2 Antenna Types Communication Options: Onboard
Peak Gain ~ 1.8 dBi External Peak Gain ~ 2.2 dBi Communication Options: Communication Channel, Transmission Power
7
Communication Range Set of loopback tests were conducted in an open field Environmental factors were kept to a minimum and no GHz networks were present Quantitative performance measure was reception rate – the number of packets received of the number that were sent
8
Communication Range Onboard Antenna The range depends on the circumstances. 30m on the data sheet. Shorter under certain circumstances. About 30 m when installed on a steel girder. About 170 m when one node is installed on a bridge tower. External Antenna
9
Packet collisions Packet collision Random backoff
Packet collision is dealt with at lower level. Packet experiencing collision are detected by TinyOS (ex. Cyclic Redundancy Check) and discarded. For users, packet collision is packet loss. Random backoff When a packet is transmitted, the channel clearance check is performed. If not clear, wait for a random period of time and try to transmit again
10
Packet structure Active message
typedef struct TOS_Msg { uint8_t length; uint8_t fcfhi; uint8_t fcflo; uint8_t dsn; uint16_t destpan; uint16_t addr; uint16_t srcpan; uint16_t srcaddr; uint8_t type; uint8_t group; int8_t data[28]; …. } Active message Defined at $TOSROOT/beta/platform/imote2/AM.h 14 byte header + 28 byte payload You can increase the payload up to 116 B. header payload
11
Packet transfer Broadcast and unicast
Broadcast: 1-to-”others in the range” Unicast: 1-to-1 Specify the destination by node ID Basically broadcast, but others ignore. Broadcast Unicast
12
Powering option PMIC allows 4 options Primary Battery
USB plug Powering option Pads PMIC allows 4 options Primary Battery Rechargeable battery USB Plug Pads on the Imote2 Battery board
13
Powering option Supply voltage requirement
V when nCHARGE_EN PIN position is 1 V from the battery board and V from USB and Pads on the Imote2 when nCHARGE_EN PIN position is 2
14
Crossbow battery board
Holds 3xAAA Maximum current 500mA If the supply voltage is above 4.7V, safety circuit shut off the power supply Imote2 can be connected via either the basic connectors or the advanced connectors.
15
Powering option for sensor boards
“VBAT” and “GND” are available on pins on the connectors. 1.8V and 3.0V regulated power is also available (max 200mA) VBAT and GND 1.8 & 3.0V
16
Power consumption Mode of operation current Deep sleep Mode 390 mA
Active Mode (13MHz, RF off) 31mA Active Mode (13MHz, RF Tx/Tx) 44mA Active Mode (104MHz, RF Tx,Rx) 66mA Ref. IRIS 25mA, MicaZ 32mA, Mica2Dot 16mA Power consumption too large? Efficient duty-cycle operation reduce power consumption Impossible with slower CPU nodes. If possible, such nodes end up in long-duty cycle operation. Advance in battery/energy harvesting technology Market growth in cellphone/netbook/laptop motivates development of low-power consumption/high performance CPU
17
Solar panel System2 System1 Solar panel + Li-ion polymer battery.
Power Management IC on the Imote2 is utilized to efficiently store energy on the batteries. System1 Solar panel + NiMH battery Commercially available solar panel + USB adapter. large standby power requirement (being modified to have no standby power requirement)
18
ITS400 sensor board 3-axis Accelerometer
STMicro LISL02DQ Digital accelerometer ±2g Resolution ~1mg Sampling frequency 280, 560, 1120, 4480Hz Temperature, humidity, and light sensors 4 ch 12-bit ADC Power consumption 3.3V Relatively large variation in sensitivity, sampling rate, offset, time delay
19
Data sheet
20
ITS400 sensor board Digital accelerometer LISL02DQ : easier for development but does not have sufficient characteristics Resolution Sampling timing Inflexible sampling rate/filter Large variation in sensitivity/offset Individual difference in fs
21
SHMA sensor board 3-axis Accelerometer Quickfilter Quickfilter =
20 MHz Crystal Imote2 Single-pole RC Low-pass AA Filter fc = 1500 Hz 3-axis Analog Accelerometer Op. Amplifier 16-bit Analog-to-Digital Converter SPI Interface 3-axis Accelerometer STMicro LISL02AL (analog) ±2g noise level 20-50mg/sqrt(Hz) Quickfilter 4-ch, 16-bit ADC with analog/digital filters Power consumption ~200mW Accurate sampling rate, small time delay Relatively large variation in sensitivity, offset Quickfilter = AA filter + ADC Digital filters
22
OS The Imote2 works on several operating systems including, TinyOS 1, TinyOS 2, .Net, Linux, SOS. Many software codes (e.g. drivers and middleware) have been developed on the TinyOS 1. TinyOS is suitable for low power consumption and small memory footprint applications.
23
TinyOS programming
24
TinyOS Open-source operating system for wireless embedded sensor networks A component based (modular) operating system Common abstractions such as packet communication, routing, sensing, actuation, and storage are provided as components. Components are connected with each other through interfaces. Component library can be used as-is or be customized. Written in the nesC language nesC: a dialect of the C programming language with the support for components. Lightweight (program size, memory footprint) as small as 400B
25
TinyOS Open-source operating system for wireless embedded sensor networks Event-driven Program flow is determined by events Supports concurrency Multiple things seem to be happening simultaneously (clock, radio, uart, sensing, etc) Free & open source >500 groups are using TinyOS. Many are actively contributing code. Ported to over a dozen platforms
26
Brief view on TinyOS directories
/TOSROOT apps/ applications beta/ beta contrib/ contributed files doc/ documentation including tutorials tools/ java file and others tos/ tinyos related files. e.g. interface, system, library, sensor boards etc. ISHMP directory includes files developed at UIUC Imote2 related files
27
Components A nesC application consists of components linked together to form an executable Components provide and use interfaces Interface declares a set of functions called commands and events. Commands are implemented by the component providing the interface Events are implemented by the component using the interface IF3 Comp. C IF1 IF2 Comp. B Comp. A IF Comp. interface component command event
28
Components A nesC application consists of components linked together to form an executable Two types of components Modules Provide application code, implementing interfaces Configurations Assemble other components together, connecting interfaces used by components to interfaces provided by others (wiring) One top-level configuration Comp. (module) pseudo-code Define interface 2; Define …. Comp. (configuration) pseudo-code Wire (connect) interface 3 of Comp. C to that of Comp. D Wire …
29
Components A nesC application consists of components linked together to form an executable (continued) Three types of files: modules, configurations, and interfaces You can make your own component/interface or use those provided (see $TOSDIR/interfaces, $TOSDIR/system, $TOSDIR/platform, etc.) Filename should be component/interface name + “.nc”
30
Example – Blink application
Located at $TOSROOT/apps/Blink Blink application Consists of a few components Blinks periodically Interface provided by the lower level components are used by upper level interface. Main StdControl component interface StdControl command event BlinkM Leds Timer Leds Timer StdControl LedsC SingleTimer
31
Interface Declares a set of functions called commands and events. They are defined (implemented) in module files. Interfaces are the only point of access to the component and are bi-directional A single component may use/provide multiple interfaces and multiple instances of the same interface. Naming convention Nouns, in mixed case with the first letter of each internal word capitalized. Ex. Timer.nc, Leds.nc, … interface file format interface IFNAME{ command datatype CMDNAME(ARGTYPE ARG); event datatype EVTNAME(ARGTYPE ARG); //list of commands and events follows }
32
Example – interfaces in Blink application
Interface StdControl, Timer $TOSROOT/tos/interfaces/StdControl.nc $TOSROOT/tos/interfaces/Timer.nc interface StdControl { command result_t init(); command result_t start(); command result_t stop(); } interface Timer { command result_t start(char type, uint32_t interval); command result_t stop(); event result_t fired(); }
33
Configuration List of components wiring configuration file format
Configurations wire components together All the components involved (including “Main” ) need to be listed after “components” keyword. The common interface of a provider and user are connected by arrow. (user).(interface) -> (provider).(interface) or (provider).(interface) <- (uer).(interface) You can omit “.interface” of the provider if apparent. One user interface can be wired (fanned out) to multiple provider interfaces. Configuration file name is usually xxxC.nc or xxx.nc configuration CFNAME{ } Implementation{ components Main, component1, component2, …, component K; Main.StdControl -> component1.StdControl; component1.ifname1->component2.ifname1; component3.ifname2<-componentK; … “Main”: only for the top level configuration List of components wiring Only one top-level configuration which is specified in the make file. Main.StdControl always needs to be wired in the top configuration file.
34
configuration file provides interface using “=“
configuration file format You can give local names to components so that you can easily swap components. Configuration can provide interfaces. Using “=“, configurations can bounce the responsibility to other components which actually provide interfaces or which again bounce the responsibility configuration CFNAME{ provides interface IFNAME; } Implementation{ components Main, component1 as XXX, component2 as YYY, …, component K as ZZZ; Main.StdControl -> XXX; XXX.ifname1->YYY; IFNAME=ZZZ; Local name using “as” configuration file provides interface using “=“
35
Example – Blink application
Consists of a few components Blinks periodically Interface provided by the lower level components are used by upper level interface. Main StdControl component interface StdControl command event BlinkM Leds Timer Leds Timer StdControl LedsC SingleTimer
36
Example - configuration
Blink application $TOSROOT/apps /Blink Related files: Blink.nc, BlinkM.nc, SingleTimer.nc, Makefile Configuration file wire modules Blink.nc (configuration file) configuration Blink { }implementation { components Main, BlinkM, SingleTimer, LedsC; Main.StdControl -> SingleTimer.StdControl; Main.StdControl -> BlinkM.StdControl; BlinkM.Timer -> SingleTimer.Timer; BlinkM.Leds -> LedsC; } List of components “components LIST” Configuration name “configuration NAME” Wiring “->” StdControl interface is provided by BlinkM component and used by Main component. Short for “BlinkM.Leds-> LedsC.Leds – User.interface -> Provider.interface – Provider.interface <- User.interface
37
Example – fan out Wiring to multiple components
Single user can be wired to multiple providers Blink.nc (configuration file) configuration Blink { }implementation { components Main, BlinkM, SingleTimer, LedsC; Main.StdControl -> SingleTimer.StdControl; Main.StdControl -> BlinkM.StdControl; BlinkM.Timer -> SingleTimer.Timer; BlinkM.Leds -> LedsC; } StdControl interface is also provided by SingleTimer component and used by Main component.
38
Example – Blink application
Consists of a few components Blinks periodically Interface provided by the lower level components are used by upper level interface. Main StdControl component interface StdControl command event BlinkM Leds Timer Leds Timer StdControl LedsC SingleTimer
39
Example – configuration providing interfaces
Interfaces in configuration can be provided by other component using “=“ SingleTimer.nc configuration SingleTimer { provides interface Timer; provides interface StdControl; } implementation { components TimerC; Timer = TimerC.Timer[unique("Timer")]; StdControl = TimerC; Configuration file can provide interfaces “=“ bounces responsibilities. Timer is actually provided by TimerC StdControl is provided in TimerC
40
Module Module file name is usually xxxM.nc
Module file format module MODULENAME{ provides interface IFNAME; users interface IFNAME; } Implementation{ //main body of the module //implement provided and used interfaces Module file name is usually xxxM.nc Interfaces provided and used must be implemented in the “implementation” block Multiple interfaces can be provided and used Commenting Characters after “//” and those between “/*” & “*/” are considered comments When more than one interface is provided or used, change provides/users interface IFNAME; to provides/uses { interface IFNAME1; interface IFNAME2; …} or provides/users interface IFNAME1; provides/users interface IFNAME2;
41
Example - module Module file implementation BlinkM.nc (module file)
module BlinkM { provides { interface StdControl; } uses { interface Timer; interface Leds; implementation { command result_t StdControl.init() { call Leds.init(); return SUCCESS; (BlinkM.nc continued) command result_t StdControl.start() { return call Timer.start(TIMER_REPEAT, 1000); } command result_t StdControl.stop() { return call Timer.stop(); event result_t Timer.fired() { call Leds.yellowToggle(); return SUCCESS; Module name “module NAME” interface declaration The beginning of implementation
42
Module inside “implementation{…}” Command and event implementation
(similar to function definition) Module must implement commands of interfaces this module provides Module must implement events of interfaces this module uses call and signal commands/events (similar to function call) Module can call commands of interfaces this module uses call IFNAME.CMDNAME(ARGTYPE ARG); Module can signal events of interfaces this module provides signal IFNAME.CMDNAME(ARGTYPE ARG); Commands and events of the interface are declared in the interface file command datatype IFNAME.CMDNAME(ARGTYPE ARG) { //command implementation return RTNVALUE; } event datatype IFNAME.EVTNAME(ARGTYPE ARG) { //event implementation return RTNVALUE; }
43
All commands of provided interfaces needs to be implemented (defined)
Example - module Module file implementation StdControl.nc (Interface file) interface StdControl { command result_t init(); command result_t start(); command result_t stop(); } All commands of provided interfaces needs to be implemented (defined) BlinkM.nc (module file) module BlinkM { provides { interface StdControl; } uses { interface Timer; interface Leds; implementation { command result_t StdControl.init() { call Leds.init(); return SUCCESS; (BlinkM.nc continued) command result_t StdControl.start() { return call Timer.start(TIMER_REPEAT, 1000); } command result_t StdControl.stop() { return call Timer.stop(); event result_t Timer.fired() { call Leds.yellowToggle(); return SUCCESS;
44
All events of used interfaces needs to be implemented (defined)
Example - module Module file implementation All events of used interfaces needs to be implemented (defined) Timer.nc (Interface file) interface Timer { command result_t start( char type, unit32_t interval); command result_t stop(); event result_t fired(); } BlinkM.nc (module file) module BlinkM { provides { interface StdControl; } uses { interface Timer; interface Leds; implementation { command result_t StdControl.init() { call Leds.init(); return SUCCESS; (BlinkM.nc continued) command result_t StdControl.start() { return call Timer.start(TIMER_REPEAT, 1000); } command result_t StdControl.stop() { return call Timer.stop(); event result_t Timer.fired() { call Leds.yellowToggle(); return SUCCESS; Leds.nc (Interface file) interface Leds { async command result_t init(); async command result_t redOn(); async command result_t redOff(); (no event) }
45
Module Interfaces can be given instance names File naming convention
to have multiple instances of the same interface, to clarify the interface role by its name, or for other purposes when the instance name is omitted, instance name is assumed same as the interface name. File naming convention Nouns, in mixed case with the 1st letter of each word capitalized. Terminates with “M” Ex. TimerM, UARTM interface IFNAME as ISNAME; interface IFNAME as ISNAME2; “interface IFNAME;” is same as “interface IFNAME as IFNAME;”
46
Concurrency model Event driven programming
As opposed to batch programming where the execution flow is determined by the programmer, the flow of event-driven programming is determined by events. (Ref. Wikipedia) Batch version pseudocode to add two numbers read a number (from the keyboard) and store it in variable A[0] read a number (from the keyboard) and store it in variable A[1] print A[0]+A[1] Event-driven version pseudocode set counter K to 0 repeat { whenever a number has been entered (from the keyboard){ //keyboard-number event store in A[K] and increment K // keyboard-number handler } if K equals 2{ // ready-to-sum event print A[0]+A[1] and reset K to // ready-to-sum handler } }
47
Concurrency model Two threads of execution: Task
Declared as task void taskname(){…}; Dispatched as post taskname(); The post operation places the task on an internal task queue which is processed in FIFO order. Once scheduled, they run to completion and do not preempt one another (FIFO). Preempted by hardware event handler. used to perform general-purpose "background" processing in an application Hardware event handler Executed in response to a hardware interrupt. May preempt the execution of a task or other hardware event handler. Commands and events that are executed as part of a hardware event handler must be declared with the async keyword. Hardware event handler should be short. Time consuming calculations should be performed as tasks.
48
Concurrency model Most of program code application users need to edit is in tasks. Hardware event handlers are likely already implemented. These handlers may post tasks to perform non-time-critical operations. Most application users edit these tasks. Time synchronization related programs may require modification of hardware event handler Not a real time system soft real-time system The hardware event handler has priority over the task Ref. A hard real-time system: guarantee that critical real time tasks be completed within their deadlines A soft real-time system: critical real-time task will receive priority over other tasks.
49
Execution flow When the mote starts up, Main.StdControl.init() and then Main.StdControl.start() are called. Lines defined in the corresponding command implementation are executed. When hardware events (RF receive, timer firing, etc) happen, corresponding hw event handlers are called and operations described in the implementation are performed. Tasks posted are executed in FIFO order after the handler operations are all completed. Commands and events execution is just like normal functions: when function is called, the flow goes to the called function. The flow comes back with the return value. When tasks are posted, the task is placed on an internal task queue and the flow comes back. The body of the task is executed after the caller’s execution is completed.
50
Execution flow – example-
Main.StdControl.init(); Main.StdControl.start(); + Event driven Blink application flow BlinkM.nc (module file) module BlinkM { provides { interface StdControl; } uses { interface Timer; interface Leds; implementation { command result_t StdControl.init() { call Leds.init(); return SUCCESS; (BlinkM.nc continued) command result_t StdControl.start() { return call Timer.start(TIMER_REPEAT, 1000); } command result_t StdControl.stop() { return call Timer.stop(); event result_t Timer.fired() { call Leds.yellowToggle(); return SUCCESS;
51
Execution flow – example-
Blink configuration Main StdControl Main.StdControl.init(); Main.StdControl.start(); component interface command result_t StdControl.start() { return call Timer.start(TIMER_REPEAT, 1000); } StdControl command event BlinkM Event driven Event Timer.fired Leds Timer event result_t Timer.fired() { call Leds.yellowToggle(); return SUCCESS; } Leds Timer StdControl Call Leds.yellowToggle(); LedsC SingleTimer
52
Execution flow -Task example-
BlinkTask application $TOSROOT/apps/BlinkTask Related files: BlinkTask.nc, BlinkTaskM.nc, SingleTimer.nc, Makefile BlinkTask.nc (configuration file) configuration BlinkTask { }implementation { components Main, BlinkTaskM, SingleTimer, LedsC; Main.StdControl -> BlinkTaskM.StdControl; Main.StdControl -> SingleTimer; BlinkTaskM.Timer -> SingleTimer; BlinkTaskM.Leds -> LedsC; }
53
Execution flow -Task example-
(BlinkM.nc continued) command result_t StdControl.start() { return call Timer.start(TIMER_REPEAT, 1000); } command result_t StdControl.stop() { return call Timer.stop(); task void processing(){ if (state) call Leds.redOn(); else call Leds.redOff(); event result_t Timer.fired() { state = !state; post processing(); return SUCCESS; BlinkTask application BlinkTaskM.nc (module file) module BlinkTaskM { provides { interface StdControl;} uses { interface Timer; interface Leds; }} implementation { bool state; command result_t StdControl.init() { state = FALSE; call Leds.init(); return SUCCESS; } Task is processed global variable Toggle “state” global variable post a task event execution is completed
54
Execution flow ~pseudo-code example~
Configuration Task: ex. calculate sum of received data resume interrupt mod1 Hardware event handler Task2: ex. calculate sum of received data Async event mod2 mod3 mod4 Task post task2 post task Packet interpret mod5 Reception timestamp mod6 RF Rx Event driven
55
makefile Make file specifies the main component by describing: “COMPONENT = NAME makefile needs to be in the application directory. Necessary path, options, etc. can be described in makefile Ex. Makefile COMPONENT=Blink include ../Makerules Main configuration component name “COMPONENT=NAME”
56
How to make and install Go to the application directory (ex. apps/Blink) and type: “make imote2” Compilation. Blink/build/imote2/main.bin.out is generated “usb-install” main.bin.out is downloaded to the Imote2 Ex. Open a cygwin window and type: (without “”) “cd $TOSROOT/apps/Blink” “make imote2” Connect your imote2 to the usb cable, press reset button, and type: (without “”) “usb-install”
57
Steps in Imote2 Programming
Prepare programming environment Cygwin, TinyOS source code, nesC compiler, ISHMP files, etc. Compile and upload (Prepare your own code) Compile TinyOS and user applications Upload to the Imote2 Run By connecting the Imote2 to power source and pressing reset button you can run the Imote2. You can check the imote2 behavior using LED and serial port interface.
58
Appendix A Programming basics
59
Programming basics Data type
Example: implementation { uint8_t a; command result_t StdControl.init() { return SUCCESS; } command result_t StdControl.start() { return call Timer.start(TIMER_ONE_SHOT, 1024); command result_t StdControl.stop() { return SUCESS; event result_t Timer.fired() { uint8_t b=0; a++; b++; Data type int8_t, int16_t, int32_t, uint8_t, uint16_t, uint32_t, float, double, enum, boolean, etc. int8_t is defined to ensure 8bit variable is used. Same for other data types. In the same way as C language. int, long int, etc, are also available. Array and structures can also be defined. Ex. uint8_t a[10]; Hardware floating point math is not supported. Slow
60
Programming basics Local and global variables
Example: implementation { uint8_t a; command result_t StdControl.init() { return SUCCESS; } command result_t StdControl.start() { return call Timer.start(TIMER_ONE_SHOT, 1024); command result_t StdControl.stop() { return SUCESS; event result_t Timer.fired() { uint8_t b=0; a++; b++; Local and global variables Local variable defined in command, event, task, or function Global variable defined outside “a” is available after the declaration “b” is available only in this block
61
Component & interface examples - Leds
Leds.nc Command Leds.init(): initialization redOn(), redOff, redToggle: red LED “on”, “off”, “toggle” greenOn(), greenOff(), greenToggle(): green LED “on”, “off”, “toggle” yellowOn(), yellowOff(), yellowToggle(): blue LED “on”, “off”, “toggle” set(uint8_t value): Set Leds to a specified “value” (0-7) Wired to LedsC.Leds Used as call Leds.redOn(); call Leds.yellowOff(); call Leds.set(0);
62
Component & interface examples - Timer
Timer.nc Command start(char type, uint32_t interval): start the timer. “type” is “TIMER_REPEAT” or “TIMER_ONE_SHOT”. “Interval” specifies timer interval in 1/1000 second unit. stop(): stop the timer: Event Fired(): the signal generated by the timer when it fires Often wired to TimerC.Timer[uint8_t id] Parameterized interface Used in wiring as “TimerC.Timer[unique(“Timer”)]; By using different id, multiple instances of an interface can be used. unique(“XXX”) generates a unique 8-bit number to each instance corresponding to the string “XXX” Used as call Timer.start(TIMER_REPEAT,10); call Timer.stop(); event result_t Timer.fired(){ … return SUCCESS; }
63
Component & interface examples - SendMsg
SendMsg.nc Command Send(uint16_t address, uint8_t length, TOS_MsgPtr msg): send a packet to “address” (node ID). TOS_BCAST_ADDR(0xffff) corresponds to broadcast. Event sendDone(TOS_MsgPtr msg, result_t success): the signal generated when the transmission is complete. Wired to GenericComm.SendMsg[uint8_t id] Used as TOS_Msg msg; msg.data[1] = 4;… call SendMsg.send(TOS_BCAST_ADDR,28,&msg); event result_t SendMsg.sendDone(TOS_MsgPtr doneMsg, result_t success){ … return SUCCESS; }
64
Component & interface examples - SendMsg
SendMsg.nc Command Send(uint16_t address, uint8_t length, TOS_MsgPtr msg): send a packet to “address” (node ID). TOS_BCAST_ADDR(0xffff) corresponds to broadcast. Event sendDone(TOS_MsgPtr msg, result_t success): the signal generated when the transmission is complete. Wired to GenericComm.SendMsg[uint8_t id] Used as TOS_Msg msg; msg.data[1] = 4;… call SendMsg.send(TOS_BCAST_ADDR,28,&msg); event result_t SendMsg.sendDone(TOS_MsgPtr doneMsg, result_t success){ … return SUCCESS; } typedef struct TOS_Msg { uint8_t length; uint8_t fcfhi; uint8_t fcflo; uint8_t dsn; uint16_t destpan; uint16_t addr; uint16_t srcpan; uint16_t srcaddr; uint8_t type; uint8_t group; uint8_t data[TOSH_DATA_LENGTH]; … (TOSH_DATA_LENGTH=28) …. }
65
Component & interface examples - ReceiveMsg
Wired to GenericComm.ReceiveMsg[uint8_t id] Used as event TOS_MsgPtr ReceiveMsg.receive(TOS_MsgPtr m){ uint8_t data[28]; data[0]= m->data[0]; … return m; } ReceiveMsg.nc Event receive(TOS_MsgPtr m): the signal generated when a packet is received.
66
Component & interface examples - Time
Time.nc (ISHMP/lib/Time64/) Command get64(): get 64-bit system time getHigh32(): get high 32-bit time getLow32(): get low 32-bit time set(uint64_t t): set system time adjust(int64_t t): adjust system time … Wired to LocalTimeC.Time; Used as uint64_t time; time = call Time.get(); call Time.adjust(diff);
67
Component & interface examples - SendVarLenPacket
SendVarLenPacket.nc Command send(uint8_t* packet, uint8_t numBytes): send numBytes of the buffer data. Event sendDone(uint8_t* packet, result_t success): send request completed Often wired to UARTBufferC.Time; Used as call SendVarLenPacket.send(pkt, strnlen(pkt, PKT_SIZE)) ; event result_t SendVarLenPacket.sendDone(uint8_t *packet, result_t success){ return SUCCESS; }
68
Component & interface examples - Flash
Often wired to FlashC.Flash; Used as call Flash.erase(addr); call Flash.write(addr, data, numBytes); call Flash.read(addr, data, numBytes); Flash.nc (platform/pxa27x/) Command write(uint32_t addr, uint8_t* data, uint32_t numBytes): writes numBytes of the buffer data to the address in flash specified by addr erase(uint32_t addr): erases the block of flash that contains addr. All bits are set to 1. read(uint32_t addr, uint8_t* data, uint32_t numBytes): read the data
69
Component & interface examples – BluSH_AppI
BluSH_AppI.nc (platform/imote2/) Command getName( char* buff, uint8_t len): callApp( char* cmdBuff, uint8_t cmdLen, char* resBuff, uint8_t resLen): Often wired to BluSHC.BluSH_AppI[uint8_t id] -> ApplicationModule.BluSH_AppI; Used as Command BluSH_result_t BluSH_AppI.getName(char *buff, uint8_t len){ const char name[]=“BluSH_AppI”; strcpy(buff, name); return BLUSH_SUCCESS_DONE; } Command BluSH_result_t BluSH_AppI.callApp(char *cmdBuff, uint8_t cmdLen, char *resBuff, uint8_t resLen){ …. sscanf(cmdBuff, “%u %u ….”, &var1, &var2, ….); …
70
Appendix B programming tips
71
Some important notes When you edit text file, the line ending needs to be unix system line ending (i.e., LF. not CRLF of windows system). Some text editor does not support LF. Try using Programmer’s notepad. To use debug port (or to run BluSH), use the second COM port. To transfer a large amount of data using UartBufferC (or SendVarLenPacket interface), use the first COM port. To program Imote2, connect your usb cable directly to the Imote2. To see the output using “imote2comm” command, connect the cable to the interface board.
72
Suggestion – appropriate use of pointer
Pointer basics When you pass arrays or structures to functions, commands, or events, do not pass variables, but pass pointers. If you pass variables, functions/commands/events will make a copy of them. Inefficient use of memory space. (Remember: memory space on sensor nodes are limited. You do NOT want to waste memory space. You pass the pointers to variables. In this way a function shares the same memory space with the function caller.
73
Debugging on the Imote2 Imote2 does not have a display. You cannot see the debug message directly on the node. The following is a guide to debug programs for Imote2 functions which do not depends on hardware should be prepared on a PC first. After debugging they’ll simply ported to the Imote2. Look for error messages during compilation. Connect the Imote2 to the interface board. Through the debug port, you can see the message the Imote2 send. In module file, “includes trace;” and at lines where you want to check execution state, insert the following “trace(DBG_USR1, “Change this message to yours %d \n”, yourvariable);” Also by implementing Leds.redOn() etc on program codes, you can confirm that the part of the code was executed. If you have two interface board, you can use the debug port of remote node, too.
74
Some tips on Imote2 data processing
Global variables are initialized to zero when declared. Local variables are not initialized to zero. malloc() is very convenient but make sure you free the memory space. Otherwise, available memory space get smaller and smaller. When you use structure, make sure they are 32-bit aligned and packed attribute is appropriately used.
75
Some tips on Imote2 data processing
At the end of compilation, RAM space needed for the program is displayed. This space need to be smaller than 256kB. However, memory space for local variable and malloc are not included. Make sure you have enough memory space. If you’d like to save compilation error message from cygwin window to text file, do the following “make imote2 >& log.txt” Array index starts at 0, not 1. int16_t data[3] consist of data[0],data[1],and data[2]. If you access data[3], you may experience system hangup. Such memory accesses are very likely the cause of Imote2 hangup you experience. Predefined TOS_LOCAL_ADDRESS: the local source address. TOS_BCAST_ADDR: broadcast address. Useful information sources ISHMP web site shm.cs.uiuc.edu Imote2 Yahoo group Crossbow knowledgebase
76
Notes on the use of structure
Notes on structure usage on the Imote2 PXA271 processor is a 32 bit processor. 32 bit is processed at a time. The data needs to be 32-bit aligned. 32bit 32bit 32bit 32bit 32bit Int8_t data[10] 8 8 8 8 8 8 8 8 8 8 OK
77
Notes on the use of structure
Notes on structure usage on the Imote2 PXA271 processor is a 32 bit processor. 32 bit is processed at a time. The data needs to be 32-bit aligned. 32bit 32bit 32bit 32bit 32bit Typedef struct{ int8_t data1; int16_t data2[2]; double data3;} sample 8 16 16 64 16 You’ll get strange results
78
Notes on the use of structure
Notes on structure usage on the Imote2 PXA271 processor is a 32 bit processor. 32 bit is processed at a time. The data needs to be 32-bit aligned. 32bit 32bit 32bit 32bit 32bit typedef struct{ int8_t data1; int16_t data2[2]; double data3;} sample; struct sample{ int16_t data2[2]; int8_t data1; int8_t dummy[3]; double data3; } sample __attribute__((packed)); Reorder Append dummy Use “packed” attribute to 32-bit align.
79
Notes on the use of structure
The header to TOS_msg has length such that by the time you get to the payload, the data is 16-bit aligned. If you define a structure used in the data member of TOS_msg, then it should be something like {16-bit, 32bit, 32bit , ..} and {8-bit, 8-bit, 64bit, …}. Structure of the form {32-bit, 16-bit,…} does not work.
80
IF3 Comp. C IF3 IF4 IF3 IF4 Comp. E Comp. F
Similar presentations
© 2025 SlidePlayer.com Inc.
All rights reserved.