Transcript
Internet of Things Architecture IoT-A Project Deliverable D5.4
Project acronym: Project full title: Grant agreement no.: Doc. Ref.: Responsible Beneficiary : Editor(s): List of contributors: Reviewers: Contractual Delivery Date: Actual Delivery Date: Status: Version and date V1, Aug 22 2011
IOT-A The Internet of Things Architecture 257521
Thorsten Kramp, Thomas Eirich, Marcus Oestreicher Michele Rossi
Final Changes
Reviewers / Editors
Project co-funded by the European Commission within the Seventh Framework Programme (2007-2013)
PU PP RE CO
Dissemination Level Public Restricted to other programme participants (including the Commission Services) Restricted to a group specified by the Consortium (including the Commission Services) Confidential, only for members of the Consortium (including the Commission Services)
INSIDE IBM MOTE RUNNER Volume 2: Byte Code, Load-File Format, and Intermediate Language
IBM Zurich Research Laboratory, Switzerland v1.0 - August 19, 2011
Copyright and Warranty Information Copyright (C) IBM Corp. All rights reserved. Even though IBM has reviewed this manual, IBM MAKES NO WARRANTY OR REPRESENTATION, EITHER EXPRESS OR IMPLIED, WITH RESPECT TO THIS MANUAL, ITS QUALITY, ACCURACY, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. AS A RESULT, THIS MANUAL IS PROVIDED “AS IS,” AND YOU, THE READER, ARE ASSUMING THE ENTIRE RISK AS TO ITS QUALITY AND ACCURACY. IN NO EVENT WILL IBM BE LIABLE FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES RESULTING FROM ANY DEFECT OR INACCURACY IN THIS MANUAL, even if advised of the possibility of such damages
Contents 1 Introduction 1.1 IBM Mote Runner . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Structure of this Document . . . . . . . . . . . . . . . . . . . . . . 1.3 Other Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3 3 4 4
2 Virtual Machine Basics 2.1 Basic Data Types . 2.2 Arrays . . . . . . . 2.3 Classes . . . . . . . 2.4 Interfaces . . . . . 2.5 Stack . . . . . . . .
. . . . .
5 6 6 6 7 8
3 Load-File Format 3.1 Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3 Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9 10 15 19
4 Byte Code 4.1 Load Constants, Variables, and Array Elements 4.2 Store Variables and Array Elements . . . . . . . 4.3 Special Loads and Stack Manipulation . . . . . 4.4 Arithmetic Operations and Conversions . . . . . 4.5 Control Flow . . . . . . . . . . . . . . . . . . . 4.6 Method Invocations . . . . . . . . . . . . . . . 4.7 Object Handling . . . . . . . . . . . . . . . . . 4.8 Miscellaneous Byte Codes . . . . . . . . . . . . 4.9 Argument and Stack-Handling Tables . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
21 22 26 29 32 37 42 47 49 50
5 Intermediate Language 5.1 Types and Syntax . . . . . . . . . . 5.2 Preamble and Depedencies . . . . . 5.3 Namespaces, Classes, and Interfaces 5.4 Assembly Initializer . . . . . . . . . 5.5 Scoping . . . . . . . . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
59 59 60 60 63 64
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
1
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
6 Example 6.1 C# . . . . . . . . . . . 6.2 Java . . . . . . . . . . 6.3 Intermediate Language 6.4 Load File . . . . . . . .
. . . .
. . . .
. . . .
. . . .
. . . .
2
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
65 65 66 68 71
Chapter 1
Introduction Inside IBM Mote Runner is a five-volume set that tells you what you need to know to write applications for sensor networks running IBM Mote Runner, to write drivers for sensors and actuators for IBM Mote Runner, to write your own development tools as add-ons to or replacements of the current tool chain of IBM Mote Runner, and to communicate with motes within a sensor network running IBM Mote Runner. It does not include information about programming in general, any hardwarespecific information, or fundamentals of sensor networks as such (e.g., networking protocols). It is further assumed that the reader is familiar with at least Java or C#, and has read Inside IBM Mote Runner, Volume 1: Overview. NOTE: IBM Mote Runner is under active development and currently in beta status. For the latest up-to-date information please refer to the HTML documentation provided as part of the IBM Mote Runner download.
1.1
IBM Mote Runner
IBM Mote Runner is a run-time platform and development environment for wireless sensor networks (WSN) currently under development at the IBM Zurich Research Laboratory, Switzerland. It consists of an on-mote environment, the so-called “firmware,” with some standard libraries, an off-mote environment (including an edge server facilitating communication between the WSN and the outside world, a command shell permitting high-level control of the WSN, and source-level debugger for refinement of the application code running inside the WSN), and a set of development tools such as a command-line compiler and graphical integrated development environment (IDE).
3
1.2
Structure of this Document
The remainder of this document is structured as follows. Chapter 2 introduces the basics of IBM Mote Runner virtual machine (VM) such as its data types and the stack model. Next, in Chapter 3, the load-file format of IBM Mote Runner is presented. This includes both the overall component structure of a load file as well as the interplay between the components. Chapter 4 then specifies all the byte codes of the IBM Mote Runner VM including their arguments and the changes to the stack, before in Chapter 5 an intermediate language is presented the bridges the gap between high-level object-oriented programming languages such as Java or C#, and the low-level load-file format. Finally, Chapter 6 lists a simple example application in Java, C#, the intermediate language, and as load file.
1.3
Other Resources
For discussions about IBM Mote Runner you may visit the IBM Mote Runner forums at http://www.alphaworks.ibm.com/tech/moterunner/forum http://groups.google.com/group/moterunner The latest release of IBM Mote Runner is available at http://www.alphaworks.ibm.com/tech/moterunner For technical questions or support you may contact us by email at
[email protected]
4
Chapter 2
Virtual Machine Basics The IBM Mote Runner virtual machine (VM) follows a stack-based architecture, that is, byte codes primarily operate on and manipulate the stack. For an efficient and compact implementation able to execute on a very small and, hence, commercially attractive hardware platform, the byte code is statically typed, which saves an additional lookup to determine the type of the objects on the stack. Having a typed byte code makes it possible to map various statically typed high-level programming languages onto the byte code (e.g., Java or C#). Statically typed byte code further allows static code and type flow analysis to permit off-mote optimizations that save on-mote resources including memory and power. The IBM Mote Runner VM byte code is object-oriented and natively supports classes, interfaces, fields, methods, and exceptions. Correspondingly, individual byte codes not only operate on primitive data types but also on classes or objects. This again facilitates the mapping of high-level object-oriented languages byte code from Java or C# to IBM Mote Runner byte code. The basic management unit of the IBM Mote Runner VM is the assembly. Assemblies can be dependent on other assemblies by using their classes or calling their static methods. All assemblies implicitly depend on the system assembly; further dependencies might include libraries or other assemblies.
5
2.1
Basic Data Types
The IBM Mote Runner VM supports the following basic data types. Basic Data Types byte
integer long reference
delegate
2.2
Short integer type; 8 bits wide. Interpretation as signed or unsigned value depends on the individual byte code. Bytes can be transported as 8-bit quantities but for computation they are promoted to 16-bit integer values. Standard integer type; 16 bits wide. Interpretation as signed or unsigned value depends on the individual byte code. Extended integer type; 32 bits wide. Long values are always interpreted as signed values. Reference to some object; 16 bits wide. A reference encodes the address of some object in memory whereby the object itselfs stores context information such as its type, its dynamic size (for arrays), or the value of its fields in case of a class object. Delegate to some method; 32 bits wide. A delegate encodes a static or virtual method address plus a reference to some object in case the method is virtual.
Arrays
The IBM Mote Runner VM natively supports array of basic types as elements. Arrays are limited in size to 216 − 1 elements. Any array element can be accessed using a 16-bit unsigned integer value.
2.3
Classes
Classes in IBM Mote Runner are user-defined data types. The built-in class Object serves as the root of the class hierarchy, that is, all classes ultimately are derived from Object. Each class extends exactly one superclass which is either another user-defined class or Object. Classes are defined by the following elements:
6
Class Elements superclass data fields
reference fields
virtual methods
interfaces
Each class extends another class. By default, the superclass is Object. Each class may extend the set of data fields of its superclass; data fields are 16 bits wide. Two consecutive fields can be used to store a long value. Delegate values may not be stored in data fields. Data fields are addressed by their field indices whereby all public data fields must have lower addresses than all the private ones. Each class may extend the set of reference fields of its superclass; reference fields are 16 bits wide. Reference fields are addressed by their field indices whereby all public reference fields must have lower addresses than all the private ones. Each class may add new virtual methods or override public virtual methods of one of its superclasses. New virtual methods are numbered by indices local to a class. All newly defined public virtual methods must have lower indices as all the newly defined private methods. Each class defines which interfaces it implements.
Note that classes do not contain static methods or fields on the byte-code level. All static methods or fields must be grouped in the special class com.ibm.saguaro.system.Assembly. In contrast to standard VMs for Java or C#, the Object class in IBM Mote Runner is completely empty. It does not have any fields, nor does it implement any virtual methods or interfaces. Its only purpose is to serve as a root type for all user-defined class types and all array types. Class fields are divided into separate namespaces for data and reference types to simplify garbage collection. References must be examined during garbage collection, and a separate namespace enables location of references with less overhead. Due to the design of byte-code instructions, the number of data and reference fields in an object is limited to 256. The number of virtual methods per object os also limited to 256. The IBM Mote Runner VM further implements two access scopes: public and private. Public fields (data and reference), and public virtual methods may be accessed by other assemblies. Private fields (data and reference), and private virtual methods can only be accessed from within the same assembly. It is possible to add public fields and virtual methods per class without breaking compatibility with a previous version of an assembly.
2.4
Interfaces
Interfaces in IBM Mote Runner define a collection of interface methods with special byte codes to invoke these methods. Interface methods do not have an access scope, only the interface itself can be public or private govering access to its methods. 7
Interfaces can extend one or more other interfaces; the dependency graph may not contain cycles, though. Interface methods are identified by indices with the maximum number of interface methods being limited to 256 again. Reference arrays can be annotated with an interface type. Such arrays contain only references to objects which implement the annotated interface.
2.5
Stack
The IBM Mote Runner VM stack holds the execution context of a program. It is organized as stack of frames where each frame pertains to a method invocation and holds the method’s arguments, its local variables, and any temporary values generated during expression evaluation. A stack frame again consists of stack cells, each stack cell being 16 bits wide. Long and delegate values take two consecutive stack cells, all other data types fit in a single stack cell. Each method, be it a static method or a virtual method of some object, has a method header describing its basic properties as follows: Method Header unsigned byte unsigned byte unsigned byte
nargs locals maxstack
number of method argument cells number of local variable cells (incl. argument cells) maximum size of the expression stack in stack cells
whereby nargs ≤ locals and locals + maxstack < 253. The byte codes implementing a method’s behavior start right after the method header. Whenever a method invocation takes place, a new frame is opened (unless the anount of stack cells as specified in the method header exceeds available resources). The old frame is suspended as long as the called method is active. If a called method terminates, the active frame is destroyed and a possible return value is transferred to the expression stack of the previous frame.
8
Chapter 3
Load-File Format An IBM Mote Runner load file is the binary representation of an assembly. Each assembly defines one application or library, whereby the distinction between assemblies and libraries is a purely conceptual one. Load files are transferred to a mote via a load protocol that is specified elsewhere and by itself is not relevant for the discussion here. It may be assumed that he load file is divided into smaller units and that the on-mote loader should be able to process arbitrarily sized load-file units. The loader shall collects received load-file units in an internal RAM buffer until it has sufficient data to process some logical data structure. Accordingly, the load file is designed so that modifications of the loaded data structures can takes place in RAM before they are eventually flushed out to persistent storage (Flash, EPPROM). This so-called single-pass loading and linking avoids to go over stored data a second time to perform fix ups. In order to facilitate loading and linking using a small RAM buffer, the load file contains transient information which only serves to help linking certain values. This transient data elements are removed during loading and linking, and shall not be written to persistent storage. Similarly, to reduce the size of load files, certain virtual elements are omitted which can be reconstructed on the fly on the mote (mostly padding). The loader on the mote shall generate these elements as required and write them to persistent memory. Offsets and distances within the load-file structures are laid out under the assumption that transient elements have been removed and virtual elements have been properly reconstructed. All integer values are encoded in big-endian byte order. The loader can adapt the byte order during upload if desired. All addressing of classes, methods, etc. inside the assembly are either relative to the current position, or relative to the base address of the assembly header component. The layout of all data structures before the assembly header component is at the discretion of the VM implementation since there is not direct reference to these from the rest of the load file. To describe the load-file layout we use a number of data types to describe the semantics of individual elements.
9
Load-File Data Types u1 u2 s2 u4 uN, uM fwd21 fwd22 rel1 rel1 coref
padn
cref mref
3.1
unsigned 8-bit value unsigned 16-bit value (big endian) signed 16-bit value (big endian) unsigned 32-bit value (big endian) sequence of bytes whose exact length is a complex term unsigned 16-bit value (big endian) forward distance; addrtarget = addrcurrent + f wd21 unsigned 16-bit value (big endian) scaled forward distance; addrtarget = addrcurrent + 2 ∗ f wd21 signed 8-bit value specifying a relative distance; addrtarget = addrcurrent + rel1 signed 16-bit value specifying a relative distance; addrtarget = addrcurrent + rel2 reference (16 bits) to an initialized immutable array; in the load file this value is an index into the table of initialized arrays which has to be converted by the loader to an index into an implementation specific object reference padding bytes which are not included in the load file itself but must be inserted by the loader as required; the subscript n indicates the alignment class reference (16 bits) encoding references to class/interface structures method reference (16 bits) encoding references to public methods in other assemblies
Components
A load file consists of a number of components concatenated in the order of their description in the following sections.
3.1.1
Prelude
The prelude identifies a file as a load file of some specific version. If this does not match the mote expectations or capabilities, the load protocol may abort early with some error. This component is transient, that is, its information need not be stored into persistent memory.
10
TYPE
NAME
DESC
u4
magic
u2
lffVersion
Magic number to identify the load file. The magic number is 0x5EEDCA5E(read seedcase). Major/minor version of the load-file format. The high byte encodes the major number, the low byte the minor number. This specification describes version 1.0.
3.1.2
Directory
The directory contains resource sizes so that the loader on the mote can either try to allocate memory ahead, or reject the load file upfront if it exceeds available resources. This component is transient, that is, its information need not be stored into persistent memory. TYPE
NAME
DESC
u1
numIniObjs
u1
numImports
u2
imageSize
u2
idataSize
Number of statically initialized immutable arrays which allows to estimate the implementation specific overhead required to store the statically initialized immutable arrays. Implementation specific overhead can be, for instance, the object header (carrying type information, array length, etc.) and possibly alignment. Number of imported assemblies which defines the size of the import table. An assembly may depend on other assemblies on the mote and it is up to the loader to resolve references to public items classes, methods, and fields of these assemblies. Size of the image after linking. To get the size in bytes this number must be multipled by 8. Size of all initialization data. To get the size in bytes this number must be multipled by 8. The value is the sum of the scaled data sizes of all initialized immutable arrays. The scaled data size s is computed from the size of initialization data n in the following way: s = (n + 7)/8.
3.1.3
Import Table
The import table contains a list of required assemblies, that is, those assemblies which are referenced by this assembly. The loader must validate that all required assemblies are available on the mote in a version that fits the one given in the import table. A requested major/minor number to any loaded assembly is considered a fit if it has the same major number and a minor number that is the same or higher. If there are multiple assemblies with eligible minor versions, the loader will choose, first, the one with exactly the same minor, and then the one with highest minor number. 11
TYPE
NAME
DESC
uN
asmname [numImports]
List of required assemblies. Each entry specifies the name and the version of the required assembly. When referring to elements of required assemblies, the remaining components of the load file, an index into the import table will be used. The loader must be able to translate such an index into a pointer to the run-time structures of the respective loaded assembly.
3.1.4
Assembly Name
The assembly name specifies the name of the assembly contained in this load file. If an assembly with the same name and same version already exists on the mote, the loader will abort the load protocol with an error. Several assemblies with the same name but different versions (different majors, or same majors but different minors) can coexist on a mote (cf. the import table on how the loader resolves references to assemblies if several versions are eligible). TYPE
NAME
DESC
uN
asmname
The binary name and version of this assembly.
3.1.5
Initialized Data
The initialized data contais a table of variable-sized structures describing preinitialized arrays. TYPE
NAME
DESC
uN
iniary [numIniObjs]
List of array initialization structures. This section may be empty if numIniObjs is zero.
3.1.6
Assembly Header
The assembly header starts the actual image of the assembly.
12
TYPE
NAME
DESC
u2
build
fwd22
asmCtor
fwd21
firstExBlock
fwd21
firstIf
u2
numMethods
This number identifies a particular build. While the version of an assembly only assert a specific API, the build number names the implementation. This number is stored on the mote and can be retrieved via the mote-manager application. This value refers forward to the start of the assembly initializer (a.k.a., assembly constructor). It points to a method header of a method that contains all static initializer code from all classes of the assembly. The initializers have to be serialized according to their static dependencies; unrelated initializers can be arbitrarily ordered. Cyclic dependencies shall be rejected by the tool chain. This value refers forward to the first exceptiondescriptor block in the code component. If there is not a single exception block in the whole assembly, this element is zero. This is the starting point for the VM to locate an appropriate handler if an exception occurs. This value refers forward to the first interface header in the class table. Number of methods in the method table of this assembly.
3.1.7
Method Table
The method table lists all public static methods of an assembly. The table is used for calls from other assemblies. A public method from another assembly is named by a reference to the assembly and an index into the method table which selects the desired method. TYPE
NAME
fwd22 methTable [numMethods] [numMethods]
3.1.8
DESC List of forward distances to method headers for each public static method.
Class Table
The class table describes all classes defined in the assembly. The list contains both private and public classes. If other assemblies refer to a public class, they use an index n which is resolved by scanning the list of class structures and finding the n-th public class. The VM can change such a load-file index into something else (e.g., an offset) to speed up access to classes structures defined in other assemblies.
13
TYPE
NAME
DESC
clshdr[N]
clsTable
List of class headers. The list is never empty since every assembly defines at least one class that subclasses com.ibm.saguaro.system.Assembly. This class hosts all static variables and is used for system management. The last class in the list has a “last class” flag set to signal the end of the list. The list is ordered in a way to help simplify state and computation required for linking. A class with a direct external (outside of this assembly) superclass is directly followed by all subclasses in this assembly in any order. There must not be any other class between them. The reason for this order is that the external class governs linking of the subclasses.
3.1.9
Interface Table
The interface table describes all interfaces defined in the assembly; it extends the class table introduced before. The list contains both private and public interfaces. If other assemblies refer to a public interface they use an index n which is resolved by scanning the list of interface structures and finding the n-th public interface. The VM can change such a load-file index into something else (e.g., an offset) to speed up access to interface structures defined in other assemblies. If the assembly does not define any interfaces, this component is absent and the last class in the class table also has the “last interface” bit set. TYPE
NAME
DESC
ifinfo[N]
ifTable
List of interface headers.
3.1.10
Code Segment
The code segment finally describes the code for all methods defined in the assembly. In the load file this is a sequence of opcodes, each one with an individual structure. Mostly, the opcodes are program instructions for the VM and are copied to persistent memory. But some signal structures are embedded into the stream of opcodes. For example, there are two special byte codes which are not VM instructions: mhdr and escape. The mhdr byte code signals the start of a method header, while the meaning of the escape byte code depends on the following byte: 01 for exception block structures, 02 for end-of-code. The code component also ends the load file.
14
3.2 3.2.1
Data Structures Assembly Name
The assembly name (asmname) is used in the load file to denote a dependency to some other assembly, and to describe the name and version of the assembly contained in the load file itself. TYPE
NAME
DESC
u1 u1 u1
minor major nameLen
Minor version of the specified assembly. Major version of the specified assembly. Length of the assembly name (1 ≤ nameLen ≤ 16). Sequence of bytes specifying the binary name of the assembly.
u1[nameLen] name
3.2.2
Initialized Data
The initialized data (iniary) describes the initialition data of an immutable array object, that is, its type and the initialization data itself. Immutable means that the contents of the array may not be changed after loading. The loader may place such data in persistent memory to save precious RAM space. TYPE
NAME
DESC
u1
typeLen
u1[len] u2[len] u4[len] coref[len]
inidata
Encodes the type of the array and its length. The two most significant bits encode the type information and the remaining 14 bits the length information. The type variable uses the following enconding: 0 for byte arrays (u1), 1 for integer array (u2), 2 for long arrays (u4), and 3 for reference arrays (coref). The type information specifies what elements are expected after typeLen in the load-file data stream. coref specifies a reference to some previously initialized immutable array object. The load file contains the index of the array in the iniTable which must be turned into an object reference by the loader. Sequence of data elements as determined from the type information.
3.2.3
Class Header
A class header (clshdr) describes the features of a class and is part of the class table. Each class header must start on an address that is a multiply of 4.
15
TYPE
NAME
DESC 7
PUBLIC if set, class is public; otherwise private 6 XASM if set, class is from external assembly; otherwise internal 5 ISIF if set, class is interface (always u1 flags 0 for classes) 4-2 unused, must be 0 1 ENDCT set for the last structure in the class table 0 LASTCL set for the last clshdr structure cref lnkref The XASM bit in the previous flags field is set, that is, the class reference refers to an external class and is used to resolve this class’ elements. u1 ifCnt Number of implemented interfaces. cref superclass Reference to the superclass. If this value is 0, the superclass is the built-in class of Object . u1 refFldCnt Number of reference fields of this class. A reference field is 16 bits wide. If an object is created from this class, the instance provides space for all the reference fields of this class and all superclasses. u1 dataFldCnt Number of data fields of this class. All nonreference variables of a class are mapped to data fields. The variable types byte and integer map exactly to one field slot, the type long uses two consecutive field slots. The type delegate may not be used as instance variable. If an object is created from this class, the instance provides space for all the reference fields of this class and all superclasses. u1 vbase Number of virtual methods implemented for the first time in this class. This counts both private and public methods. It does not count implementations of overridden methods. u1 methodCnt Number of virtual methods implemented in this class. This includes both private and public methods as well as overridden and newly created virtual methods. u1 overridden Number of overridden methods. vtok overrideVidxs Table describing the virtual-method indices of all [overridden] overridden methods. The table is ordered by increasing class hierarchy and increasing indices. Superclasses methods are listed before subclasses methods, and methods per class are listed with increasing virtual method indices. u1 newVidxs Virtual-method indices of methods implemented for the first time (not overriding methods in other classes). The table is ordered by increasing index values. fwd22 methodRefs Sequence of method references for all methods im[methodCnt] plemented 16by this class, ifmap interfaceRefs Sequence of interface references for all interfaces [ifCnt] implemented by this class.
3.2.4
Interface Map
An interface map (ifmap) defines how the methods of an interface are mapped onto virtual methods of a class. This structure is part of the class header. Each interface map must start at an even address. TYPE
NAME
cref ifc u1 mapCnt vtok[mapCnt]map
3.2.5
DESC Reference to the implemented interface structure. Length of the following map table. Table indexed with an interface method identifier storing the respective virtual method identifier.
Method Header
A method header describes the stack characteristics of any method (static or virtual). A method header is used when the method is being invoked to create an properly sized stack frame. Before creating a new stack frame, the VM checks that the stack resources are sufficient to hold such a frame. The byte codes implementing the method start right after the header. It is not required that the code be in a contiguous area after the header. The method header itself (i.e., after the special mhdr byte code) must start at an even address. TYPE
NAME
DESC
u1
mhdr
u1
nargs
u1
locals
u1
maxstack
Special byte code that introduces a method header in the sequence of byte codes in the code segment. It need not be written into persistent storage. Number of stack cells this method receives as arguments. Number of stack cells used for local variables. This number does not count the method argument cells. Inside of the method, arguments and local variables are consecutively numbered from 0 to nargs + locals whereby index 0 refers to the first argument being passed. Maximum number of stack cells used by the method code. At any point in time, the number of stack cells on the expression stack must not exceed this number.
3.2.6
Exception Block
An exception block is embedded into the bytes codes and describes the mapping of code ranges to tables of class references and entry points for exception handlers. An
17
exception block describes the mapping only for the code after the exception block and until the next exception block occurs, or until the end of the code if no next exception block. Code offsets in exception blocks are relative to the base address. The exception block itself (i.e., after the special escape byte code) must start at an address that is a multiply of 4. TYPE
NAME
DESC
u1 u1
escape 01
fwd21
next
u2
xbeg
Special byte code that introduces an excpeption block. The escape byte code followed by argument 01 signals the start of an exception block structure. This sequence need not be written to persistent storage. Forward distance to next exception block. If this is the last exeption block, this field is 0. Start offset for a code range, or zero if the exception block ends. A non-zero value indicates that an exception range is following. The offset is relative to the start of the exception block and denotes the byte address of the first byte code covered by this exception range plus one.
3.2.7
Exception Range
TYPE
NAME
DESC
u2
hcntrlen
excatch[N] u2
catchClauses xbeg
16-bit value that encodes the number of exception catch clauses following, and the code span for which these are valid. 15-11 number of exception catch clauses following (0-31) 10-0 length of the code range covered by this exception catch clauses List of catch handlers for a particular code region. Start offset for a code range or zero if the exception block ends. A non-zero value indicates that an exception-range structure is following.
18
3.2.8
Exception Catch Clause
TYPE
NAME
DESC
cref
cref
fwd21
exhcode
The class annotated with the catch block. The VM checks if the thrown exception object is a subclass of this class. If so, the VM execution is continued at the exception handler. A value of 0 denotes a finally clause. If present at all, it is always the last entry in the list. Place where the exception-handler code starts if the thrown exception object is a subclass of the class specified by cref .
3.3 3.3.1
Data Types Class/Interface Reference
A class reference or interface reference (cref) is used to specify a reference to a class in the same assembly, or in any assembly from the import list. If it refers to a class in the same assembly, it uses an encoding different from a class/interface reference pointing to a class/interface from the import list. A cref is a 16-bit value with the following two layouts depending on the location of the referenced class: Class in Same Assembly 15-11 10-0
0 offset
Class from Import List 15-11 10-0
assembly id index i
The offset identifies the class header within the class table of the assembly. It is a scaled offset relative to the address of the assembly header, whereby the first byte of the structure allows to distinguish between class or interface headers. If an external class or interface is referenced, the assembly id allows the loader to locate the address of the assembly header via implementation-specific run-time data structures. This address and index i are then used to compute the address of the class or interface header by scanning the class table of the other assembly for the i-th class or interface info structure with the PUBLIC flag being set.
3.3.2
Virtual Method Token
A virtual method token identifies a virtual method in some other assembly. It is used in class headers to describe an overridden virtual method. Virtual methods defined in the loaded assembly and overridden in the very same assembly do not
19
require such a descriptor since all internal relationships in an assembly are already resolved beforehand. Assume some class hierarchy A0 , A1 , ..., Ak−1 , Ak where A0 is the root class and Ak is the one overriding some method from superclass Ai . For resolving a virtual method index, the class reference points to the class Aj with the following properties: j < i, and all classes Aj+1 , ..., Ai are in the same assembly and Aj is not in the same assembly as Ai .
3.3.3
Method Reference
A method reference is used to specify an assembly-level method in another assembly that is used, for instance, after the call.asm byte code. It is a 16-bit value with the following layout: 15-11 10-0
assembly id offset
The most significant 5 bits (assembly id) specify the assembly which contains the method definition; a value of 0 refers to the current assembly. The offset identifies a specific method of an assembly. It is a scaled offset relative to the address of the other assemblies header structure. The assembly id allows the loader to located the address of the assembly header via implementation-specific run-time structures. This address and offset are then used to compute the address of the method header of the method to be invoked.
20
Chapter 4
Byte Code The IBM Mote Runner VM follows a stack-based architecture whose byte code is statically typed. That is, each byte code operates on statically defined data types, and there are different type codes for the same operation on different data types. For adding two integer or long values, for example, the two byte codes add and add.l have to be used, respectively. All byte codes in general operate on the stack, possibly popping a certain number of arguments from the stack and pushing other values in return. Some byte codes take further arguments, though, which are encoded in the byte code stream. These arguments consecutively follow the opcode of the byte code. For each byte code, both the arguments taken from and put onto the stack as well as the arguments passed directly are specified. Furthermore, since the IBM Mote Runner VM byte code is object-oriented and natively supports classes, interfaces, fields, methods, and exceptions, individual byte codes not only operate on primitive data types but may also take, for example, class or object references as arguments. Finally, IBM Mote Runner allows cross-assembly references (e.g., to link to libraries). Throughout this document, the following terminology is used accordingly. An assembly-level method is any non-virtual method, that is, either a static method or an non-virtual instance method. In the latter case, the method’s first argument must be the reference to the object implementing this method (the so-called this reference). Non-virtual instance methods are supported in C# but not in Java. Nevertheless, a byte-code converter from Java to IBM Mote Runner might, under certain conditions, use a non-virtual method call as an optimization. Public assembly-level methods are recorded in the method table of the assembly (cf. Chapter 3). Private assembly level methods are located by the relative distance between method header and calling byte code. The byte-code argument link class reference (lnkcref) is a class reference that must be evaluated only during loading and therefore should be not stored in persistent memory afterwards. It helps the loader to map the byte-code argument virtual method index (vidx) from a class local index into a unique index for the class hierarchy indicated by link class reference. Virtual indices are assigned per class and 21
have to be accompanied by a link class reference that identifies the superclass of the class where the virtual method received its virtual index. When a non-static byte-code method is executed, its object reference is loaded from the first cell of the method’s stack frame and its class info structure (clshdr) is located. There, the virtual method index is looked-up in the virtual table (vtable). If found, the method header (mhdr) is located using the corresponding slot in the methods table. If the virtual table does not contain virtual method index, the search continues at the superclass.
4.1
Load Constants, Variables, and Array Elements
MNEM
OPC
DESC
ldc ldc.b ldc.r
AE 89 A4
pushes int const onto stack pushes unsigned byte const onto stack pushes ref const onto stack
ldc.l ldc.{0..6} ldc.m1 ld ld.{0..7} ld.l ld.l.{0..3}
A1 10 17 84 20 80 30
pushes long const onto stack pushes int const {0..6} onto stack pushes int const -1 onto stack loads int/ref onto stack from local var loads int onto stack from local var {0..7} loads long onto stack from local var loads long onto stack from local var {0..3}
lda lda.b lda.r lda.l
42 41 40 43
loads loads loads loads
int onto stack from array unsigned byte onto stack from array ref onto stack from array long onto stack from array
ldf ldf.r ldf.l ldf.this ldf.r.this ldf.l.this ldf.asm ldf.r.asm ldf.l.asm asm.obj
C4 C0 C8 C5 C1 C9 D1 D0 D2 A0
loads loads loads loads loads loads loads loads loads loads
int onto stack from obj field ref onto stack from obj field long onto stack from obj field int onto stack from current obj field ref onto stack from current obj field long onto stack from current obj field int onto stack from current asm field ref onto stack from current asm field long onto stack from current asm field ref to asm obj on stack
4.1.1
ldc[.brl]
Load constant. Pushes a constant of type integer, byte, object reference, or long onto the stack. The value to push is passed as an argument.
22
ldc
ldc.b
ldc.r
ldc.r
4.1.2
arguments:
int
stack before: stack after:
... ...
arguments:
byte
stack before: stack after:
... ...
arguments:
ref
stack before: stack after:
... ...
arguments:
long
stack before: stack after:
... ...
int
byte
ref
long
ldc.{0..6}, ldc.m1
Load constant. Pushes a constant integer value of 0..6 or -1 onto the stack. No arguments are passed. ldc.{0..6}
stack before: stack after:
... ...
0..6
ldc.m1
stack before: stack after:
... ...
-1
4.1.3
ld[.l]
Load. Push an integer or a long value from a local variable onto the stack. The slot of the local variable whose value to push is passed as an argument. ld
ld.l
arguments:
locvar
stack before: stack after:
... ...
arguments:
locvar
stack before: stack after:
... ...
int
long
23
4.1.4
ld.{0..7}, ld.l.{0..3}
Load. Loads an integer or a long value from a local variable of the given stack slot(s) and pushes it onto the stack. Effectively, variables stored in the the first eight slots of the current stack frame can be addressed directly this way. No arguments are passed. ld.{0..7}
stack before: stack after:
... ...
int
ld.l.{0..3}
stack before: stack after:
... ...
long
4.1.5
lda[.brl]
Load array. Loads an integer value, byte value, reference, or long value from an array and pushes it onto the stack. The array element is addressed by an object reference and an array index, both taken from the stack. No arguments are passed. lda
stack before: stack after:
... ...
ref int
int
lda.b
stack before: stack after:
... ...
ref byte
int
lda.r
stack before: stack after:
... ...
ref ref
int
lda.l
stack before: stack after:
... ...
ref long
int
4.1.6
ldf[.rl]
Load field. Loads an integer value, reference, or long value from a field and pushes it onto the stack. The object reference is taken from the stack while the class link reference of the field and its field index are passed as arguments. ldf
ldf.r
arguments:
lnkcref, fldidx
stack before: stack after:
... ...
arguments: stack before: stack after:
lnkcref, fldidx ... ref ... ref
ref int
24
ldf.l
4.1.7
arguments:
lnkcref, fldidx
stack before: stack after:
... ...
ref long
ldf[.rl].this
Load field. Loads an integer value, reference, or long value from a field of the current object (this) and pushes it onto the stack. The class link reference of the field and its field index are passed as arguments. ldf.this
ldf.r.this
ldf.l.this
4.1.8
arguments:
lnkcref, fldidx
stack before: stack after:
... ...
arguments:
lnkcref, fldidx
stack before: stack after:
... ...
arguments:
lnkcref, fldidx
stack before: stack after:
... ...
int
ref
long
ldf[.rl].asm
Load field. Loads an integer value, reference, or long value from a static field and pushes it onto the stack. The assembly index of the static field and its field index are passed as arguments. ldf.asm
ldf.r.asm
ldf.l.asm
arguments:
asmidx, fldidx
stack before: stack after:
... ...
arguments:
asmidx, fldidx
stack before: stack after:
... ...
arguments:
asmidx, fldidx
stack before: stack after:
... ...
int
ref
long
25
4.1.9
asm.obj
Assembly object. Pushes a reference to the assembly object of a given assembly index onto the stack. The assembly index is passed as an argument. asm.obj
4.2
arguments:
asmidx
stack before: stack after:
... ...
ref
Store Variables and Array Elements
MNEM
OPC
DESC
st st.{0..7} st.l st.l.{0..3}
85 28 81 34
stores stores stores stores
int/ref from stack into local var int from stack into local var {0..7} long from stack into local var long from stack into local var {0..3}
sta sta.b sta.r sta.l sta.d
52 51 50 53 54
stores stores stores stores stores
int from stack into array unsigned byte from stack into array ref from stack into array long from stack into array delegate from stack into array
stf stf.r stf.l stf.this stf.r.this stf.l.this stf.asm stf.r.asm stf.l.asm
C6 C2 CA C7 C3 CB D4 D3 D5
stores stores stores stores stores stores stores stores stores
int from stack into obj field ref from stack into obj field long from stack into obj field int from stack into current obj field ref from stack into current obj field long from stack into current obj field int from stack into current asm field ref from stack into current asm field long from stack into current asm field
4.2.1
st[.l]
Store. Pops an integer or long value from the stack and stores into a local variable on the stack. The stack slot of the local variable is passed as an argument. st
st.l
arguments:
locvar
stack before: stack after:
... ...
arguments:
locvar
stack before: stack after:
... ...
int
long
26
4.2.2
st.{0..7}, st.l.{0..3}
Store. Pops an integer or long value from the stack and stores it into the local variable of the given stack slot. Effectively, variables stored in the the first eight slots of the current stack frame can be addressed directly this way. No arguments are passed. st.{0..7}
stack before: stack after:
... ...
int
st.l.{0..3}
stack before: stack after:
... ...
long
4.2.3
sta[.brld]
Store array. Pops an integer value, byte value, reference, long value, or delegate from the stack and stores it in an array. The array element is addressed by an object reference and an array index, both also taken from the stack. No arguments are passed. sta
stack before: stack after:
... ...
ref
int
int
sta.b
stack before: stack after:
... ...
ref
int
byte
sta.r
stack before: stack after:
... ...
ref
int
ref
sta.l
stack before: stack after:
... ...
ref
int
long
sta.d
stack before: stack after:
... ...
ref
int
del
4.2.4
stf[.rl]
Store field. Pops an integer value, reference, or long value from the stack and stores it into a field. The object reference is taken from the stack while the class link reference of the field and its field index are passed as arguments. stf
arguments:
lnkcref, fldidx
stack before: stack after:
... ...
ref
27
int
stf.r
stf.l
4.2.5
arguments:
lnkcref, fldidx
stack before: stack after:
... ...
arguments:
lnkcref, fldidx
stack before: stack after:
... ...
ref
ref
ref
long
stf[.rl].this
Store field. Pops an integer value, reference, or long value from the stack and stores it into a field of the current (this) object. The class link reference of the field and its field index are passed as arguments. stf.this
stf.r.this
stf.l.this
4.2.6
arguments:
lnkcref, fldidx
stack before: stack after:
... ...
arguments:
lnkcref, fldidx
stack before: stack after:
... ...
arguments:
lnkcref, fldidx
stack before: stack after:
... ...
int
ref
long
stf[.rl].asm
Store field. Pops an integer value, reference, or long value from the stack and stores it into a static field. The assembly index of the static field and its field index are passed as arguments. stf.asm
stf.r.asm
stf.l.asm
arguments:
asmidx, fldidx
stack before: stack after:
... ...
arguments:
asmidx, fldidx
stack before: stack after:
... ...
arguments:
asmidx, fldidx
stack before: stack after:
... ...
int
ref
long
28
4.3
Special Loads and Stack Manipulation
MNEM
OPC
DESC
lda.len
18
loads array length to stack as unsigned int
ld.b.ref ld.i.ref ld.r.ref ld.l.ref ld.d.ref
E8 EB EC E9 EA
create create create create create
ref ref ref ref ref
to to to to to
obj obj obj obj obj
stored stored stored stored stored
ldf.b.ref ldf.i.ref ldf.r.ref ldf.l.ref
CC CE CF CD
create create create create
ref ref ref ref
to to to to
obj obj obj obj
field field field field
lda.ref
86
create ref to section of existing array
pop pop2 dup dup2 dupx swap swap2
08 09 0A 0B 8A 0C 0D
discards top value on stack discards top two values on stack duplicates top value on stack duplicates top two values on stack duplicates some stuff on stack swaps top two int values on stack swaps two top long values on stack
4.3.1
on on on on on of of of of
stack stack stack stack stack type type type type
byte int ref long
lda.len
Load array length. Loads an array length value and pushes it onto the stack as an unsigned int. The array reference is taken from the stack. No arguments are passed. Throws an exception if the length of the array is larger than 216 . lda.len
4.3.2
stack before: stack after:
... ...
ref int
ld.{birld}.ref
Load reference. Creates a local reference object which refers to a local variable of type byte, integer, reference, long or delegate. A reference to the reference object is pushed onto the stack. The stack slot of the reference object and the lowest slot of the local variable are passed as arguments. *
arguments:
refobj, locvar
stack before: stack after:
... ...
ref
Note: The reference object and local variable must not be reused as long as the returned reference is being used. Reference objects cannot be returned from calls.
29
The stack slots of the local variable must be smaller than the stack slot of the local object, and the difference between the two stack slots must be less than 128.
4.3.3
ldf.{birld}.ref
Load field reference. Creates a local reference object which refers to a field. A reference to the reference object is pushed onto on the stack. The reference to the object of the field is taken from the stack, while the stack slot of the reference object to be created, the class link reference of the field, and its field index are passed as arguments. ldf.*.ref
arguments:
refobj, lnkcref, fldidx
stack before: stack after:
... ...
ref ref
Note: The reference object must not be reused as long as the returned reference is being used. Reference objects cannot be returned from calls.
4.3.4
lda.ref
Load array reference. Creates a local reference object which refers to a section of an existing array. A reference to the reference object is pushed onto on the stack. The reference to the existing array and the offset into the existing array are taken from the stack, while the stack slot of the reference object to be created is passed as an argument. lda.ref
arguments:
refobj
stack before: stack after:
... ...
ref ref
int
Note: The reference object must not be reused as long as the returned reference is being used. Reference objects cannot be returned from calls.
4.3.5
pop[2]
Pop. Pops the topmost value from the stack. No arguments are passed. pop
stack before: stack after:
... ...
sx
pop2
stack before: stack after:
... ...
slx
30
4.3.6
dup[2]
Duplicate. Duplicates the topmost value on the stack. No arguments are passed. dup
stack before: stack after:
... ...
sx sx
dup2
stack before: stack after:
... ...
slx slx
4.3.7
sx
slx
dupx
Duplicate. Duplicates the topmost m stack slots and moves them n slots down the stack. The values of m and n are are 4-bits values and passed as a single mn byte argument, whereby m < n. dupx
4.3.8
arguments:
mn
stack before: stack after:
... ...
s1 ...sn sn−m+1 ...sn
s1
...sn
swap[2]
Swap. Swaps the two topmost values onto the stack. No arguments are passed. swap
stack before: stack after:
... ...
sx sy
swap2
stack before: stack after:
... ...
slx sly
31
sy sx sly slx
4.4
Arithmetic Operations and Conversions
MNEM
OPC
DESC
add add.l sub sub.l mul mul.l div div.l div.u rem rem.l rem.u neg neg.l shl shl.l shr shr.l shr.u and and.l or or.l xor xor.l not not.l lnot
70 71 72 73 74 75 77 78 79 7A 7B 7C 7E 7F 60 61 62 63 64 68 69 6A 6B 6C 6D 6E 6F 65
adds two ints adds two longs subtracts two ints subtracts two longs multiplies two ints multiplies two longs multiplies two ints divides two longs divides two unsigned ints remainder of two ints remainder of two longs remainder of two unsigned ints negates int negates long left shifts int left shifts long right shifts int right shifts long right shifts unsigned int logical and on two ints logical and on two longs logical or on two ints logical or on two longs logical xor on two ints logical xor on two longs binary not on int (xor with -1) binary not on long (xor with -1) logical not on an int
inc inc.l
87 83
increment int increment long
sxb zxb sxi zxi l2i i2ui
1B 1C 1D 1E 1F 1A
sign-extend byte zero-extend byte (signed) int to long unsigned int to long long to int throw exception for negative int value
4.4.1
add[.l]
Add. Pops the two topmost values from the stack and pushes the sum of the two values. Works for both signed and unsigned values. No arguments are passed. add
stack before: stack after:
... ...
int int 32
int
stack before: stack after:
add.l
4.4.2
... ...
long long
long
sub[.l]
Subtract. Pops the two topmost values from the stack and pushes the difference of the two values (value1 - value2 ). Works for both signed and unsigned values. No arguments are passed. sub
stack before: stack after:
... ...
int1 int
sub.l
stack before: stack after:
... ...
long1 long
4.4.3
int2
long2
mul[.l]
Multiply. Pops the two topmost values from the stack and pushes the least significant 16 or 32-bit of the product of the two values. Works for both signed and unsigned values. No arguments are passed. mul
stack before: stack after:
... ...
int int
mul.l
stack before: stack after:
... ...
long long
4.4.4
int
long
div[.lu]
Divide. Pops the two topmost values from the stack and pushes the 16 or 32-bit quotient of the two values (value1 / value2 ). The input values are either signed (div[.l]) or unsigned (div.u). No arguments are passed. div[.u]
stack before: stack after:
... ...
int1 int
div.l
stack before: stack after:
... ...
long1 long
4.4.5
int2
long2
rem[.lu]
Remainder. Pops the two topmost values from the stack and pushes the 16 or 32bit remainder resulting from dividing the two values (value1 % value2 ). The input values are either signed (rem[.l]) or unsigned (rem.u). No arguments are passed.
33
rem[.u]
stack before: stack after:
... ...
int1 int
rem.l
stack before: stack after:
... ...
long1 long
4.4.6
int2
long2
neg[.l]
Negate. Pops the topmost value from the stack and pushes its negated value (2complement) onto the stack. No arguments are passed. neg
stack before: stack after:
... ...
int int
neg.l
stack before: stack after:
... ...
long long
4.4.7
int
long
shl[.l]
Shift left. Pops the two topmost values from the stack and pushes value1 shifted left by value2 bits onto the stack, effectively dropping the value2 most significant bits of value1 and inserting value2 zero bits as least significant bits. Only the four (shl) or five (shl.l) least significant bits of value2 are considered. No arguments are passed. shl
stack before: stack after:
... ...
int1 int
shl.l
stack before: stack after:
... ...
long1 long
4.4.8
int2
int2
shr[.lu]
Shift right. Pops the two topmost values from the stack and pushes the signed (shr[.l]) or unsigned (shr.u) value1 shifted right by value2 bits onto the stack, effectively dropping the value2 last significant bits of value1 and inserting value2 bits as most significant bits. The inserted bits have a value matching the sign of value1 (shr[.l]) or are zero bits (shr.u). Only the four (shr[.u]) or five (shr.l) least significant bits of value2 are considered. No arguments are passed. shr[.u]
stack before: stack after:
... ...
int1 int
shr.l
stack before: stack after:
... ...
long1 long
34
int2
int2
4.4.9
and[.l]
And. Pops the two topmost values from the stack and pushes the logical and of the two values onto the stack. No arguments are passed. and
stack before: stack after:
... ...
int int
and.l
stack before: stack after:
... ...
long long
4.4.10
int
long
or[.l]
Or. Pops the two topmost values from the stack and pushes the logical or of the two values onto the stack. No arguments are passed. or
stack before: stack after:
... ...
int int
or.l
stack before: stack after:
... ...
long long
4.4.11
int
long
xor[.l]
Xor. Pops the two topmost values from the stack and pushes the logical xor of the two values onto the stack. No arguments are passed. xor
stack before: stack after:
... ...
int int
xor.l
stack before: stack after:
... ...
long long
4.4.12
int
long
not[.l]
Not. Pops the topmost value from the stack and pushes its value with all bits reverted back onto the stack. No arguments are passed. not
stack before: stack after:
... ...
int int
not.l
stack before: stack after:
... ...
long long
35
4.4.13
lnot
Logical not. Pops the topmost integer value from the stack and pushes a logical not of its value back onto the stack. The result of logical not is either zero if the value is non-zero and vice versa. No arguments are passed. stack before: stack after:
lnot
4.4.14
... ...
int int
inc[.l]
Increment. Increments the value of an integer or long local variable by an integer value. The slot of the local variable as well as the increment are passed as arguments. No values are pushed or popped. arguments:
*
4.5
locvar, inc
Control Flow
MNEM
OPC
DESC
cmp cmp.l ceq cne clt cle cgt cge clt.u cle.u cgt.u cge.u
0E 0F 55 58 56 57 5A 59 5B 5C 5E 5D
compare compare compare compare compare compare compare compare compare compare compare compare
two two two two two two two two two two two two
signed ints (result: -1, 0, 1) signed longs (result: -1, 0, 1) signed ints (result: 0, 1) signed ints (result: 0, 1) signed ints (result: 0, 1) signed ints (result: 0, 1) signed ints (result: 0, 1) signed ints (result: 0, 1) unsigned ints (result: 0, 1) unsigned ints (result: 0, 1) unsigned (result: 0, 1) unsigned ints (result: 0, 1)
36
MNEM
OPC
DESC
bzeq bzne bzeq.w bzne.w bzlt bzle bzgt bzge bzlt.w bzge.w bzgt.w bzle.w beq bne beq.w bne.w blt bge bgt ble blt.u bge.u bgt.u ble.u blt.w bge.w bgt.w ble.w blt.u.w bge.u.w bgt.u.w ble.u.w
90 91 B0 B1 92 95 94 93 B2 B3 B4 B5 96 97 B6 B7 98 99 9A 9B 9C 9D 9E 9F B8 B9 BA BB BC BD BE BF
branch branch branch branch branch branch branch branch branch branch branch branch branch branch branch branch branch branch branch branch branch branch branch branch branch branch branch branch brnach branch branch branch
goto goto.w
8F AF
goto goto (wide)
tswtch tswtch.l lswtch lswtch.l
DC DD DE DF
table switch (int) table switch (long) lookup switch (int) lookup switch (long)
throw
06
throw exception
4.5.1
zero not zero zero (wide) not zero (wide) less zero less or equal zero greater zero greater or equal zero less zero (wide) greater or equal zero (wide) greater zero (wide) less or equal zero (wide) equal not equal equal (wide) not equal (wide) less greater or equal greater less or equal less (unsinged) greater or equal (unsigned) greater (unsigned) less or equal (unsigned) less (wide) greater or equal (wide) greater (wide) less or equal (wide) less (unsigned wide) greater or equal (unsigned, wide) greater (unsigned, wide) less or equal (unsigned, wide)
cmp[.l]
Compare. Pops the two topmost values from the stack and pushes one of the following three value back onto the stack:
37
−1 0 1
if value1 < value2 if value1 = value2 if value1 > value2
No arguments are passed. cmp
stack before: stack after:
... ...
int int
cmp.l
stack before: stack after:
... ...
long int
4.5.2
int
long
ceq, cne
Compare equal, compare not equal. Pops the two topmost values from the stack and pushes a 1-value if they are equal, and a 0-value otherwise. No arguments are passed. stack before: stack after:
*
4.5.3
... ...
int int
int
clt[.u], cle[.u], cgt[.u], cge[.u]
Compare less than, compare less than or equal, compare greater than, compare greater than or equal. Pops the two topmost values from the stack and pushes a 1-value if value1 value1 value1 value1
< ≤ > ≥
value2 value2 value2 value2
for for for for
clt[.u] cle[.u] cgt[.u] cge[.u]
and a 0-value otherwise. The comparison is either signed or unsigend. No arguments are passed. *
4.5.4
stack before: stack after:
... ...
int int
int
bzeq[.w], bzne[.w]
Branch equal to zero, branch not equal to zero. Pops the topmost value from the stack and continues execution at the current address plus the offset given as argument if the value is (bzeq[.w]) or is not (bzne[.w]) zero. Otherwise the following byte code is executed. The offset is a signed 8-bit or 16-bit (.w) value.
38
*
4.5.5
arguments:
ofs
stack before: stack after:
... ...
int
bzlt[.w], bzle[.w], bzgt[.w], bzge[.w]
Branch less than zero, branch less than or equal to zero, branch greater than zero, branch greater than or equal to zero. Pops the topmost value from the stack and continues execution at the current address plus the offset given as argument if value1 value1 value1 value1
< ≤ > ≥
0 0 0 0
for for for for
bzlt[.u] bzle[.u] bzgt[.u] bzge[.u]
Otherwise the following byte code is executed. The value popped is treated as signed, the offset is a signed 8-bit or 16-bit (.w) value. *
4.5.6
arguments:
ofs
stack before: stack after:
... ...
int
beq[.w], bne[.w]
Branch equal, branch not equal. Pops the two topmost values from the stack and continues execution at the current address plus the offset given as argument if the values are equal (beq[.w]) or not equal (bne[.w]). Otherwise the following byte code is executed. The offset is a signed 8-bit or 16-bit (.w) value. *
4.5.7
arguments:
ofs
stack before: stack after:
... ...
int
int
blt[.w], ble[.w], bgt[.w], bge[.w], blt.u[.w], ble.u[.w], bgt.u[.w], bge.u[.w]
Branch less than, branch less than or equal, branch greater than, branch greater than or equal. Pops the two topmost values from the stack and continues execution at the current address plus the offset given as argument if value1 value1 value1 value1
< ≤ > ≥
value2 value2 value2 value2
for for for for
bzlt[.u] bzle[.u] bzgt[.u] bzge[.u]
Otherwise the following byte code is executed. The values popped are treated as
39
signed or unsigned (.u), the offset is a signed 8-bit or 16-bit (.w) value. arguments: stack before: stack after:
*
4.5.8
ofs ... ...
int
int
goto[.w]
Goto. Continues execution at the current address plus the offset given as argument. The offset is a signed 8-bit or 16-bit (.w) value. No values are pushed or popped. arguments:
*
4.5.9
ofs
tswtch[.l]
Table switch. Pops an integer or long value v from the stack and computes an index i into a table of code addresses. The lowest table index low and the number of indices cnt are passed as arguments. If (i = v−low)
error codes . . . . . . . . . . . . . . . . . . . . . . . .
22 27
A.1 A.2 A.3 A.4
USB USB USB USB
30 31 32 33
HID HID HID HID
client client client client
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
descriptor constants device descriptor . . config descriptor . . report descriptor . .
2
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
4
. . . .
. . . .
. . . .
. . . .
. . . .
Chapter 1
Introduction This document describes the default communication protocols used to exchange messages with IBM Mote Runner motes. Firstly, the link protocol (LIP) is documented which is used to communicate from a host with IBM Mote Runner motes attached by serial line or USB connection. Secondly, the wireless link protocol (WLIP) is specified, a 802.15.4 based wireless protocol which enables the exchange of LIP messages with wirelesse motes through a WLIP gateway. In the IBM Mote Runner system, a WLIP gateway is a mote attached to a host using LIP, running the IBM Mote Runner OS and the “wlip-gateway” application. The “wlip-gateway” application is reponsible to forward the LIP messages between host and wireless motes by encapsulating them in radio messages. LIP and WLIP are exported to on-mote applications through an application programming interface (API), but is also used by the system framework and its mote manager (MOMA) protocols (see Chapter 4). These protocols allow for the management of IBM Mote Runner motes, especially of the installed applications. This document is organized as follows. First, the on-mote LIP API is shortly introduced (see [3] for details). Second, the key characteristics of the LIP and WLIP protocol for host applications are detailed. The following LIP specification handles the serial and USB based communication interface. The WLIP chapter specifies the protocol extending LIP to reach wireless motes. Finally, this document specifies the MOMA protocols to manage motes based on the exchange of LIP messages. Protocol data units (PDUs) and data structures are listed using the following list of data types. Data Type Definitions u1 Unsigned 8-bits value u2 Unsigned 16-bits value (big endian) s2 Signed 16-bits value (big endian) u4 Unsigned 32-bits value (big endian) u[N] Sequence of N bytes padn Padding bytes; the subscript n indicates the alignment eui 8-bytes, LSB, EUI-64 format specifying a unique mote id (see [4])
3
On-Mote API From the on-mote application point of view, the LIP and WLIP protocols are stateless, datagram-oriented communication protocols. LIP and WLIP messages carry a source and destination port allowing for the multiplexing on the side of the host and mote. Additionally, they encapsulate application-specific, transport-independent data available to both system and applications. The Mote Runner system receives LIP and WLIP messages over the air or cable, extracts the transport-independent part and passes it on to a handler registered for the target port, either residing in the system framwork or application. Port 0 is reserved for the system and MOMA protocols (see Chapter 4), other ports are reserved for addressing assemblies using their assembly id (..63). Applications may explicitly allocate additional ports to receive LIP messages. Applications register a receiver method with the LIP API (see also the Mote Runner system API specification [3]) which is called with incoming LIP messages in the format as depicted in Table 1.1. On-mote applications use the Offset
Type
Description
0 4 6 7
u4 u2 u1 u1[n]
Host address, value representing the host. Host port, value representing the source/target port on the host. The target/source port on the mote. Payload: the protocol-/application-specific payload.
Table 1.1: LIP/WLIP messages for Mote Runner assemblies “send” method in the LIP class to send a message to the host using LIP or WLIP. They can transmit data to the host whenever the VM activated them, e.g. after a message was received or a timer expired. Typically, the application uses the header information (host address, host port, mote port) from an incoming message, adds its application-specific payload data and sends the message. The host port in the response allows for the multiplexing of the message on the receiver side. The “send” method does not return an error if the message could not be transmitted even after several retries. LIP assumes the resulting error situations to be detected and handled by the host.
Off-Mote Properties Mote identificcation Both LIP and WLIP export the uniqueid of a mote to a host for the unique id of the identification of a mote. The unique id of a mote is persistently stored in the firmware and should be formed according to the rules for the Extended Unique Identifier (EUI-64) of the Institute of Electrical and Electronics Engineers (IEEE) ( [4]). At runtime, it can be altered using one of the MOMA protocols (see
4
Chapter 4). Host applications can thus track motes and their unique id in the LIP and WLIP network and use them as address specification in messages. Communication Properties LIP and WLIP are stateless, datagram-oriented communication protocols. Whereas LIP messages sent over physical line are unicast messages, WLIP also allows for broadcasting a LIP message to wireless motes. LIP and WLIP do not support message fragmentation, but messages are subject to a maximum size which is hardware dependent and can be queried using LIP and WLIP mechanisms. In the IBM Mote Runner implementation, LIP and WLIP messages may be buffered at various levels before they are transmitted to the target mote. The acceptance of a message is ackknowledged by the target mote in both LIP and WLIP. In case of the WLIP implementation, messages are even retransmitted up to a configurable number of times if no ackknowledgement is received. Due to buffering and timing constraints, the host is still notified in an asynchonous manner. LIP and WLIP assume error recovery to typically take place at the application-specific layer on the host side. In contrast to LIP, WLIP allows to broadcast a LIP message to all reachable motes. Broadcast messages are not ackknowledged and it is fully up to the host application to determine the success and progress of its operations. Both LIP and WLIP assume the host application to drive and control the communication with connected motes. Whereas the host may reach any of the connected motes, the motes themselfes can only send messages to the host, no direct intercommunication between motes is supported. In case of WLIP, the wireless motes form a star-based network where communication takes place only directly between gateway and wireless motes and vice versa.
5
Chapter 2
LIP 2.1
Introduction
The IBM Mote Runner Link Protocol (LIP) supports the following physical media to connect to motes: RS232 cables, serial over USB, and the USB profile Human Interface Device (HID). LIP supports querying the hardware interfaces for connected motes, their unique mote id and state. Additionally, it allows for resetting attached motes, the transmission of LIP messages to connected motes and the notification and delivery of events from the mote. These events are LIP or log messages from the Mote Runner system and applications or state changes such as a mote reset.
2.2
Sample Off-Mote C-API
The IBM Mote Runner SDK ships with a C-library allowing to incorporate the LIP protocol in host applications. It abstracts from the physical connection (serial or USB) and provides a simple API to access described LIP features. The following provides a quick overview of the API which is fully specified in [2]. getPD
lip pd t
Calling LIP getPD returns an object of type lip pd t which acts as main entry point to the LIP API. enumerate Allows to enumerate the available hardware interfaces to connect to motes. Both the available serial and UDB HID ports and their connection parameters can be queried. create Creates a LIP handle of type lip t which encapsulates the connection to a single hardware interface, either serial or USB based. waitForMultiple Wait for events on a selected set of connected motes. The function returns as soon as there is a pending event to read from a mote. 6
lip pd t
open
close reset get read send
Opens a connection to a single hardware interface and connects this interface to the specified LIP handle. Closes the connection and frees resources. Resets the mote attached to this physical connection. Queries properties of the connected mote, especially its unique mote id. Read an event from the connected mote, a LIP or log message, or a state change. Send a LIP message to a connected mote. The message might be buffered in the library and sent at a later time.
All functions may return an error of type lip err t . The function lip t . lastErr may be used to receive a human-readable representation of the error. The use of the API is typically centered around calls of lip pd t . waitForMultiple . A client enumerates available hardware interfaces, connects them, queries the mote states and spawns a thread calling lip pd t . waitForMultiple for the notification about mote events. If the program wants to send a LIP message to a mote, it checks for the mote to be ready for communication (which might require an external hardware reset first). If it is ready, it calls lip t .send to issue the message. lip pd t . waitForMultiple returns whenever an event occured. The client can examine the event and act accordingly. For instance, if a LIP message arrived, it can continue wth the application-specific protocol.
2.3
Serial Interface
By default, the off-mote C-library initializes the serial line in the following mode: two stop bits, no hardware flow control, receiver enabled, no parity enabled, duplex mode and baudrate 57600. The C-library still allows to overwrite these default settings, if the host application and mote agree and support different serial settings and higher baudrates. The LIP protocol expects the PC to receive byte by byte and not to loose any data on reception (i.e. non-canonical, non-line input mode for the serial connection). On the mote side, the IBM Mote Runner OS uses the UART of the microccontroller for the serial communication. The C-library buffers packets to transmit internally up to a certain limit. Transmission errors are reported asynchronously. The library thus implements a limited control flow on the side of the host. On the mote, the flow-control occurs at the VM level. While a LIP packet from the host is handled by mote system and application, the serial line is reported to be busy and the Mote Runner OS rejects any newly incoming packets.
7
Type
Tag
Description
u1
FS
u1
HDR
u1 u1[LEN] u2 u1
LEN DATA CRC FE
Frame start: the start of the frame is signaled by 0xAD. SEQNO 4-bit, high nibble, sequence number. TAG 4-bit, low nibble, frame type, see Table 2.4. If payload, length of the following payload data. If payload, payload data for messages of type TAG. If payload, Fletcher CRC over the payload data (RFC 905, [5]). Frame end: the end of the frame is signaled by 0xAE.
Table 2.2: Serial frame format Tag
Value
Escaped
FS FE ESC
AD AE AF
AF00 AF01 AF02
Table 2.3: Serial escape sequences
2.3.1
Serial Frame Format
All frames are encoded using the format speified in ( Table 2.2). LEN, DATA and CRC fields are only included for serial frame messages carrying data. The frame format uses start and end delimiters to signal the start and end of messages in the stream of characters read from the serial line. The CRC code in case of payload allows to verify the integritry of the message. Frames with payload data appear in both communication directions, from host to mote (h2m) as well as from mote to host (m2h). The TAG nibble indicates the type of the frame and whether it contains any payload data. If the payload data contains the FS and FE bytes, they must be escaped according to ( Table 2.3). Table 2.4 specifies specifies the TAG value of frames in the HDR field, the communication direction they are used in (host to mote: h2m, mote to host: m2h), and whether the frame is of type SF1 (includes payload) or of SF2 (without payload). Tag
Value
h2m
m2h
Description
READY BUSY RESET INFO LOG DATA ATR STATUS
1 2 3 4 5 6 7 8
SF2 SF2 SF2 SF1 SF1
SF2 SF2 SF1 SF1 SF1 SF2 -
Mote acknowledges a data frame. Mote acknowledges a data frame. Host requests reset, mote reports reset. Host requests info, mote reports info. Mote reports log data. Host sends data, mote reports data. Host acknwowledges mote reset. Host asks for status.
Table 2.4: Serial message types
8
As the USB based communication shares the basic frame contents with the serial communication, the individual messages and their payload structure is specified in detail in Section 2.5.
2.3.2
Serial Communication FLow
Mote-To-Host At system startup time, the mote sends a RESET message (see Section 2.5) and waits for for an (answer-to-reset) (ATR) message by the host. If no ATR is received and the reason for the system start was a mote reset, the request is resent. Otherwise, the mote shutdowns its serial communication facility and operates wirelessly. A RESET message may occur spontaneously for the host, other messages received without an explicit request by the host are: • DATA and LOG messages: The mote sends a LIP or log message to the host. LOG and DATA messages are described in Section 2.5. • READY and BUSY messages: The mote notifies the host about being ready for incoming LIP packets or busy. Both mesages do not contain payload data. Host-To-Mote The host only transmits DATA if a mote is in ready state. If the host has multiple messages to send, it must buffer them internally and synchronize with the reception of READY messages from the mote until it can continue sending messages. When a host sends DATA, the mote replies with a BUSY frame to acknowledge the packet and to signal that the virtual machine is handling it. After the system or application has handled the incoming message and the system is ready to receive the next frame, it sends out a READY message back to the host. The host may program a timer and resend the DATA packet in case it did not receive the BUSY, but must use the same SEQ number as it has used before (see format of DATA message at in Section 2.5). While the DATA transmission must adhere to the busy and ready state of a mote, STATUS, INFO and RESET requests may be sent at any time, even within a busy period.
2.4
USB Interface
A mote connected via a USB-To-Serial bridge is operated as in case of the serial interface. The device driver on the host side maps the bridge to a serial device which is accessed from the host application as usual. On the mote side, the serial interface stays the same, too. The IBM Mote Runner OS supports operating a mote as a client USB device if the mote hardware features the required USB interface support. During the initial USB handshake, the OS registers the mote as a USB human-interface-device (HID)
9
with the USB host. The general USB handshake process is specified in detail in [1]. Most prominent is the exchange of the USB device descriptor, report descriptor and config descriptor. The descriptors returned by the IBM Mote Runner OS are specified in the Appendix A, in Table A.2, Table A.3 and Table A.4. The listed constants can be found in Table A.1
2.4.1
HID Frame Format
The USB specification requires the definition of fixed size reports which are used for the exchange of messages between USB host and USB client device. The IBM Mote Runner OS used variable length mssages for the communication over the serial line which must then be padded to satisfy the USB requirements. As the lower layers of USB already address data integrity, the frame start and end delimiters, sequence number and CRC used in the serial frame can be left out. The format of the UDP reports exchanged between host applications and the IBM Mote Runner OS is then depicted in table Table 2.5. The TAG, LEN and DATA field matches the fields used in the serial frames, the initial direction byte and padding results from the USB requirements. Similar to the serial frame, LEN and DATA is omitted if the frame TAG indicates that the message does not carry any data. Type
Name
u1
DST
u1 u1 u1[LEN] padn
TAG LEN DATA PAD
Description 0x01 USB HID report from mote. 0x02 USB HID report from host. Frame tag: carries the frame type, e.g. INFO, RESET. Lenght: specifies the length of the following data. Payload: data for messages of type TAG. Padding to fixed size of defined USB HID reports size.
Table 2.5: USB HID frame
2.4.2
HID Communication Flow
The communication flow between host and mote does not differ between the serial and the USB protocol after the initial USB handshake. The same messages are exchanged between mote and host, just frame header and end differ between serial and USB based communication.
2.5 2.5.1
Serial/USB frame payload specification READY
The READY message does not contain any payload and is sent from a mote to the host to signal the mote is ready to receive data.
10
2.5.2
BUSY
The BUSY message does not contain any payload and is sent from a mote to the host to signal that the mote has accepted a LIP message targeting system or application and that it will not accept any further message until it is ready again after the message was handled.
2.5.3
RESET
The following table specifies the payload a mote sends to the host after a reset and system startup time. Type
Field
Description
u1 u1 eui
VERSION MAXPDU EUI64
Version of LIP: 0x2. Maximum PDU size supported by this mote. Unique id of this mote.
If the host sends a RESET message to the mote, it does not contain any payload data and the host requests the mote to reset.
2.5.4
INFO
The following table specifies the payload a mote sends to the host for an INFO message. Type
Field
Description
u1 u1 eui
VERSION MAXPDU EUI64
Version of LIP: 0x2. Maximum PDU size supported by this mote. Unique id of this mote.
If the host sends an INFO message, it does not contain any payload data and the host requests the mote to answer with an INFO message.
2.5.5
DATA
The following table specifies the payload of a DATA message which is exchanged between host and mote for application-specific purposes. When sent to a mote, the content of the DATA message is forwarded to the registered handler of the target port. Type
Field
Description
u4 u2 u1 u1[N]
HOSTADDR HOSTPORT MOTEPORT PAYLOAD
Host address. Host port. Target/source port on mote. N-bytes, application-specific payload.
11
2.5.6
LOG
The following table specifies the payload of a log message sent from the mote to the host. Type
NAME
u1
CTRL
u1 u1[N]
ERR TXT
Description LOG ALL LOG DEBUG LOG INFO LOG WARN LOG ERROR LOG NONE LOG MOTE LOG ASRT Error code. Log message:
12
0x00 0x01 0x02 0x03 0x04 0x07 0x40 0x20
Log level control only. Log severity. Log severity. Log severity. Log severity. Log level control only. Message from OS. Assertion failure on mote.
ASCII character sequence of N bytes.
Chapter 3
WLIP 3.1
Introduction
The WLIP protocol is a basic wireless protocol to exchange LIP messages (as specified in Table 1.1) between a host and a set of wireless motes. It is the default protocol used by wireless IBM Mote Runner motes if no pysical connection is available. When a mote boots, it first checks for a serial or USB connection. If none is found, it continues to boot in wireless mode. During initialization, the system calls the static initializers of all installed applications. If no application acquires the radio, the system initializes the WLIP framework. Radio messages are sent out to detect a WLIP gateway in reach. If a gateway responds, the mote attaches to this WLIP network. LIP messages can now be sent from the host to the mote, in both unicast as well as broadcast mode. On-mote applications may send messages to the gateway and host whenever they are active. The WLIP protocol forms a network in star topology with the gateway and host as central hub. Radio messages are encapsulated according to the standard IEEE 802.15.4 format ( [1]). Message transmission uses non-beacon mode with CSMA/CA ( [1]). The WLIP configuration parameters such as channel, PAN id reside in the firmware of the mote. They can be altered using a MOMA protocol and are then active after a mote reset (see Section 4.2.4. The IBM Mote Runner OS implementation of the WLIP protocol keeps the radio fully powered at all times as the WLIP protocol does not foresee any special power saving mechanisms. WLIP is mainly used for mote maintenance, more sophisticated protocols are implemented by libraries or applications. The WLIP protocol only allows for one gateway per channel. A WLIP gateway is expected to search for an existing WLIP network at startup. If an existing gateway is found, the gateway is expected to abort its operation. A WLIP gateway can send out messages in both unicast and broadcast mode. Unicast messages received by a IBM Mote Runner mote are ackknowledged (using the default radio behaviour of the IBM Mote Runner OS), whereas broadcast messages are not. If no ackknowledgement is received for a data transfer, a WLIP gateway retransmits the message up to a
13
configurable number of times. Error recovery is still a matter of the application protocols as described in Section 1.
3.2 3.2.1
WLIP Gateway Assembly
The IBM Mote Runner SDK uses a wired IBM Mote Runner mote to act as WLIP gateway and tunnel messages between host and wireless motes. The gateway functionality is implemented in a seperate application, the ’wlip-gateway’ assembly, and is downloaded and installed using the regular MOMA load mechanism. After the installation, the gateway assembly registers a port on the mote (by default 64) on which it accepts incoming LIP messages from the host. The ’wlip-gateway’ application then provides the following functionality: • control interface: the host can attach to and detach from the gateway, start and stop the radio, and configure the persistent settings of the gateway, e.g. the channel to use. • transmission interface: the host can send a message to a single mote addressed by its unique id or broadcast messages to all reachable motes. • query interface: the host can ask the gateway to query WLIP motes in range and then determine the appeared and disappeared motes since the last query. • gateway notifications: the gateway application notifies the host about LIP messages received from wireless motes, transmission failures, newly appeared motes.
3.2.2
Protocol
The host and the gateway application exchange LIP messages where the message header conforms to the layout specified in the Table 3.1. The format of the payload depends on the WLIP command field. Additionally, the command field signals whether this message is a reply to a command and whether this reply reports an error for a previously received command. If response and error bit are set, the message signals a failed command, and the byte following the CMD byte is one of the error codes listed in Table 3.2. In case of a command or a reply without error, the payload depends on the type of the command. Table 3.3 lists the commands exchanged between host, gateway and mote. While the messages exchanged between host and gateway are LIP messages encapsulated in serial and USB frames, the messages exchanged between gateway and wireless motes are encapsulated in MAC frames (see Section 3.3). The protocol-specific payload data is still the same and is fully listed in the next section. The following shortly discusses the relationship between the most important WLIP gateway commands. 14
Offset Type
Tag
Description
0 4 6
u4 u2 u1
HOST ADDR HOST PORT GW PORT
7
u1
CMD
8
u1 ERRCODE u1[n] PAYLOAD
Host address, representing the host. Host port, representing the source/target port. Allocated gateway port, by default 64. Tag Bits Description WLIP CMD 0..5 Command type of message. REPLY ERR 6 If set, error reply. REPLY OK 7 If set, reply. Error code if message is an error reply. Payload, size depends on WLIP CMD.
Table 3.1: WLIP gateway message format Tag WLIP WLIP WLIP WLIP WLIP
ERR ERR ERR ERR ERR
BADCMDLEN UNKNOWNCMD RADIOBUSY EXCEPTION G2ERR
Value
Description
0x01 0x02 0x03 0x04 0x05
Illegal command length. Unknown command. Cannot acquire radio. Unhandled exception. Another gateway detected.
Table 3.2: WLIP gateway error codes WLIP CMD *
Value
Direction
Description
FORWARD HELLO BYE CONFIG DETACHED TXFAIL APPEAL BROADCAST STOPRADIO STARTRADIO
0x4 0x5 0x6 0x7 0x8 0x9 0x10 0x11 0x13 0x12
H<>G<>M H<>G M H<>G>>M H>>G>>M H>>G M H>>G M
Forward from/to radio mote. Hello from radio to gateway (no data). Bye from radio to gateway (no data). Update/retrieve persistent config settings. Host got detached. Unicast/broadcast transmission failure. Ask motes to send a HELLO. Broadcast message to all motes. Stop using radio. Try to acquire radio.
Table 3.3: WLIP commands between host(H), gateway(G) and mote(M) • WLIP CMD FORWARD: the message contains mote unique id, destination port, source port and data. The data is a LIP message either sent by the host to a wireless mote or by a wireless mote to the host. If the host receives such a message, it contains the unique id of the wireless source mote, the target host port and the mote source port. If the gateway receives such a message, it contains the unique id of the wireless target mote, the target mote port and the host source port. • WLIP CMD HELLO,WLIP CMD BYE: these messages signal the appearance or disappearance of a wireless mote. When a wireless mote boots up, it sends HELLO 15
messages until it receives an ackknowledgement by a WLIP gateway. When the WLIP is shutdown on a mote (as for instance another application takes over the radio), a WLIP CMD BYE message is sent. • WLIP CMD CONFIG: this message modifies the persistent settings of the gateway application, e.g. the PAN id and channel to use. Additonally, the number of retransmissions to perform when a wireless mote does not acknowledge a request. • WLIP CMD APPEAL: the host asks the gateway to query the current WLIP motes in the network. The gateway broadcasts a WLIP CMD APPEAL message to which all reachable WLIP motes reply with a WLIP CMD HELLO message. Note that the APPEAL message carries a sequence number which all wireless motes have to repeat in their response.
3.2.3
Commands
WLIP CMD STARTRADIO/STOPRADIO/ATTACH/DETACH These commands and their confirmation replies take no additional payload data. Both commands as well as error reponses follow the formats described in Table 3.1 and Table 3.2. WLIP CMD CONFIG Without parameter data, the WLIP CMD CONFIG retrieves the current configuration of the wlip gateway. If data is given, is describes the new configuration to save and must be of the same layout as follows. Offset
Type
Tag
Description
0 2 3 4
u2 u1 u1 u2
PAN id CHANNEL TXRETRIES TXBUFSZ
PAN id. Channel. Number of retransmissions to try. Size of message buffer cache in bytes.
WLIP CMD FORWARD The following table specifies the payload for the WLIP CMD FORWARD command sent from host to gateway as well as from gateway to host. Note that the ’wlip-gateway’ application buffers messages to be forwarded and broadcasted and reports transmission errors by a WLIP CMD TXFAIL messages at a later time. Error recovery on the host side should follow the previously described pattern (see Section 1).
16
Offset
Type
Tag
Description
0 8 11 12
eui pad3 u1 u1[n]
ADDR PAD PORT PAYLOAD
Source/destination unique id of mote. Padding. Source or destination mote. Payload of message.
WLIP CMD BROADCAST The WLIP CMD BROADCAST shares the layout with WLIP CMD FORWARD, but is only sent from the host to the gateway and not vice versa. Additionally, the ADDR part of the message is set to zero to indicate the broadcast address. Both WLIP CMD FORWARD and WLIP CMD BROADCAST lead to WLIP CMD TXFAIL messages at some point later if the transmission failed. WLIP CMD TXFAIL A WLIP CMD TXFAIL message notifies the host about a transmission error. The gateway replaces the command byte in the original FORWARD or BROADCAST message by the WLIP CMD TXFAIL command byte and sends the message to the host. WLIP CMD APPEAL The WLIP CMD APPEAL command carries a sequence number picked by the host. WLIP motes in range respond by WLIP CMD HELLO messages including this sequence number. Offset
Type
Tag
Description
0
u2
SEQNO
Sequence number picked by host.
WLIP CMD HELLO,WLIP CMD BYE The WLIP CMD HELLO and WLIP CMD BYE message encapsulate the unique id of the mote. The sequence number is only specified in case of WLIP CMD HELLO. Offset
Type
Tag
Description
0 8
eui u2
EUI64 SEQNO
Unique id of mote. WLIP CMD HELLO: appeal sequence number or zero.
17
3.3
WLIP Radio
Table 3.3 presented the types of the messages exchanged between gateway application and wireless motes. These messages are encapsulated in 802.15.4 radio MAC frames (see [6] for the 802.15.4 standard). The WLIP implementation on the Mote Runner OS assumes certain behaviour of the underlying radio interface which is described in the radio API specification ( [2]). Most importantly, WLIP exploits the following properties: • 64-bit extended addressing: WLIP messages partly carry the 64-bit unique id of a mote (EUI-64) as source or destination addresss. • ACKRQ: unicast messages sent by WLIP are expected to be ackknowledged. If no ackknowledgement occurs, messages are retransmitted up to a configurable limit.
3.3.1
WLIP CMD FORWARD
Table 3.4 specifies the format of radio messages which forward LIP messages between gateway and wireless motes in both directions. The WLIP command field type WLIP CMD FORWARD is encoded in the standard sequence number field of an 802.15.4 radio message. The LIP message data (see Table 1.1) can be found starting with offset 13. Offset
Type
Tag
Description
0 2 3 5 13 17 19 20 20+N
u2 u1 u2 eui u4 u2 u1 u1[N] u1
FCF CMD PANID XADDR HADDR HPORT MPORT DATA FCS
Frame control field, see Table 3.5. WLIP command type, see Table 3.1. PAN id, as configured persistently for the mote. 8-byte extended destination/source address. Host address, see Table 1.1. Host port, see Table 1.1. Mote port, see Table 1.1. Data, variable length. Frame check sequence, as specified for 802.15.4.
Table 3.4: WLIP unicast MAC frame encapsulating LIP messages Table 3.5 details the frame control fields sent in WLIP radio messages. In case of a unicast message, the ACK bit is set to receive acknowledgements from the destination mote. If no ackknowledgements are received, the gateway and the wireless mote retransmit the message until the configured limit. When forwarding a message, the gateway sets the unique id of the target address as destination address in the message. When sending a message to the gateway, a wireless mote sets its unqique id as source address in the message.
18
Bits
Value
0..2 3 4 5 6 10..11
1 0 0 0 0 00b/11b
14..15
Description
Frame type: Data. Security Enabled: Disabled. Frame pending: Ignored. ACK. request: Enabled. Compressed PAN Id: Set, no source PAN id included. Destination Addressing Mode: Set to 11b if message is a WLIP CMD FORWARD from gateway. 00b/11b Source Addressing Mode: Set to 11b if message from wireless mote.
Table 3.5: WLIP frame control field
3.3.2
WLIP CMD HELLO,WLIP CMD BYE
When starting up and sending a WLIP CMD HELLO message to a gateway, the mote embeds its EUI-64 as source address in the message. The WLIP CMD HELLO message carries a two bytes payload, a sequence number. This is either the value received from a previous WLIP CMD APPEAL message or zero (when starting up). A WLIP CMD BYE message carries no payload. A wireless mote expects this message to be ackknowledged, too, but does not undertake retransmissions of WLIP CMD BYE messages. Offset
Type
Tag
Description
0 2 3 5 13 15
u2 u1 u2 eui u2 u1
FCF CMD PANID XADDR DATA FCS
Frame control field, see Table 3.5. WLIP command type, see Table 3.1. PAN id, as configured persistently for the mote. 8-byte extended source address. WLIP CMD HELLO: sequence number or zero. Frame check sequence, as specified for 802.15.4.
When a mote received an 802.15.4 ackknowledgement frame for a WLIP CMD HELLO message after startup, the mote assumes to be connected to a WLIP gateway. It starts to listen for unicast messages with its destination address (its unique id) and for broadcast messages. Otherwise, the radio is shutdown.
3.3.3
WLIP CMD BROADCAST
The WLIP CMD BROADCAST message is broadcasted by the gateway to the wireless motes and contains a LIP message. Host address, port, mote port and payload can be found at the same offsets as in case of WLIP CMD FORWARD simplifying the handling of LIP messages on the mote.
19
Offset
Type
Tag
Description
0 2 3 5 7 13 17 19 20 20+N
u2 u1 u2 u2 u1[6] u4 u2 u1 u1[N] u1
FCF CMD PANID BCADDR PAD HADDR HPORT MPORT DATA FCS
Frame control field, see Table 3.5. WLIP command type, see Table 3.1. PAN id, as configured persistently for the mote. Broadcast address: 0xFFFF. Unused. Host address, see Table 1.1. Host port, see Table 1.1. Mote port, see Table 1.1. Data, variable length. Frame check sequence, as specified for 802.15.4.
3.3.4
WLIP CMD APPEAL
The WLIP CMD APPEAL message is also broadcasted by the gateway and contains two bytes data, a sequence number. WLIP CMD APPEAL expects the WLIP CMD HELLO messages from wireless motes in return to carry the specified sequence number. Offset
Type
Tag
Description
0 2 3 5 7 9
u2 u1 u2 u2 u2 u1
FCF CMD PANID BCADDR SEQNO FCS
Frame control field, see Table 3.5. WLIP command type, see Table 3.1. PAN id, as configured persistently for the mote. Broadcast address: 0xFFFF. Sequence number. Frame check sequence, as specified for 802.15.4.
20
Chapter 4
MOMA 4.1
Overview
The mote manager (MOMA) protocols are implemented by the IBM Mote Runner system framework and consist of a set of LIP message based protocols (exchanged over LIP or WLIP) to manage properties and resources of a mote: • The assemblies load, list and delete protocols load, list and delete assemblies on a mote. • The reset and factoryreset protocols reset a mote and its flash contents to factory state. • The mote unique id can be retrieved or modified. • WLIP configuration can be retrieved or modified. • Resource information and statistics can be retrieved. All MOMA operations adhere to the following basic rules: • All but the load protocol are stateless. The load protocol provides means to query and reset the state of the loader in case a previous load operation has failed. • All MOMA LIP messages are sent to the MOMA port of the mote which is by default zero. • All MOMA messages start with the LIP message header followed by a MOMA command byte specifying a MOMA operation. Dependent on the MOMA command byte, the MOMA message contains additional payload data.
21
Type
Field
Description
u4 u2 u1 u1 u1[n]
HOSTADDR HOSTPORT MOTEPORT COMMAND PAYLOAD
Host address. Host port. Target/source port on mote. MOMA command field. MOMA-command-specific payload.
• The MOMA command field has the following structure: Bit
Tag
Description
0..5 6 7
MOMA CMD REPLY ERR REPLY OK
MOMA command type in message ( Table 4.1). Error reply if bit 6 and 7 are set. Reply if bit 7 is set.
The mote manager sends back a reply to all unicast messages it receives (exceptions are MOMA RESET CMD and MOMA FACTORYRESET CMD). It contains the incoming command byte with the reply bit set. In case of failure, the error bit is set, too, and an error code byte follows the command byte in the message. Dependent on the error, additional information might be stored in the response. The following list enumerates the standard MOMA commands implemented by the Mote Runner OS implementations. If an incoming command is not understood by the OS, it is ignored. MOMA *
Value
Description
LOADSTART CMD LOADSTOP CMD LOADDATA CMD LOADSTATUS CMD LISTASMS CMD DELASM CMD FACTORYRST CMD RESET CMD QUERYINFO CMD EUI64 CMD WLIPCONFIG CMD
10 11 12 14 3 5 6 9 7 13 13
Start assembly loading process. Stop current load process. Subsequent messages for loading process. Return status of loader. List assemblies installed on mote. Delete assembly installed on mote. Reset mote state to factory state. Reset mote. Query mote resources. Get/set the unique mote id in EUI-64 format. Retrieve or set WLIP settings.
Table 4.1: MOMA commands
4.2 4.2.1
Basic Commands MOMA RESET CMD
The MOMA RESET CMD command resets a mote. In case of LIP, the mote restarts and reconnects on the serial line or USB interface. In case of WLIP, the mote restarts
22
and if no installed assembly acquires the radio, the mote reconnects to the WLIP network. No reply to the MOMA RESET CMD is sent. Offset Tag
Value Description
0
9
4.2.2
RESET CMD
Reset mote.
MOMA FACTORYRST CMD
The MOMA FACTORYRST CMD behaves as the MOMA RESET CMD, but additionally resets the persistent state of the mote to the factory state, e.g. all installed assemblies are deleted. Offset Tag
Value Description
0
6
4.2.3
FACTORYRST CMD
Factory-reset mote.
MOMA EUI64 CMD
If the MOMA EUI64 CMD message sent from host to mote carries an EUI-64 vector, the unique id of the mote is updated and the mote sends back a reply without data. If the incoming command contains no unique id, the current unique id of the mote is sent back in the reply. If the incoming message has an invalid length, the message is ignored. Offset Type Tag
Description
0 1
Set/get the mote id; if bit 7 is set, reply. EUI-64, unique mote id.
4.2.4
u1 eui
EUI64 CMD EUI64
MOMA WLIPCONFIG CMD
If the MOMA WLIPCONFIG CMD message specifies WLIP config parameters, the persistent parameters of the mote are updated. Otherwise, the current settings are returned in the reply. If the incoming message has an invalid length, the message is ignored. Offset Type Tag
Description
0 1 3 4
Set/get configuration; if bit 7 is set, reply. PAN id. Channel. Number of retransmissions in case of errors.
u1 u2 u1 u1
CONFIG CMD PAN id CHANNEL TXRETRIES
23
4.2.5
MOMA QUERYINFO CMD
The MOMA QUERYINFO CMD message retrieves resource information from the mote. The input vector specifies the resources the response should provide information for. The size of the input vector is the size of the output vector. If the incoming message has an invalid length, the message is ignored. If an invalid resource is referenced, the value at that index in the output vector is unspecified. Offset Type Tag
Description
0 1 3 ..
Get resource usage; if bit 7 is set, command reply. Resource identifier (request), resource value (reply). Resource identifier (request), resource value (reply). Resource identifier (request), resource value (reply).
u1 u2 u2 u2
QUERYINFO CMD RES RES RES
The following table specifies the values for the resource identifiers: Type Tag
Value Description
u2 u2 u2 u2 u2 u2 u2 u2 u2
0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9
4.3 4.3.1
HEAPSZ HEAPFREE HEAPUNIT STACKSIZE STACKFREE FWVERSION FWBUILD PLATFORM BATTERY STATUS
Total heap size. Free heap size. Unit size in heap. Total size of stack. Free size remaining of stack. Firmware major and minor version. Build number of firmware. Platform identifier. Battery status.
Assembly Commands MOMA LISTASMS CMD
The MOMA LISTASMS CMD command retrieves a part of the listing of the assemblies installed on a mote. The command carries the id of the assembly with which the response should start. When passing in zero, the response starts with the first assembly installed (the system assembly). An addional, optional parameter may specify the number of listing entries to retrieve, otherwise the maximum number of entries to fit in the response is returned. The response contains for each listed assembly an entry with assembly id, major version, minor version, build number and assembly name (see [3] for assembly name specification). The entries are ordered
24
according to their assembly id. Offset
Type
Tag
Description
0 1 2
u1 u1 u1
LISTASMS CMD ID NUM
Get assembly information entries. Assembly id to start with or zero (..63). Optional, return NUM entries.
The format of a successful reply is: Offset
Type
Tag
Description
0 1 2 3 4 6 7 1+5+LEN ...
u1 u1 u1 u1 u1 u1 u1[LEN] u1 ...
LISTASMS CMD ID MAJ MIN BUILD LEN NAME ID ...
List assemblies response, bit 7 is set. Assembly id (0..63). Assembly major version. Assembly minor version. Build number. Length in bytes of following assembly name. LEN-bytes, assembly name. Assembly id of next entry. ...
4.3.2
MOMA DELASM CMD
The MOMA DELASM CMD command deletes an installed assembly or tests whether an assembly is installed and can be successfully deleted. Offset Type Tag
Description
0
u1
DELASM CMD
1
u1
PARA
Delete assembly command. Tag Bits Description ID 0..5 Id of assembly. TEST 7 If set, test for deletion.
If the assembly id is invalid, the following error is returned: Offset Type Tag
Description
0 1 2
0xC5 Delete assembly error reply. Id of target assembly. Error code: illegal assembly id.
u1 u1 u1
DELASM CMD ID CODE
If other assemblies depend on the assembly to delete, the following error is returned:
25
Offset Type Tag
Description
0 1 2
0xC5 Delete assembly error reply. Id of target assembly. N ids of assemblies which depend on target.
u1 DELASM CMD u1 ID u1[N] IDS
On success, the following reply is returned. If the ’test’ bit was set, it indicates that the assembly can be deleted with another MOMA DELASM CMD command. Offset Type Tag
Description
0 1
0x85 Delete assembly reply. Id of target assembly.
4.4
u1 u1
DELASM CMD ID
Load Commands
An assembly load operation starts with a MOMA LOADSTART CMD message. It carries loader version, initial sequence number and expected size information. If the system loader can be initialized and no error is returned, the subsequent MOMA LOADDATA CMD messages feed in the binary representation of the assembly chunk by chunk together with a linearly increasing sequence number. The loader on the mote responds to each chunk with the sequence number and a flag indicating whether more data is required, the assembly was installed or an error occured. The MOMA LOADSTART CMD and MOMA LOADDATA CMD commands may return error replies where the error codes are listed in Table 4.2. Dependent on the error code, the error message contains additional information, these error-specific details are also listed in the table. The MOMA LOADSTATUS CMD command queries whether a load operation is still in progress, the MOMA LOADSTOP CMD command aborts a load operation currently in progress. As stated before, the mote manager does not respond to broadcast messages. Thus, a broadcast based loader may load an assembly in parallel on a number of connected wireless motes by feeding chunks using MOMA LOADDATA CMD broadcast messages. Finally, the loader uses the MOMA LOADSTATUS CMD command to find out about successful and failed assembly installations.
4.4.1
MOMA LOADSTART CMD
The MOMA LOADSTART CMD message initiates a load operation. The initial sequence number can be freely choosen by the host. CIMGSZ and PIMGSZ - if not zero - specify the size of the code and persistent heap size to be allocated for the assembly which may optimize the memory usage and prevent fragmentation on the mote.
26
Value
LDSC <*>
Description
0x10
WRONG VERSION
0x11 0x12 0x13
BAD MESSAGE INVALID MAGIC INVALID MAJOR
0x14
INVALID MINOR
0x15 0x16
ASM EXISTS MISSING DEP
0x17 0x18
OUT OF MEMORY BAD FORMAT
0x19 0x1A
ASM CTOR FAILED BAD SEQNO
0x1B 0x1C 0x1D
ENGINE FAILURE COMMIT FAILED LOAD IN PROGRESS
Load protocol version not supported by loader. u1 Supported version. Message has wrong format. Load file does not carry correct magic. Load file has wrong major version number. u1 Supported major version. Load file has wrong minor version number. u1 supported minor version. Assembly already exists. Missing dependency. u1 Index into imports table naming assembly. Not enough memory to store assembly. Bad load file format. LDSC <*> u2 INVALID DEPENDS CNT 0x0100 INVALID CLASSES CNT 0x0200 INVALID METHODS CNT 0x0300 INVALID IFS CNT 0x0400 INVALID ASM NAME 0x0500 INVALID LINKREF 0x0600 INVALID IFREF 0x0700 INVALID ALIGNMENT 0x0800 INVALID CODE SIZE 0x0900 INVALID VSLOT 0x0A00 INVALID FIELDSLOT 0x0B00 INVALID BYTECODE 0x0C00 Assembly constructor failed. Message with wrong sequence number. u2 Expected sequence number. Loader engine failed for unknown reason. Transactional commit failed. Load is already in progress. u2 Expected sequence number.
Table 4.2: LDSC <*> error codes Offset Type Tag
Description
0 1 2 4 6
Start of assembly load. Expected loader version: 0x02. Initial sequence number. Image cabin size. Persistent heap size.
u1 u1 u1 u2 u2
LOADSTART CMD VERSION SEQNO CIMGSZ PIMGSZ
Success of the command is reported back by following reply.
27
Offset Type Tag
Description
0
0x8A Reply to start of assembly load.
u1
LOADSTART CMD
An error is reported back by following reply. Offset Type Tag 0 1 2
4.4.2
u1 u1 u1
Description
LOADSTART CMD CODE DETAILS
0xCA Error reply to start of assembly load. WRONG PROTO VERSION/LOAD IN PROGRESS. See Table 4.2.
MOMA LOADDATA CMD
MOMA LOADDATA CMD messages feed in the binary assembly file. The size of the payload should be picked close to the maximum possible PDU size to reduce the number of required messages. The sequence number ensures the correct ordering of the downloaded chunks. Offset Type Tag
Description
0 1 2
0xC Load data command. Sequence number. N bytes of the binary assembly.
u1 LOADDATA CMD u2 SEQNO u1[N] DATA
The following table describes the reply received on a MOMA LOADDATA CMD message. Offset Type Tag
Description
0 1 3 4
0x8C/0xCC: Reply to load data command. Sequence number. Loader state (see below). State details.
u1 u2 u1 u1
LOADDATA CMD SEQNO STATE DETAILS
If the loader returned an error, the STATE and DETAILS fields contain error values as specified in the Table 4.2. If the response signaled no error, the STATE field contains one of the follwing values. LDSC <*> MORE DATA DATA DONE ASM CTOR DONE
Value 0x01 0x00 0x02
Description Loader needs more data from the binary assembly. Load finished successfully. Load finished successfully, constructor has been executed.
28
4.4.3
MOMA LOADSTATUS CMD
The MOMA LOADSTATUS CMD message queries the loader state. Offset Type Tag
Description
0
Load status command.
u1
LOADSTATUS CMD
The reply to the MOMA LOADSTATUS CMD message signaling success looks as follows: Offset Type Tag
Description
0 1 2
0x8E Response to load status command. LDSC DATA DONE/LDSC LOAD IN PROGRESS. Sequence number if LDSC LOAD IN PROGRESS.
4.4.4
u1 u1 u2
LOADSTATUS CMD STATE SEQNO
MOMA LOADSTOP CMD
The MOMA LOADSTATUS CMD message aborts a load process. Offset Type Tag
Description
0
Load stop command.
u1
LOADSTOP CMD
29
Appendix A
USB HID descriptors Name
Value
USB USB USB USB USB USB USB USB HID HID HID HID HID HID HID HID
0x01 0x02 0x03 0x04 0x21 0x22 0x03 0x05 32 1 2 3 4 0x00 0x04B3 0x4046
DEVICE DESC CONFIG DESC CLASS HID INTFCE DESC HID DESC REPORT DESC TYPE INT ENDPNT DESC REPORT SMALL SZ REPORT SMALL IN ID REPORT SMALL OUT ID REPORT FULL IN ID REPORT FULL OUT ID VERSION VENDOR ID IBM PRODUCT ID MOTE RUNNER
Table A.1: USB HID client descriptor constants
30
Offset
Value
Description
0 1 2 4 5 6 7 8 10 12 14 15 16 17
0x12 USB DEVICE DESC 0x00, 0x02 0x00 0x00 0x00 64 0xB3, 0x04 0x46, 0x40 0x00, 0x01 0x00 0x00 0x01 0x01
Length. Type. USB 2.0 Class defined at interface level. No subclass. No device protocol. EP0: 64 bytes. Vendor: IBM Corp. Product ID: 4046. Device version: 1.0. Manufacturer string. Product string. Serial number string. Number of configurations.
Table A.2: USB HID client device descriptor
31
Offset
Value
Description
0 1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 23 24 25 27 28 29 30 31 33
0x09 USB CONFIG DESC 0x00, 0x22 0x01 0x01 0x00 0x80 50 0x09 USB INTFCE DESC 0x00 0x00 0x01 USB CLASS HID 0x00 0x00 0x00 0x09 USB HID DESC 0x11, 0x01 0x00 0x01 USB REPORT DESC 0x00, 0x3f 0x07 USB ENDPNT DESC 0x81 USB TYPE INT 64, 0x00 2
Length. Type. Total length. Number of interfaces. Configuration value. Configuration string. Attributes: bus-poered, no remote-wakeup. Maximum power: 100mA. Length. Type. Interface number. Alternate setting. Number of endpoints. Interface class. No subclass. No protocol. Interface string. Length. Type. HID version: 1.1.1 No country code. Number of additional descriptors. Type of descriptor[0]. Size of descriptor[0]. Length. Type. Address: 1 IN. Attributes Maximum packet size. Polling interval: 2 frames (=2ms).
Table A.3: USB HID client config descriptor
32
Offset
Value
Description
0 3 5
0x06, 0x00, 0xff 0x09, 0x01 0xa1, 0x01 Report ID 1/IN 0x09, 0x01 0x85, HID REPORT SMALL IN ID 0x25, 0x7f 0x15, 0x80 0x95, HID REPORT SMALL SZ 0x75, 0x08 0x81, 0x00 Report ID 2/OUT 0x09, 0x01 0x85, HID REPORT SMALL OUT ID 0x25, 0x7f 0x15, 0x80 0x95, HID REPORT SMALL SZ 0x75, 0x08 0x91, 0x00 Report ID 3/IN 0x09, 0x01 0x85, HID REPORT FULL IN ID 0x25, 0x7f 0x15, 0x80 0x95, IOBUF PAYLOAD SIZE 0x75, 0x08 0x81, 0x00 Report ID 4/OUT 0x09, 0x01 0x85, HID REPORT FULL OUT ID 0x25, 0x7f 0x15, 0x80 0x95, IOBUF PAYLOAD SIZE 0x75, 0x08 0x91, 0x00 0xc0
USAGE PAGE (Vendor Defined Page 1) USAGE (Vendor Usage 1) COLLECTION (Application)
7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 51 53 55 57 59 61 63 65
Table A.4: USB HID client report descriptor
33
USAGE (Vendor Usage 1) REPORT ID LOGICAL MAXIMUM (127) LOGICAL MINIMUM (-128) REPORT COUNT (REPORT SZ) REPORT SIZE (8) INPUT (Data,Ary,Abs) USAGE (Vendor Usage 1) REPORT ID LOGICAL MAXIMUM (127) LOGICAL MINIMUM (-128) REPORT COUNT (REPORT SZ) REPORT SIZE (8) OUTPUT (Data,Ary,Abs) USAGE (Vendor Usage 1) REPORT ID LOGICAL MAXIMUM (127) LOGICAL MINIMUM (-128) REPORT COUNT (REPORT SZ) REPORT SIZE (8) INPUT (Data,Ary,Abs) USAGE (Vendor Usage 1) REPORT ID LOGICAL MAXIMUM (127) LOGICAL MINIMUM (-128) REPORT COUNT (REPORT SZ) REPORT SIZE (8) OUTPUT (Data,Ary,Abs) END COLLECTION
Bibliography [1] Compaq Computer Corporation, Hewlett-Packard Company, Intel Corporation, Lucent Technologies Inc., Microsoft Corporation, NEC Corporation, and Koninklijke Philips Electronics N.V. Universal serial bus specification (revision 2.0). http://www.usb.org/developers/docs/usb 20 05122006.zip, 2000. [2] IBM. Inside ibm mote runner, volume 1: Apis. [3] IBM. Inside ibm mote runner, volume 2: Byte code, load-file format, and intermediate language. [4] IEEE. Eui-64 guidelines. http://standards.ieee.org/develop/regauth/ tut/eui64.pdf. [5] A. McKenzie. ISO Transport Protocol specification ISO DP 8073. RFC 905, April 1984. [6] I. C. Society. IEEE Standard for Information Technology – Telecommunications and Information Exchange Between Systems – Local and Metropolitan Area Networks – Specific Requirements – Part 15.4: Wireless Medium Access Control (MAC) and Physical Layer (PHY) Specifications for Low Rate Wireless Personal Area Networks (LR-WPANs). IEEE 802.15.4-2006, Sept. 2006.
34
INSIDE IBM MOTE RUNNER Volume 4: An introduction in the programming model, language specific features and an exhaustive API documentation.
IBM Zurich Research Laboratory, Switzerland v1.0 - August 19, 2011
Abstract Copyright (C) IBM Corp. All rights reserved. Even though IBM has reviewed this manual, IBM MAKES NO WARRANTY OR REPRESENTATION, EITHER EXPRESS OR IMPLIED, WITH RESPECT TO THIS MANUAL, ITS QUALITY, ACCURACY, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. AS A RESULT, THIS MANUAL IS PROVIDED “AS IS,” AND YOU, THE READER, ARE ASSUMING THE ENTIRE RISK AS TO ITS QUALITY AND ACCURACY. IN NO EVENT WILL IBM BE LIABLE FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES RESULTING FROM ANY DEFECT OR INACCURACY IN THIS MANUAL, even if advised of the possibility of such damages
Contents 1 Introduction 1.1 IBM Mote Runner . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.1 Key Features . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Structure of this Document . . . . . . . . . . . . . . . . . . . . . .
2 2 3 3
2 Programming Model: Reactive Programming
4
3 Language Specific: C# / Java Programming for Mote Runner 3.1 Features not Supported . . . . . . . . . . . . . . . . . . . . . 3.2 Size of Integer Types . . . . . . . . . . . . . . . . . . . . . . 3.3 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4 Class Initializers . . . . . . . . . . . . . . . . . . . . . . . . . 3.5 Data Initializers and Immutable Objects . . . . . . . . . . . . 3.6 String Initializers . . . . . . . . . . . . . . . . . . . . . . . . . 3.7 Delegates . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.8 Getters/Setters . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
6 7 8 8 9 10 11 11 13
4 Reference Documentation 4.1 namespace com.ibm.saguaro.system . . . . . 4.1.1 public class WLIP . . . . . . . . . . 4.1.2 public sealed class Util . . . . . . . . 4.1.3 sealed public delegate TimerEvent . . 4.1.4 public class Timer . . . . . . . . . . 4.1.5 public class Time . . . . . . . . . . . 4.1.6 sealed public delegate SystemInfo . . 4.1.7 public class SystemException . . . . 4.1.8 public class SimpleDevices . . . . . . 4.1.9 sealed public delegate RadioTxDone . 4.1.10 sealed public delegate RadioRxPdu . 4.1.11 sealed public delegate RadioDone . . 4.1.12 public abstract class Radio . . . . . . 4.1.13 public class OutOfResourcesException 4.1.14 public class NullReferenceException . 4.1.15 public class MoteException . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
14 14 14 17 27 28 30 33 34 36 41 42 43 44 62 63 64
1
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
4.1.16 4.1.17 4.1.18 4.1.19 4.1.20 4.1.21 4.1.22 4.1.23 4.1.24 4.1.25 4.1.26 4.1.27
public class Mote . . . . . . . . . . . . . public sealed class LIP . . . . . . . . . . public class LED . . . . . . . . . . . . . public class InvalidCastException . . . . public class IndexOutOfRangeException . public sealed class Err . . . . . . . . . . sealed public delegate DataHandler . . . public sealed class Assembly . . . . . . . public class ArrayTypeMismatchException public class ArithmException . . . . . . . public class ArgumentException . . . . . public class AccessException . . . . . . .
5 Baseterms 5.1 byte . . . . . . . . . . . . 5.2 byte[] . . . . . . . . . . . . 5.3 sbyte . . . . . . . . . . . . 5.4 sbyte[] . . . . . . . . . . . 5.5 int . . . . . . . . . . . . . 5.6 int[] . . . . . . . . . . . . 5.7 uint . . . . . . . . . . . . . 5.8 uint[] . . . . . . . . . . . . 5.9 long . . . . . . . . . . . . 5.10 long[] . . . . . . . . . . . . 5.11 object[] . . . . . . . . . . . 5.12 object . . . . . . . . . . . 5.13 namespace . . . . . . . . . 5.14 class . . . . . . . . . . . . 5.15 delegate . . . . . . . . . . 5.16 Final Modifier . . . . . . . 5.17 Sealed Modifier . . . . . . 5.18 Const Modifier . . . . . . . 5.19 Readonly Modifier . . . . . 5.20 Static Modifier . . . . . . . 5.21 Abstract Modifier . . . . . 5.22 Modifiers . . . . . . . . . . 5.23 Public Access Specifier . . 5.24 Protected Access Specifier 5.25 Private Access Specifier . . 5.26 Internal Access Specifier . . 5.27 Access Specifiers . . . . . . 5.28 Attributes/Annotations . . 5.29 NonVirtual . . . . . . . . . 5.30 Immutable . . . . . . . . . 5.31 Temporary Objects . . . . 5.32 Object Life Times . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
65 69 74 76 77 78 79 80 83 84 85 87
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
89 89 89 90 90 90 90 91 91 92 92 92 92 93 93 94 95 96 96 96 96 97 97 99 99 99 99 99 100 101 102 102 103
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Chapter 1
Introduction Inside IBM Mote Runner is a five-volume set that tells you what you need to know to write applications for sensor networks running IBM Mote Runner, to write drivers for sensors and actuators for IBM Mote Runner, to write your own development tools as add-ons to or replacements of the current tool chain of IBM Mote Runner, and to communicate with motes within a sensor network running IBM Mote Runner. It does not include information about programming in general, any hardwarespecific information, or fundamentals of sensor networks as such (e.g., networking protocols). It is further assumed that the reader is familiar with at least Java or C#, and has read Inside IBM Mote Runner, Volume 1: Overview. NOTE: IBM Mote Runner is under active development and currently in beta status. For the latest up-to-date information please refer to the HTML documentation provided as part of the IBM Mote Runner download.
1.1
IBM Mote Runner
IBM Mote Runner is a run-time platform and development environment for wireless sensor networks (WSN) currently under development at the IBM Zurich Research Laboratory, Switzerland. It consists of an on-mote environment, the so-called “firmware,” with some standard libraries, an off-mote environment (including an edge server facilitating communication between the WSN and the outside world, a command shell permitting high-level control of the WSN, and source-level debugger for refinement of the application code running inside the WSN), and a set of development tools such as a command-line compiler and graphical integrated development environment (IDE).
3
1.1.1
Key Features
Programming Languages: Hardware Requirements: Supported Motes: Programmable Middleware: Mote Simulation:
IDE: Web Front-End:
1.2
Java and C# (either/or/mixed) + optimizer 8K RAM, 64K Flash (8bit/16bit/32bit CPUs) IRIS Mote (Memsic), RZUSBSTICK (Atmel), AVRRAVEN (Atmel) Control, customization, setup, and testing of mote networks Debugging, testing, analysis of sensor networks including power consumption, sensor feeds, inspection, tracing Source level distributed debugging using Eclipse Integration of WSN applications with web-based front end
Structure of this Document
In chapter 2 the progamming paradigma of “Reactive Programming” is introduced in a nutshell. Chapter 3 sheds light on the adaptions on the well-known programming languages Java and C# to be better applicable in the context of ressource-restricted small systems (c.f. section 1.1.1).
4
Chapter 2
Programming Model: Reactive Programming Wireless sensors and embedded programming are inherently about reacting to external events in the most resource-efficient way. That is, embedded applications do not work self-directed but rather are notified whenever an event occurs that the application is interested in. The application then performs some typically short burst of processing in response, possibly changes its state, and possibly triggers operations that eventually may result in further events. So, conceptually there is a finite state machine underlying the code whose transitions are triggered by events. There are several approaches in existing systems to implement such applications. In a purely thread-based model each thread checks on some event and blocks until that event is fired. Supporting threads on small embedded systems has two drawbacks, though. The stack supplied with each thread needs to be large enough to run arbitrary user applications, or the virtual machine must provide a mechanism to dynamically resize a stack. So, either precious RAM space is wasted and badly utilized because threads are waiting for events most of the time, or the virtual machine gets bigger by implementing and managing a sophisticated stack growing and shrinking scheme. The virtual machine and operating system would have to provide an API and implementation for thread synchronization, thereby again increasing the footprint of the virtual machine. In addition, the application programmer is faced with synchronizing concurrency introduced by non-deterministic events. As a consequence, the IBM Mote Runner development philosophy avoids threads altogether and instead favor a purely reactive programming model. In such a model the application registers a method to be called whenever an event fires. This scheme requires one and only one virtual machine stack and no synchronization since only one event handler or callback is active at any point in time. It is further undemanding to implement and results in simple application code as long as the handling of events does not require lengthy processing. Lengthy processing must be split up into smaller functions, which are driven by a priority task list or by some timer event. In thread-based systems, such tasks would be assigned to a background thread.
5
To support a reactive programming scheme in an object-oriented language there are basically two possibilities. Firstly, the system API defines either an abstract class or interface, which must be implemented by applications and can be registered with the operating system for callback whenever a specific event occurs. This scheme is resource wasteful, as it requires an application to implement many different abstract classes and have as many instances, while these instances probably just forward the callback to an object that maintains the application state. When using interfaces the disadvantage is that calls introduce an additional level of indirection, which has to be resolved at run time by mapping interface methods to virtual methods. Secondly, the system allows a pointer to a method to be registered - an older concept, more recently re-introduced in object oriented languages by C#, where it is called a delegate. A delegate type describes the parameters and return values of the method and at run time holds a pointer to an object and a pointer to a method implementation. Delegates allow an application programmer to tie event callbacks directly to those object instances that hold the application state. We choose delegates for IBM Mote Runner, as they require only a small overhead in terms of memory and run-time execution when compared to the alternative approach.
6
Chapter 3
Language Specific: C# / Java Programming for Mote Runner Mote Runner applications can be programmed in either Java or C#. Mote Runner targets small embedded systems while Java and C# have been designed with normal PC or server hardware in mind. In order to make Java and C# work well for embedded systems Mote Runner requires a number of adaptations. The imposed restrictions and alterations do not change the basic programming experience of the respective language. However, you cannot copy program code literally from your PC environment to Mote Runner. Even if you could it is probably a bad idea since your mote has KBs of RAM while your PC has GBs of it. Thus, portability is not the goal. The changes to the languages introduced by Mote Runner are all aiming to improve the performance on small embedded systems: small footprint, high bytecode throughput, reduced RAM usage. The sections below discuss the language features, that are not supported at all, supported but modified, and finally, features added to Java and C#. The Mote Runner compiler calls the language compiler and then a converter to transform the language specific bytecode into Mote Runner bytecode (SIL). The language compilers will check a program against the full feature set, unaware of the restrictions imposed by Mote Runner. The next compilation step then will check against the superimposed Mote Runner semantics. Programs using unsupported language elements will be rejected and modified elements will be verified against the change meanings, possibly resulting in Mote Runner specific warnings and errors.
7
3.1
Features not Supported
Due to the restricted resources on embedded platforms, Mote Runner is unable to support all language features. It is a common approach to define a subset of the Java or C# language suitable for small systems. The table below lists the most prominent restrictions and omissions: Float and double data types 64-bit or longer integer arithmetic Multi-dimensional arrays Reflection Inner classes in C# (inner classes in Java are supported) Any runtime type info (e.g. getClass(), class names. etc.) except for language operators as instanceof, is, or as. Templates Multicast delegates (only unicast delegate supported) Threads and synchronization primitives bool/boolean arrays Strings (except in one special situation - more below) and String Arrays Boxing Standard runtime APIs Enums Standard runtime APIs for the language support and standard libraries of Java and C# are too big to fit onto small embedded systems. Mote Runner defines its own system APIs and any language runtime support has been cut to a minimum. This means no reflection, no symbolic runtime type information, no classes for boxing value types, root class Object comes without any methods and fields, and more. Multi-dimensional arrays are not directly supported but you can you simulate them by nesting Object arrays. Bool/boolean arrays are not supported because storing bits packed requires too much code for something that rarely used. If bits are not stored packed then boolean arrays are basically like byte arrays, hence inefficient and should therefore not be used anyway.
8
3.2
Size of Integer Types
Since Mote Runner is targeted for small embedded systems it implements a 16-bit VM. The basic stack slot and many other sizes (objects, arrays, etc.) are restricted to 16 bit. Although the VM also supports 32 bit integer types, this is kept to places where really required (e.g. Time). The main work is carried out in 16 bit which makes perfect sense on 8-bit and 16-bit CPUs. Using a 32 bit data type in place of a 16 bit one implies a serious performance impact (factor of 2-5 slow down depending on operation). Unfortunately, the standard type in Java and C# is int which is implemented as a 32 bit quantity in regular VMs. To obtain 16 bit arithmetic for our Mote Runner platform there where two options: 1. Use the short integer type for 16 bit arithmetic 2. Change int to be 16 bit While (1) seems appealing since it does not change language semantics it has serious drawbacks. The language compiler promotes short integer types to int. Thus, the programmer has to permanently work against this promotion by inserting of a lot of casts. If the programmer misses a cast the program will work fine since the VM also supports 32 bit arithmetic but the operation is unnecessarily slow. It is hard to spot those missing casts. Besides, there is no obvious indication that int has been used. A programmer would have to cross read the SIL file (Mote Runner assembler) to effectively find those places. Option (2) mirrors what C compilers for embedded system do. They re-define the int type to be 16 bit. Unlike embedded C compilers, the language compilers for Java and C# are unaware of this mapping since we reuse existing compilers. The change to 16 bit is checked and enforced in the converter phase of the Mote Runner compiler. Accordingly, the long type is mapped to 32 bit.
3.3
Exceptions
Mote Runner imposes a few minor restrictions on the handling of exceptions in Java and C#. Java makes a distinction between RuntimeException and its subclasses and other exceptions. The latter ones are part of the signature of a method and the language enforces the annotation of these exceptions on methods. In addition, Java has Error exceptions and as a common root class Throwable. C#’s root class for all exceptions is System.Exception which matches Java’s RuntimeException. Mote Runner does not support exception annotation on methods. The root class of all exceptions being thrown on Mote Runner platforms is MoteException which is subclassed from RuntimeException for Java code, and from System.Exception for C# code. Because of cross language interoperability you may not use any of the standard exception classes or subclass them. User defined exceptions must subclass MoteException. To catch all possible exceptions on a Mote Runner platform a catch for the MoteException class can be used. 9
MoteException and all system defined exceptions support a 16 bit reason code as context information. Stack traces, nested exception information or file and line number information are not supported. User defined exception classes may extend the amount of context information. In order to further improve exception handling performance a Mote Runner platform uses a special singleton exception object which is used for all exceptions during system interaction and which is available to user programs through a static method named throwIt on all predefined exception classes. The method MoteException.throwIt() throws a reference to a predefined system exception object and frees the user of allocating such an object from the heap. If a user defined exception class is being used, it is a good idea to have one instance preallocated and reuse this object in error conditions. Otherwise, a new object is allocated at each error clause, passed to the catch handler, and most likely its reference is ”forgotten” and, thus, turned into garbage. This programming pattern, although common on ”big” platforms, introduces a significant load for the garbage collector on small systems. Reference to the system singleton object also is special in another way. The reference may only be stored on the VM stack. It may not be stored into objects allocated from the heap. It is intended to only carry state in the call stack and may not be used as a pointer to context information for global state. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
package ex ; import com . ibm . saguaro . system .*; public class Ex { public int meth ( int v ) { if ( v ==0 ) MoteException . throwIt (1); return v +1; } public int meth2 () { try { return meth (0); } catch ( MoteException e ) { if ( e . reason ==2 ) throw e ; return 2; } } }
3.4
namespace ex { using com . ibm . saguaro . system ; public class Ex { public int meth ( int v ) { if ( v ==0 ) MoteException . throwIt (1); return v +1; } public int meth2 () { try { return meth (0); } catch ( MoteException e ) { if ( e . reason ==2 ) throw e ; return 2; } } } }
Class Initializers
Both Java and C# have a concept of initializing a class prior to its first use. The initialization code for a class is located in a static constructor for C# and in one or more static code blocks for Java. The order of class initialization depends on the actual program execution. The runtime systems for both Java and C# check upon access to any class feature if the class is already initialized. Such a scheme carries too much state for a VM designed for small embedded systems. Therefore, Mote Runner turns the dynamic initialization order of classes into a static one by ordering execution of class initializers according to the following relation: if the static initializer of a class A accesses class B then B is initialized before A. This rule resolves the problem of class initialization for most programs. For
10
some special situations the Mote Runner platform introduces a weight annotation to disambiguate. The default weight of un-annotated classes is zero. Weight can be arbitrary positive or negative values. Higher weighted classes are initialized before lower weighted ones. The disambiguation rules are: Unrelated classes with the same weight are initialized in any order. If a cycle is detected the Mote Runner compiler picks the class with the highest weight in the cycle to be initialized first. Having more than one class with the same weight in a cycle is an error. The example below shows the use of a weight annotation to ensure class B is initialized before class A and C. Since classes A and C are unrelated and have the same weight they are initialized in an undefined order. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
using com . ibm . saguaro . system . attr . Weight ; class A { static A () { .. } } [ Weight (3)] class B { static B () { .. } } class C { static C () { .. } }
3.5
import com . ibm . saguaro . system . attr . Weight ; class A { static { .. } } @Weight (3) class B { static { .. } } class C { static { .. } }
Data Initializers and Immutable Objects
The Mote Runner platform treats initializer data in a way that allows efficient initialization of objects from persistent memory. Initialization data is placed in persistent memory (flash/eeprom) together with the code and other data structures of the assembly. Upon initialization of an assembly this data is copied into array objects allocated from the object heap in RAM. Assembly initialization occurs after a successful upload and after the mote has been reset. If array objects are only read and never written then these arrays are immutable. Java and C# do not have a means to express this fact. You can declare a reference to array to be final (Java) or readonly (C#) which means you cannot change the contents of the variable pointing at the array but you still can change the array cells. Mote Runner defines an annotation to declare an array immutable. The language compiler does not know the semantics of this annotation and, therefore, will still allow modification of array cells. But the Mote Runner compiler in the converter phase will track the immutable property and complain about these assignments.
11
The benefit of declaring an array immutable is reduced RAM footprint, the most precious resource. Since the array is never written, the data is directly read from persistent memory. It need not be copied into RAM.
3.6
String Initializers
Strings are not supported on Mote Runner with one exception. A constant string can be used to initialize a byte array. Sometimes it is necessary to embed strings into an application if the embedded system has display capabilities. Initializing a byte array from a constant string is an easy way to save the programmer from a tedious conversion of ”display data” into a sequence of bytes or a sequence of individual characters. The Mote Runner converter recognizes the use of a special pattern and will convert the function call and string data into a byte array initialization during compile time. The example below illustrates the use of this feature: 1 2 3 4 5 6 7 8 9 10
namespace strini { using com . ibm . saguaro . system ;
1 2 3 4 5 6 7 8 9
public class DisplayStrings { public static readonly byte [] d1 = csr . s2b ( " Foo " ); public static readonly byte [] d2 = csr . s2b ( " Bar " ," UTF8 " ); } }
package strini ; import com . ibm . saguaro . system .*; public class Di sp la ySt ri ng s { public static final byte [] d1 = csr . s2b ( " Foo " ); public static final byte [] d2 = csr . s2b ( " Bar " ," UTF8 " ); }
String initializer data is always stored as immutable data in flash. The result of the s2b(..) are reference to immutable byte array objects. These references then are assigned to the respective static variable fields. The default character encoding is UTF8. You can select a specific character encoding by passing a second string identifying the desired encoding.
3.7
Delegates
Basically, delegates are pointers to methods. A delegate contains the address of the method implementation and optionally a reference to an object if a virtual method is being addressed. At the language level, delegates also define a particular method signature, that is, the number and types of the parameters and the type of return value. Delegates are useful in reactive programming (see here for more details on this programming pattern). Delegates are registered with the operating system and are invoked on specific events, acting as an elegant and flexible callback mechanism. The C# language natively supports the concept of delegates while Java lacks this feature. Mote Runner only supports unicast delegates and does not support C# multicast delegates. Although, the Java language does not offer this concept natively, the Mote Runner delegates can be exploited nevertheless. The programmer has to use a specific programming pattern which is being recognized by the Mote Runner byte code converter. The code below shows an example using delegates in C# and Java. First we have to declare a delegate type that specifies the signature of the methods to be 12
called via this type.
1
1 2 3 4 5 6 7 8
public delegate int CallB ( byte [] b , int l );
public abstract class CallB extends com . ibm . saguaro . system . java . Delegate { public Callback ( Object obj ) { super ( obj ); } public abstract int invk ( byte [] b , int l ); };
The code above declares a delegate which is being called with two arguments (a byte array and an integer) and returns an integer. For the converter to recognize the delegate pattern in Java, you have to create a subclass of the system class com.ibm.saguaro.system.java.Delegate. The abstract subclass must have a constructor passing on its single, object typed, parameter to the super class. It must have one additional abstract method called invoke which defines the signature of the delegate. The code above shows the user supplied elements of the Java pattern as underlined text. Delegate types are often defined in system libraries. The next step is to create an instance of a delegate pointing to a specific method and to invoke this method via the delegate. The code below implements an application class DelApp which creates a delegate in the method registerCallback, uses a delegate in invokeCallback, and defines the called method onCallback. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
public class DelApp { Callback currentCB ; public void registerCB () { currentCallback = onCallback ; } public int invokeCB ( byte [] data ) { return currentCB ( data , data . Length ); } public int onCB ( byte [] buf , int len ) { // ... do something return 0; } }
public class JDelApp { Callback currentCB ; public void registerCB () { currentCB = new Callback ( this ) { public int invoke ( byte [] b , int l ) { return (( JDelApp ) obj ). onCB ( buf , len ); } }; } public int invokeCB ( byte [] data ) { return currentCB . invoke ( data , data . length ); } public int onCB ( byte [] buf , int len ) { // ... do something return 0; } }
The invocation of the target method through a delegate reference in Java is quite simple and uses the invoke method of the delegate subclass. The implementation of this method will forward to the actual target method. The creation of the delegate in method registerCallack uses an anonymous inner class, subclassing our previously defined delegate type Callback. It implements the abstract method invoke by calling the actual target method. If the target method is static then the invoke method would not use the instance variable obj. Since our example delegates to an instance method the constructor is supplied with the respective object which is stored in obj and evaluated during invocation. The converter checks that the implementation of the invoke method only calls one static method or one instance method using all the parameters supplied to invoke and just returns the return value of this method. Deviating from this pattern makes the converter complain. The code patterns are depicted below in a more formal way. The bold elements describe elements to be supplied by user code. The other code must appear literally.
13
The return statement must be absent if retType is void. The first box shows the pattern for delegating to an instance method, the second box for a static method. 1 2 3 4 5
new delegateType ( objRef ) { public retType invoke ( arg1 ,.. , argn ) { retopt (( tgtClass ) obj ). tgtMeth ( arg1 ,.. , argn ); } }
1 2 3 4 5
new delegateType ( null ) { public retType invoke ( arg1 ,.. , argn ) { retopt tgtClass . tgtMethod ( arg1 ,.. , argn ); } }
Delegates in C# and their surrogates in Java are objects. When creating a delegate to some method a new object is allocated and is initialized with information about the target method. For performance reasons, the Mote Runner converter will turn delegate objects into delegate values which can be handled much more efficiently at runtime than object references. For all practical purposes, this change will not be noticed by a developer. As a side effect of this optimization, delegate values in Mote Runner cannot be casted to Object.
3.8
Getters/Setters
C# supports a feature called getter/setters. Access to a variable can be routed through special access methods. Although syntactically looking like a variable, at runtime a a method is called to read or write the value. Java mimics this behavior using methods named void setVar(TYPE) and TYPE getVar(). A getter/setter field in C# will be mapped to the Java equivalent by creating two methods as described above from the field name and its type. If you implement in Java and your code has some getVar/setVar methods then they are exposed to C# as methods with the same signature unless you specific them to map to getter/setter in C#. The examples below show some Java code and how it is exposed to C# programmers. First the Java code and how it is going to be exposed to C#: 1 2 3 4 5 6 7 8 9 10 11 12
public class App { int err , code ; public int getErr () { return err ; } public int getCode () { return code ; } public void setCode ( int err ) { this . code = code ; } }
1 2 3 4 5 6 7 8 9 10
public class App { int err , code ; public int getErr (); public int getCode (); public void setCode ( int err ); }
Another example of Java code (left) and how it is going to be exposed to C#: 1 2 3 4 5 6 7 8 9 10 11 12 13 14
public class App { int err , code ; @Getter public int getErr () { return err ; }
1 2 3 4 5 6 7 8 9 10 11
@Getter public int getCode () { return code ; } @Setter public void setCode ( int err ) { this . code = code ; } }
14
public class App { public int Err { get ; } public int Code { get ; set ; } }
Chapter 4
Reference Documentation 4.1
namespace com.ibm.saguaro.system
4.1.1
public class WLIP
This class implements WLIP, the LIP protocol for the radio. This protocol is very simple and only meant for setting up motes and initial or occasional maintenance (like loading assemblies, doing base configurations etc.). The protocol is single hop and is not trimmed for power efficiency. Use of this protocol is only encouraged for a short intial setup phase or for emergency mote recovery (explicitely triggered by an application). The WLIP protocol requires a gateway assembly to be installed on a mote with a wired link to some host. The WLIP protocol then creates the illusion of a wireless mote being hooked up via a cable to the gateway’s host. The WLIP protocol is automatically started after reset if no assemblies are installed on the mote or if none the installed assemblies acquired the radio. [see: com.ibm.saguaro.system.LIP] fields SYSEV WLIP UP SYSEV WLIP DOWN STATUS PROBING
SYSEV WLIP NOGATEWAY STATUS DOWN
SYSEV WLIP TXFAIL STATUS UP
methods getStatus
activate
shutdown
public static sealed int SYSEV WLIP UP [default: 0x10] The WLIP protocol has made initial contact to a gateway is ready now. This event is reported back to the callback registered with activate.
15
public static sealed int SYSEV WLIP NOGATEWAY [default: 0x11] WLIP protocol could not be started because no gateway responded. This event is reported back to the callback registered with activate. public static sealed int SYSEV WLIP TXFAIL [default: 0x12] The transmission of some radio frame to the WLIP gateway failed. This event is reported back to the callback registered with activate. public static sealed int SYSEV WLIP DOWN [default: 0x13] The WLIP protocol has been shutdown and the radio device is available again. This event is sent to all assemblies via the registered system info callback. public static sealed int STATUS DOWN [default: 0x00] The WLIP protocol is not activated. public static sealed int STATUS UP [default: 0x01] The WLIP protocol up and running. public static sealed int STATUS PROBING [default: 0x02] The WLIP protocol is starting up and is trying to detect a gateway. public static byte getStatus () Retrieve the current status of the WLIP protocol. Return Value byte
public static method activate (SystemInfo evh,bool probe) Start up the WLIP protocol. The WLIP protocol will allocate some buffers from the heap. These are not released even if the WLIP protcol is shutdown. If memory is very tight, the mote should be reset after maintenance to make the full heap available to applications.
16
Parameters type SystemInfo
name evh
bool
probe
documentation The event handler receiving notifications on protocol states SYSEV WLIP TXFAIL and SYSEV WLIP TXFAIL If true then check if a gateway is being found. If no answer from a gateway after certain tries the WLIP protocol is shutdown. If false the mote will stay in receive mode and might respond to APPEAL broadcasts from a gateway.
Exceptions exception com.ibm.saguaro.system.SystemException With reason code DENIED if either the mote is attached to a host via some cable (RS232/USB), if the WLIP protocol is already active, or if the radio is use by another application. public static method shutdown () Stop the WLIP protocol. The completion is reported as SYSEV WLIP DOWN event to all assemblies via system info callback. Exceptions exception com.ibm.saguaro.system.SystemException With reason code WRING STATE if WLIP is up
17
4.1.2
public sealed class Util
Util class of system API. This class contains a number of static methods supporting the programming of mote application. fields BYTE ARRAY UINT ARRAY
SBYTE ARRAY LONG ARRAY
INT ARRAY OBJECT ARRAY
methods make16 set16le fillData fillData set32le rand16 copyData get32be
alloca fillData overlay disposeOverlay updatePersistentData get16be rand8
get16le fillData compareData make32 get32le set16be set32be
public static sealed byte BYTE ARRAY [default: 0x00] Type parameter for alloca to allocate a byte array. public static sealed byte SBYTE ARRAY [default: 0x00] Type parameter for alloca to allocate a signed byte array. public static sealed byte INT ARRAY [default: 0x03] Type parameter for alloca to allocate an int array. public static sealed byte UINT ARRAY [default: 0x03] Type parameter for alloca to allocate an unsigned int array. public static sealed byte LONG ARRAY [default: 0x01] Type parameter for alloca to allocate an long array. public static sealed byte OBJECT ARRAY [default: 0x04] Type parameter for alloca to allocate a reference array. public static uint make16 (byte high,byte low) Create a 16-bit integer value from two bytes. 18
Parameters type byte byte
name high low
documentation The most significant byte. The least significant byte.
Return Value uint
Returns a combined value: high*256/low
public static object alloca (byte size,byte type) Allocate some array on the stack. Parameters type byte byte
name size type
documentation The size of the array. The type of the array (OBJECT ARRAY, OBJECT ARRAY, OBJECT ARRAY, OBJECT ARRAY, OBJECT ARRAY)
Return Value object
Returns the object as allocated on the stack
public static uint get16le (byte[] ary,uint index) Read a 16-bit integer value from a byte array in little endian byte order. Parameters type byte[] uint
name ary index
documentation The array to be accessed. The array index of the first byte. The index+1 must be still within the array. Otherwise an exception is thrown.
Return Value uint
Returns a 16-bit value ary[index]+ary[index+1]*256
public static uint set16le (byte[] ary,uint index,uint value) Write a 16-bit integer value into a byte array in little endian byte order.
19
Parameters type byte[] uint
name ary index
uint
value
documentation The array to be written. The array index of the first byte. The index+1 must be still within the array. Otherwise an exception is thrown. The value to be written.
Return Value uint
Returns index+2
public static uint fillData (byte[] ary,uint off,uint len,byte filler) Fill an array section with a given value. Parameters type byte[]
name ary
uint uint
off len
byte
filler
documentation The array to be written. This array must be in transient memory and must not be flagged as read only. The start index into the array. The number of bytes to be copied. This value is treated as an unsigned value. The value written into the array slots.
Return Value uint
Returns off+len.
public static uint fillData (uint[] ary,uint off,uint len,uint filler) Fill an array section with a given value. Parameters type uint[]
name ary
uint uint
off len
uint
filler
documentation The array to be written. This array must be in transient memory and must not be flagged as read only. The start index into the array. The number of bytes to be copied. This value is treated as an unsigned value. The value written into the array slots.
20
Return Value uint
Returns off+len.
public static uint fillData (object[] ary,uint off,uint len,object filler) Fill an array section with a given value. Parameters type object[]
name ary
uint uint
off len
object
filler
documentation The array to be written. This array must be in transient memory and must not be flagged as read only. The start index into the array. The number of bytes to be copied. This value is treated as an unsigned value. The value written into the array slots.
Return Value uint
Returns off+len.
public static object overlay (object array,uint beg,uint len,byte type) Create an array aliasing a section of another array. Only arrays holding integer data can be aliased. Parameters type object uint uint byte
name array beg len type
documentation A data array (byte[], int[], uint[], or long[]). The start of the array section. The length of the array section. The type of the array. (OBJECT ARRAY, OBJECT ARRAY, OBJECT ARRAY, OBJECT ARRAY, OBJECT ARRAY)
Return Value object
Returns the object as allocated on the stack
Exceptions exception com.ibm.saguaro.system.ArgumentException With reason code array if the object array has wrong.
21
public static uint compareData (object src,uint soff,object dst,uint doff,uint len) Compare array elements and stop on first inequality. Both arrays must be of the same type for arrays: byte[], int[], uint[], long[]. For arrays containing object references suppose type of source and destination arrays are S[] and T[], respectively. The operation will only succeed if S can be casted to T. That is, (S)T[0] would succeed. Otherwise, the call is aborted with an appropriate exception. Parameters type object
name src
uint object
soff dst
uint uint
doff len
documentation The source array. This array can be in transient or persistent memory. The start index into the source array. The destination array. This array must be in transient memory and must not be flagged as read only. The start index into the destination array. The number of elements to be copied. This value is treated as an unsigned value.
Return Value uint
Returns the smallest index where both arrays differ. If both arrays are equal the method returns 0xFFFF.
Exceptions exception com.ibm.saguaro.system.IndexOutOfRangeException If the ranges [soff;soff+len], [doff;doff+len] violate the array lengths of src or dst, respectively. public static uint fillData (long[] ary,uint off,uint len,long filler) Fill an array section with a given value. Parameters type long[]
name ary
uint uint
off len
long
filler
documentation The array to be written. This array must be in transient memory and must not be flagged as read only. The start index into the array. The number of bytes to be copied. This value is treated as an unsigned value. The value written into the array slots.
22
Return Value uint
Returns off+len.
public static method disposeOverlay (object array) Disposes of the resources creating the overlay abstraction. The reference to the overlay array object should not be used after this call. Parameters type object
name array
documentation An overlay array object created by Util.overlay().
Exceptions exception com.ibm.saguaro.system.ArgumentException With reason code array if the object array is not an overlay array. public static long make32 (int high,int low) Create a 32-bit integer value from two bytes. Parameters type int int
name high low
documentation The most significant byte. The least significant byte.
Return Value long
Returns a combined value: high*256+low
public static uint set32le (byte[] ary,uint index,long value) Write a 32-bit integer value into a byte array in little endian byte order. Parameters type byte[] uint
name ary index
long
value
documentation The array to be written. The array index of the first byte. The index+3 must be still within the array. Otherwise an exception is thrown. The value to be written.
23
Return Value uint
Returns index+4
public static uint updatePersistentData (object src,uint soff,object dst,uint doff,uint len) Update an array stored in persistent memory with data stored in an array stored in transient memory. Both arrays must be of the same type for arrays: byte[], int[], uint[], long[]. Persistent object arrays cannot be be updated. Otherwise, the call is aborted with an appropriate exception. Parameters type object uint object
name src soff dst
uint uint
doff len
documentation The source array. This array must reside in transient memory. The start index into the source array. The destination array. This array must be in persistent memory and the elements must basic integer types. The start index into the destination array. The number of elements to be copied. This value is treated as an unsigned value.
Return Value uint
Returns soff+len.
public static long get32le (byte[] ary,uint index) Read a 32-bit integer value from a byte array in little endian byte order. Parameters type byte[] uint
name ary index
documentation The array to be accessed. The array index of the first byte. The index+3 must be still within the array. Otherwise an exception is thrown.
Return Value long
Returns a 32-bit value (ary[index+3]*0x1000000)+(ary[index+2]*0x10000)+(ary[index+1]*0x100)+ary[in
public static uint rand16 () Create a 16-bit random integer value. 24
Return Value uint
public static uint get16be (byte[] ary,uint index) Read a 16-bit integer value from a byte array in big endian byte order. Parameters type byte[] uint
name ary index
documentation The array to be accessed. The array index of the first byte. The index+1 must be still within the array. Otherwise an exception is thrown.
Return Value uint
Returns a 16-bit value ary[index]*256+ary[index+1]
public static uint set16be (byte[] ary,uint index,uint value) Write a 16-bit integer value into a byte array in big endian byte order. Parameters type byte[] uint
name ary index
uint
value
documentation The array to be written. The array index of the first byte. The index+1 must be still within the array. Otherwise an exception is thrown. The value to be written.
Return Value uint
Returns index+2
public static uint copyData (object src,uint soff,object dst,uint doff,uint len) Copy data between arbitray arrays. Both arrays must be of the same type for arrays: byte[], int[], uint[], long[]. For arrays containing object references suppose the types of source and destination arrays are S[] and T[], respectively. The operation will only succeed if S can be casted to T. That is, (S)T[0] would succeed. Otherwise, the call is aborted with an appropriate exception. The destination array may not be a persistent array. To update a persistent array use updatePersistentData.
25
Parameters type object
name src
uint object
soff dst
uint uint
doff len
documentation The source array. This array can be in transient or persistent memory. The start index into the source array. The destination array. This array must be in transient memory and must not be flagged as read only. The start index into the destination array. The number of elements to be copied. This value is treated as an unsigned value.
Return Value uint
Returns soff+len.
public static byte rand8 () Create a 8-bit random integer value. Return Value byte
public static uint set32be (byte[] ary,uint index,long value) Write a 32-bit integer value into a byte array in big endian byte order. Parameters type byte[] uint
name ary index
long
value
documentation The array to be written. The array index of the first byte. The index+3 must be still within the array. Otherwise an exception is thrown. The value to be written.
Return Value uint
Returns index+4
public static long get32be (byte[] ary,uint index) Read a 32-bit integer value from a byte array in big endian byte order.
26
Parameters type byte[] uint
name ary index
documentation The array to be accessed. The array index of the first byte. The index+3 must be still within the array. Otherwise an exception is thrown.
Return Value long
Returns a 32-bit value (ary[index]*0x1000000)+(ary[index+1]*0x10000)+(ary[index+2]*0x100)+ary[inde
27
4.1.3
sealed public delegate TimerEvent
The delegate type for expired timer events. methods com.ibm.saguaro.system
public abstract method TimerEvent (byte param,long time) The delegate type for expired timer events. Parameters type byte long
name param time
documentation
28
4.1.4
public class Timer
Alarm time service. This class is used to trigger an action at a specific point in time. A program can setup an absolute point in time relative to the current mote current. The current mote time is maintained in an internal register in the operating system. It starts at value 0 when the mote is being reset and is continuously incremented. The timer class uses 32 bit values quantities using the tick precision. A tick is a platform specific value between 0.9us and 128us. Therefore, a 32 bit is unique within a span of -35 min. and +32 min. relative to current mote time. Longer time spans must be expressed by repeating smaller spans. methods getAlarmTime setCallback setAlarmTime
cancelAlarm setAlarmBySpan
setParam setAlarm
public long getAlarmTime () Retrieve the alarm time. Return Value long
public method cancelAlarm () Cancel this timer. This has no effect if the timer is not active. public method setParam (byte param) Set parameter byte supplied with each timer callback. Parameters type byte
name param
documentation
public method setCallback (TimerEvent ev) Set callback delegate.
29
Parameters type TimerEvent
name ev
documentation
public method setAlarmBySpan (long tickspan) Setup an alarm time some time ahead of the current time. Please note that this call is subject to inherent drift. An application has to take into account the time from the calculation of the time span to the location in the operating system where the timer is actually installed. For high accuracy please use setAlarm(..). Parameters type long
name documentation tickspan The amount of ticks ahead in time.
public method setAlarm (TimerEvent ev,long targetTimeTicks) Setup an alarm callback firing at the specified time. It is not an error to specify a time in the past. In this case the callback will be scheduled right away. Parameters type TimerEvent long
name documentation ev A delegate to the method being called at the specified time targetTimeTicks The absolute alarm time in ticks.
public method setAlarmTime (long targetTimeTicks) Setup timer to fire at the specified time. It is not an error to specify a time in the past. In this case the callback will be scheduled right away. Parameters type long
name documentation targetTimeTicks The absolute alarm time in ticks.
public constructor Timer () Constructor
30
4.1.5
public class Time
A class giving access to current time of the system. Time management in the operating system is based on ticks. The actual time span of a tick is dependent on the underlying hardware. A tick will not be less than 0.9 microseconds but can be as big as 128 microseconds. The operating system maintains the current time in register with more than 32 bit. Since the virtual machine’s biggest data type is 32 bit a program can only work with least significant 32 bits of this global time. The current time can be read in ticks, returning only the least 32 bits of the internal time register, or it can be returned in milliseconds and seconds. The internal register is first converted to the requested unit and then the least signficant 32 bits are returned. Time spans in milliseconds and seconds cna be convert to ticks and vice versa. These functions cna be used to convert between portable time quantities and platform specific ticks. A 32 bit ticks counter can cover at least a range of 71 minutes. A tick based timestamp will be unambiguous only within such a time frame. After this time the values repeat. To make time stamps unique either reduces to accurary (record seconds) or associate disambiguing informatation. (like a second time stamp, a generation counter etc.). fields SECONDS
MILLISECS
TICKS
methods currentTicks toTickSpan
currentTime
fromTickSpan
public static sealed uint SECONDS [default: 0x02] Time unit of seconds. public static sealed uint MILLISECS [default: 0x01] Time unit of milliseconds (1/1000 sec). public static sealed uint TICKS [default: 0x00] Platform specific tick unit. One tick is between 0.9us and 128us. public static long currentTicks () Return least significant 32 bits of current mote time in ticks. This value should be treated as an unsigned value.
31
Return Value long
public static long currentTime (uint unit) Convert current mote time from ticks into specified time unit and return least significant 32 bits of this value. Parameters type uint
name unit
documentation The requested precision. Must be one of: TICKS, TICKS, or TICKS.
Return Value long
public static long fromTickSpan (uint unit,long ticks) Convert a time span from ticks to the specified unit. Parameters type uint
name unit
long
ticks
documentation The requested precision. Must be one of: SECONDS or SECONDS. Time span in ticks.
Return Value long
public static long toTickSpan (uint unit,long time) Convert a time span from specified unit to ticks. Parameters type uint
name unit
long
time
documentation The requested precision. Must be one of: SECONDS or SECONDS. Time span in specified units.
32
Return Value long
33
4.1.6
sealed public delegate SystemInfo
The delegate signature of the system info handler. Assemblies can register with the operating system to receive system info events. The reported events inform about certain states changes. methods com.ibm.saguaro.system
public abstract int SystemInfo (int type,int info) The delegate signature of the system info handler. Assemblies can register with the operating system to receive system info events. The reported events inform about certain states changes. Parameters type int int
name type info
documentation The type of event. See SYSEV * constants. Additional information (defaults to 0 if not used).
Return Value int
The return value is context specific.
34
4.1.7
public class SystemException
Some system function/feature failed. This exception usually has a non-zero reason code. fields NOT IMPLEMENTED ALREADY DONE FAILED
NOT SUPPORTED DENIED
NOT FOUND WRONG STATE
methods throwIt
public static sealed uint NOT IMPLEMENTED [default: 0x01] Some feature/functionality is not implemented on this mote. public static sealed uint NOT SUPPORTED [default: 0x02] Some feature is not supported on this mote. public static sealed uint NOT FOUND [default: 0x03] Some item not found. public static sealed uint ALREADY DONE [default: 0x04] Some action already performed or some object is already in requested state. public static sealed uint DENIED [default: 0x05] Action denied. public static sealed uint WRONG STATE [default: 0x06] Object is wrong state for requested action. public static sealed uint FAILED [default: 0x07] Object in wrong state for requested action. public constructor SystemException (uint reason) Parameters type uint
name reason
documentation
35
public static method throwIt (uint reason) Parameters type uint
name reason
documentation
36
4.1.8
public class SimpleDevices
SimpleDevices API (will be OBSOLETE with the NEXT RELEASE). Simple devices provide sensor values instantly. That is, their values can be queried at any time and the value is provided without delay. This API is common on standard computer hardware (e.g. PCs, laptops etc.). This is also additional API to control power consumption of these sensors. This API are allows manipulation of simple actuators (e.g. setting fan speed). fields SCH TEMP CASING SCH TEMP CPU HEAT SINK SCH FAN CASING SCH ACCEL UNIT MOTE LIGHT MOTE HUMIDITY MOTE ADC CTRL INFO CTRL MAXV
SCH TEMP CPU SCH TEMP GPU HEAT SINK SCH FAN CPU SCH LIGHT AMBIENT MOTE ACCEL MOTE POWER STATUS MOTE VOLTAGE CTRL CALIBRATE
SCH TEMP GPU SCH TEMP HARDDISK SCH FAN GPU MOTE TEMP MOTE BAROMETER MOTE GPS VIBRATION CTRL MINV
methods read
actuate
control
public static sealed uint SCH TEMP CASING [default: 0x1000] public static sealed uint SCH TEMP CPU [default: 0x1001] public static sealed uint SCH TEMP GPU [default: 0x1002] public static sealed uint SCH TEMP CPU HEAT SINK [default: 0x1003] public static sealed uint SCH TEMP GPU HEAT SINK [default: 0x1004] public static sealed uint SCH TEMP HARDDISK [default: 0x1005] public static sealed uint SCH FAN CASING [default: 0x1006] public static sealed uint SCH FAN CPU [default: 0x1007] public static sealed uint SCH FAN GPU [default: 0x1008] public static sealed uint SCH ACCEL UNIT [default: 0x1009] public static sealed uint SCH LIGHT AMBIENT [default: 0x100a] public static sealed uint MOTE TEMP [default: 0x2000] Mote specific temperature sensor. Check the respective hardware platform for details. For the IRIS mote check the Sensors in the firmware section.
37
public static sealed uint MOTE LIGHT [default: 0x2010] Mote specific light sensor. Check the respective hardware platform for details. For the IRIS mote check the Sensors in the firmware section. public static sealed uint MOTE ACCEL [default: 0x2020] Mote specific acceleration sensor. Check the respective hardware platform for details. For the IRIS mote check the Sensors in the firmware section. public static sealed uint MOTE BAROMETER [default: 0x2030] Mote specific presuce sensor. Check the respective hardware platform for details. For the IRIS mote check the Sensors in the firmware section. public static sealed uint MOTE HUMIDITY [default: 0x2040] Mote specific humidity sensor. Check the respective hardware platform for details. For the IRIS mote check the Sensors in the firmware section. public static sealed uint MOTE POWER STATUS [default: 0x2050] Status of power supply. [0] unsigned 8-bit: flags: 7:main power available, 6:charging, 5:critical low power. [1] unsigned 8-bit: charge level of battery: 0 - empty, 255 - full [2-3] unsigned 16-bit: capacity of battery (0=unknown, unit mAh) [4-5] unsigned 16-bit: current voltage in mV (optional) – either all or none [6-7] unsigned 16-bit: reference voltage in mV (optional) [8-9] unsigned 16-bit: brownout voltage in mV (optional) public static sealed uint MOTE GPS [default: 0x2060] public static sealed uint MOTE ADC [default: 0x2090] Analog to digital converter. Use the device index to distinguish between different ADCs. Check the respective hardware platform for details. For the IRIS mote check the Sensors in the firmware section. public static sealed uint MOTE VOLTAGE [default: 0x20a0] Status of power supply: SimpleDevices.MOTE POWER STATUS public static sealed uint VIBRATION [default: 0xf123] public static sealed uint CTRL INFO [default: 0x00] Retrieves auxiliary information about a specific device. Mode value for control() method. The amount and semantics of the returned data depends on the specified device. The returned information can be for instance the color of an LED, the measurement units of the device.
38
public static sealed uint CTRL CALIBRATE [default: 0x01] Set calibration parameters for the specified device. Mode value for control() method. public static sealed uint CTRL MINV [default: 0x02] Retrieve the minimum values possibly returned by the device. Mode value for control() method. The returned values are inclusive. public static sealed uint CTRL MAXV [default: 0x03] Retrieve the maximum values possibly returned by the device. Mode value for control() method. The returned values are inclusive. public static int read (uint deviceClass,uint idx,uint mode,byte[] buf,uint off,uint len) Read sensor values into specified buffer. Parameters type uint uint uint byte[] uint uint
name documentation deviceClassThe ID of a sensor device class. See SDEV * constants above. idx The index of the device if there are several of that kind (e.g. multiple temperature sensors). If there is only one specify 0. mode The read mode. Specify 0 for normal mode. buf The buffer receiving the sensor data. off Start offset into data buffer. len Amount of buffer made available. If this is not enough to hold the sensor data the method returns a negative value indicating how much more bytes are needed. The device might also truncate the returned sensor data. If length is 0 it always will return the required buffer size as a negative number.
Return Value int
Return the number of bytes being written into supplied buffer. A zero value indicates that the sensor cannot be read currently. A negative value signals the output buffer is too small by negated amount of bytes.
Exceptions exception com.ibm.saguaro.system.IndexOutOfRangeException If the deviceClass is supported but the specified index exceeds the available sensors. The reason code specifies the maximum available sensors.
39
exception com.ibm.saguaro.system.SystemException If the deviceClass is not implemented, supported, or not available for some other reason. public static int actuate (uint deviceClass,uint idx,uint mode,byte[] buf,uint off,uint len) Set actuator to a state as specified in buffer. Parameters type uint uint uint byte[] uint uint
name documentation deviceClassThe ID of a device class. See SDEV * constants above. idx The index of the device if there are several of that kind (e.g. multiple temperature sensors). If there is only one specify 0. mode The actuation mode. Specify 0 for normal mode. buf The buffer containing the actuator data. off Read actuator data from this offset. len Size of actuator data. If this is not enough data the method returns a negative value indicating how much more bytes are expected.
Return Value int
Return a positive number to indicate successful actuation. A zero value indicates that the actuator cannot be accessed currently. A negative value signals the input buffer does not contain enough data (negated amount of bytes more required).
public static int control (uint deviceClass,uint idx,uint mode,byte[] buf,uint off,uint len) Perform a control operation on the specified devive. Parameters type uint uint uint byte[] uint uint
name documentation deviceClassThe ID of a device class. See SDEV * constants above. idx The index of the device if there are several of that kind (e.g. multiple temperature sensors). If there is only one specify 0. mode Specifies the mode of operation. buf The buffer containing data for the device and/or receiving data from the device. off Start offset into supplied buffer. len The length of the supplied buffer.
40
Return Value int
A signed return value. Its interpretation is dependent on the specified flags.
41
4.1.9
sealed public delegate RadioTxDone
Report completion of an transmission attempt. methods com.ibm.saguaro.system
public abstract method RadioTxDone (byte[] pdu,uint len,int status,long txend) Report completion of an transmission attempt. Parameters type byte[]
name pdu
uint int
len status
long
txend
documentation A buffer containing the radio frame. The frame data starts at index zero. Note, this byte array is a temporaryobject and it cannot be stored into objects. It can be passed around only on the stack. The length of the radio frame in bytes. The status of the transmit attempt. A negative value indicates an error. Zero or a positive value signals success. A time stamps in ticks that marks the end of channel usage. In case of unacknowledged transmit this is the end of the frame transmission. In case of acknowledged transmit this marks the end of receive of the incomming ACK frame. This parameter is only valid if transmit was successful.
42
4.1.10
sealed public delegate RadioRxPdu
This type of method is being called when a radio frame has been received. methods com.ibm.saguaro.system
public abstract method RadioRxPdu (byte[] pdu,uint len,long time,uint quality) This type of method is being called when a radio frame has been received. Parameters type byte[]
name pdu
uint long uint
len time quality
documentation The buffer holding the received frame. The data starts at index zero. Note, this byte array is a temporaryobject and it cannot be stored into objects. It can be passed around only on the stack. The length of the received frame in bytes. The time in ticks when the frame started. The quality of the reception. The high byte describes the LQI (link quality indicator) with 0 being least and 255 being the best quality. The low byte is the RSSI value (received signal strengh indicator) with 0 being weakest and 255 being strongest signal strength.
43
4.1.11
sealed public delegate RadioDone
This callback reports completion of some state changed or reports some event. methods com.ibm.saguaro.system
public abstract method RadioDone (uint info) This callback reports completion of some state changed or reports some event. Parameters type uint
name info
documentation The meaning of this parameter is context dependent.
44
4.1.12
public abstract class Radio
IEEE 802.15.4 Physical Layer API. This API allows to access the radio of a mote. It gives access to a number of primitives which allow construction of of custom MAC protocols. The radio is accessible only to one assembly. Before using this API the assembly must acquire the radio. At the end of use it must call release to make the radio API available to others again. An assembly owning the radio can offer APIs providing transport services and coordinating concurrent access from other assemblies. Access to the radio API while not owing it results in a SystemException with reason code DENIED. A MAC protocol using this radio API can either implement some eisting standard or it can a proprietary one (small and simple, or elaborate). In any case the sent messages should be compliant with the MAC header as defined in IEEE 802.15.4. You can find an overview of the header in the Mote Runner documentation. Although arbitrary frame can be sent the receiver expects this header in order to filter frame and check if they are destined for the receiving mote. Most of the API methods can only be called if the radio stack is in certain state. Calling an API method from an undefined state will result in a SystemException with reason code WRONG STATE. The Mote Runner documentation. provides a more detailed description of the states and the possible transitions. [see: com.ibm.saguaro.system.SystemException] fields PAN BROADCAST FCF TYPE FCF ACK FCF SEC FCF NSPID FCA FRV 2003 FCA DST MASK FCA DST SADDR FCA SRC NONE FCA SRC XADDR TXMODE CCA TXMODE POWER MASK RS SLEEP RS RXEN RS TX CCA ENERGY THRESHOLD OK PEND ERR TIMEOUT
SADDR BROADCAST FCF BEACON FCF CMD FCF PEND FCF RFU7 FCA FRV 2006 FCA DST NONE FCA DST XADDR FCA SRC RFU TXMODE LATEOK TXMODE CSMA TXMODE POWER MIN RS ACTIVE RS RXOFF RS IDLE OK SUCCESS ERR NOACK ERR TOOLATE
45
SADDR NONE FCF DATA FCF RFU FCF ACKRQ FCA FRV MASK FCA FRV RFU FCA DST RFU FCA SRC MASK FCA SRC SADDR TXMODE NOW TXMODE SLOTTED TXMODE POWER MAX RS ED RS PROMISCUOUS CCA CARRIER SENSE OK ACKED ERR NOCHACC ERR CUTOFF
methods release setPanId
setShortAddr getPanId
getShortAddr getCoordinatorMode
setCsmaParams getChannel
setExtAddr getState
getExtAddr setChannel
setRxHandler cancel enableRx transmit std2chnl transmit activate
setRxDone sleep sleep reset enablePromiscuous stopRx transmit
chnl2std acquire enableRx transmit energyDetect activate
public static sealed uint PAN BROADCAST [default: 0xffff] Broadcast PAN identifier. public static sealed uint SADDR BROADCAST [default: 0xffff] Short address value denoting a broadcast. public static sealed uint SADDR NONE [default: 0xfffe] Short address value reserved for the meaning: no short address assigned. public static sealed byte FCF TYPE [default: 0x07] A bit mask for the frame type field. public static sealed byte FCF BEACON [default: 0x00] A value for the frame type field denoting a BEACON frame. public static sealed byte FCF DATA [default: 0x01] A value for the frame type field denoting a DATA frame. public static sealed byte FCF ACK [default: 0x02] A value for the frame type field denoting an ACK frame. public static sealed byte FCF CMD [default: 0x03] A value for the frame type field denoting an CMD frame.
46
public static sealed byte FCF RFU [default: 0x04] A value for the frame type field denoting the first undefined value. Values 4-7 are reserved for future use. These bits should be always zero when sending and ignored upon receipt. public static sealed byte FCF SEC [default: 0x08] A value for the frame type field denoting that the frame is encrypted. public static sealed byte FCF PEND [default: 0x10] A value for the frame type field denoting that sender has some data pending for destination. public static sealed byte FCF ACKRQ [default: 0x20] A value for the frame type field denoting that sender shall acknowledge receipt with an ACK message. public static sealed byte FCF NSPID [default: 0x40] A value for the frame type field denoting that source PAN field is absent sender (No Source PanID). public static sealed byte FCF RFU7 [default: 0x80] A value for the frame type field denoting a reserved bit. This bit should be always zero when sending and ignored upon receipt. public static sealed byte FCA FRV MASK [default: 0x30] This value isolates the frame version bit field from the FCA header byte. public static sealed byte FCA FRV 2003 [default: 0x00] A value for the frame version bit field from the FCA header byte. This value is zero and is the default value to use for the frame version unless specific standards compliant MAC frames are sent. public static sealed byte FCA FRV 2006 [default: 0x10] A value for the frame version bit field from the FCA header byte. This value must be used for some IEEE 802.15.4 MAC layer messages if the radio uses certain channels. public static sealed byte FCA FRV RFU [default: 0x20] A value for the frame version bit field from the FCA header byte. This value is reserved for future uss. 47
public static sealed byte FCA DST MASK [default: 0x0c] This value isolates the destination address format bit field from the FCA header byte. public static sealed byte FCA DST NONE [default: 0x00] A value for the destination address format bit field from the FCA header byte. This value specifies that the destination address fields are absent. An absent destination address implicitely addresses a coordinator mote. A mote can be configured as a coordinator while setting the PAN address using the setPanId() method. public static sealed byte FCA DST RFU [default: 0x04] A value for the destination address format bit field from the FCA header byte. This value is reserved for future use. public static sealed byte FCA DST SADDR [default: 0x08] A value for the destination address format bit field from the FCA header byte. This value specifies that the destination address field consists of a 16-bit PAN followed by a 16-bit short address. public static sealed byte FCA DST XADDR [default: 0x0c] A value for the destination address format bit field from the FCA header byte. This value specifies that the destination address field consists of a 16-bit PAN followed by a 64-bit extended address. public static sealed byte FCA SRC MASK [default: 0xc0] This value isolates the source address format bit field from the FCA header byte. public static sealed byte FCA SRC NONE [default: 0x00] A value for the source address format bit field from the FCA header byte. This value specifies that the source address fields are absent. An absent source address implicitely refers to a coordinator mote as sender. A mote can be configured as a coordinator while setting the PAN address using the setPanId() method. public static sealed byte FCA SRC RFU [default: 0x40] A value for the source address format bit field from the FCA header byte. This value is reserved for future use.
48
public static sealed byte FCA SRC SADDR [default: 0x80] A value for the source address format bit field from the FCA header byte. This value specifies that the source address field consists of a 16-bit PAN followed by a 16-bit short address. public static sealed byte FCA SRC XADDR [default: 0xc0] A value for the source address format bit field from the FCA header byte. This value specifies that the source address field consists of a 16-bit PAN followed by a 64-bit extended address. public static sealed uint TXMODE LATEOK [default: 0x20] A bit specifying that a transmit request with a dealine is allowed to send the frame even if the deadline is missed. Without this bit (default) the transmit attempt would be aborted with an error code ERR TOOLATE. public static sealed uint TXMODE NOW [default: 0x04] A bit specifying that a transmit should be performed immediately. Without this bit transmission starts at a specified time. public static sealed uint TXMODE CCA [default: 0x08] A bit specifying that a transmit should use one clear channel analysis before sending at the specified time. Valid only for transmit calls specifying an explicit send time. If TXMODE NOW is specified then this bit is implicitely interpreted as TXMODE CSMA public static sealed uint TXMODE CSMA [default: 0x08] A bit specifying that a transmit should use CSMA-CA channel access before sending. CSMA-CA channel delays the transmit attempt according to the currently set parameters by a random time, then performs a CCA (clear channel analysis). If the channel is declared sending will start. Otherwise the backoff process is repeated. After a specified amount of backoffs an error will be returned. This bit is only valid together with TXMODE NOW or transmit calls that do not specify an explicit time of sending. public static sealed uint TXMODE SLOTTED [default: 0x10] A bit specifying that a transmit should use slotted CSMA-CA channel access before sending. This mode is currently not supported. public static sealed uint TXMODE POWER MASK [default: 0xff00] Bits reserved for transmit power in transmit mode.
49
public static sealed int TXMODE POWER MIN [default: 0xff00] This value specifies minimum transmit power. public static sealed int TXMODE POWER MAX [default: 0x00] This value specifies maximum transmit power. This value is zero, thus not using this constant means sending with maxium power by default. public static sealed uint RS SLEEP [default: 0x00] Radio module is in SLEEP state (lowest power consumption). public static sealed uint RS ACTIVE [default: 0x01] Radio module is in ACTIVE state (high power consumption). public static sealed uint RS ED [default: 0x04] Radio module busy handling an ’energyDetect’ task. public static sealed uint RS RXEN [default: 0x02] Radio module is ready to receive frames. public static sealed uint RS RXOFF [default: 0x03] Radio module has turned off hardware receiver but is still processing received frames. public static sealed uint RS PROMISCUOUS [default: 0x05] Radio module is ready to receive any detectable frame. public static sealed uint RS TX [default: 0x08] Radio module busy handling a ’transmit’ task. This bit occurs together with other states (SLEEP/ACTIVE/RXEN/RXOFF). public static sealed uint RS IDLE [default: 0x10] Radio module is idle and in transition to some state. During this time the hardware is put to the lowest possible power state. This bit occurs only together with other states (SLEEP/ACTIVE/RXEN/TX). public static sealed uint CCA CARRIER SENSE [default: 0x06] public static sealed uint CCA ENERGY THRESHOLD [default: 0x07] public static sealed int OK SUCCESS [default: 0x00] Some radio operation complete successfully. 50
public static sealed int OK ACKED [default: 0x02] Transmission of radio PDU completed and has been acknowledged successfully. public static sealed int OK PEND [default: 0x03] Transmission of radio PDU completed, has been acknowledged successfully, and the ACK frame carried a set pending bit indicating that the commination peer has some or more data pending for this mote. public static sealed int ERR NOACK [default: 0xff] Radio transmission failed since requested ACK frame was not received. public static sealed int ERR NOCHACC [default: 0xfe] Radio transmission failed since channel access failed. The radio listens for ongoing activity and only sends if the channel seems to be free. Details of channel access are controlled by the transmit mode and the CSMA-CA parameters. public static sealed int ERR TIMEOUT [default: 0xfd] Radio operation failed due to some timeout condition. public static sealed int ERR TOOLATE [default: 0xfc] An applications transmit request specified a point in time for transmission. Either the distance to the deadline was too close or another task in the operating system prevent to hit the exact deadline. public static sealed int ERR CUTOFF [default: 0xfb] An applications transmit request specified CSMA-CA channel access. This mode requires to specify a deadline. The exponential backoff algorithm exceeded this deadline and the transmit attempt has been aborted. public static method release () Release the radio API so that another assembly may take control of the API. public static method setShortAddr (uint saddr) Set the IEEE 802.15.4 short address of this mote. The initial default value is SADDR BROADCAST. This value controls filtering of incomming frames. The broadcast value makes the radio stack accept all frames matching the PAN address no matter what the value of the mote short address in the radio frame. This call can only be performed if the radio API is in state SLEEP or ACTIVE.
51
Parameters type uint
name saddr
documentation
public static uint getShortAddr () Retrieve the current IEEE 802.15.4 short address of this mote. This value is used for address filtering of incomming PDUs. Return Value uint
public static method setPanId (uint panid,bool isCoord) Set PAN address and state of coordinator role of this mote. Both values control address filtering in the radio. This call can only be performed if the radio API is in state SLEEP or ACTIVE. Parameters type uint
name panid
bool
isCoord
documentation The 16 bit PAN address. If set to PAN BROADCAST then the radio will accept PDUs from any PAN. Any other value makes the radio drop all PDUs that do not carry the specified PAN. True if this mote is the coordinator of the PAN, false otherwise. If true the radio will accept messages which do not have a destination address field. They are implicitly addressed to the coordinator. If false the radio will drop messages that do not have an explicit destination address.
public static uint getPanId () Retrieve the current IEEE 802.15.4 PAN address of this mote. This value is used for address filtering of incomming radio PDUs. Return Value uint
public static bool getCoordinatorMode () Retrieve the coordinator mode used for address filtering. If true the radio will accept messages which do not have a destination address field. They are implicitly
52
addressed to the coordinator. If false the radio will drop messages that do not carry an explicit destination address. Return Value bool
public static method setCsmaParams (byte maxBackoffs,byte minBE,byte maxBE,byte flags) Parameters type byte byte byte byte
name documentation maxBackoffs minBE maxBE flags
public static method setExtAddr (byte[] xaddr,uint off,bool persistent) Set extended radio address. This address is 64 bits long (8 bytes) and is specified in little endian byte order. Parameters type byte[] uint bool
name xaddr off
documentation The buffer holding the address. The start index of the address. The bytes off+0 .. off+7 define the address. persistent If this bit is true the address is stored in persistent memory so that the mote is using this address after next reset or power down. If false then this address only remains in effect until next reset or power down.
public static method getExtAddr (byte[] xaddr,uint off) Retrieve the current IEEE 802.15.4 extended address of this mote. This will write 8 bytes of address information in little endian format into the specified buffer. Parameters type byte[] uint
name xaddr off
documentation
53
public static byte getChannel () Retrieve the currently active radio channel. Return Value byte
public static byte getState () Retrieve the current radio state. See RS ... states. Return Value byte
public static method setChannel (byte channel) Change the radio channel. Note, depending on the radio state changing the channel might require a small amount of time. Changing the channel is only possible in SLEEP or ACTIVE state. Calling this during for any other state (e.g. RXEN or TX) will result in an exception. Parameters type byte
name channel
documentation
Exceptions exception com.ibm.saguaro.system.SystemException With reason code RX TX if the Radio is in the RX TX, RX TX, or RX TX state. public static method setRxHandler (byte backlog,RadioRxPdu pduHandler) Register the callback function which is invoked when a radio PDU has been received. Parameters type byte RadioRxPdu
name backlog
documentation The maximum number of PDUs buffered in the system. The value 0 means to buffer as many as possible. pduHandlerThe callback invoked on reception of a radio PDU.
54
public static method setRxDone (RadioDone onRxDone) Register the callback function which is invoked when receive mode ends. Parameters type RadioDone
name documentation onRxDoneThe callback invoked when receive task ends.
public static int chnl2std (byte chnlIdx) Convert an internal channel index into a IEEE 802.15.4 channge page and channel number specification. Internal channel indices start at 0 upto a platform specific maximum. Parameters type byte
name chnlIdx
documentation A channel index.
Return Value int
Return the channel page/number in the returned 16-bit int value or return -1 if the channel index is an illegal value. The high byte encodes the channel page and the low byte the channel number.
public static method cancel () Cancel the current task (setup/energy detect/transmit/receive). The callback signaling completion of the respective task will not be called. The radio remains in SLEEP mode if it was sleeping previously. Otherwise it enters the ACTIVE state public static method sleep () Put radio in SLEEP mode immediately. The SLEEP mode is the most power efficient mode. Note, however that bringing the radio back into ACTIVE state to receive or send messages might take up to 1 millisecond, depending on underlying hardware. The call cancels the current task (setup/energy detect/transmit/receive). The callback signaling completion of the respective task will not be called. public static method acquire () Acquire the radio device for use by the calling assembly. This method must be directly called from code placed with the assembly that wishes to acquire the radio device. After a successful acquire call, only the radio API may only be called from
55
the acquiring assembly. All other assemblies will get an SystemException with reason code DENIED when trying to access the radio. public static method enableRx (long until) Enable receiver until specified time reached. The receive callback is invoked every time a PDU has been downloaded. If new data frames arrive while one PDU is being processed the new data is buffered in the OS and a receive callback is triggered after the processing of the current frame ended. The timeout callback is invoked if the specified time has expired and after all buffered frames have been processed. Parameters type long
name until
documentation
Exceptions exception com.ibm.saguaro.system.SystemException With reason code WRONG STATE if the Radio is busy performing a previous task. public static method sleep (long until,RadioDone onDone) Put radio in SLEEP mode immediately and perform a callback using the delegate at specified point in time. Parameters type long RadioDone
name until onDone
documentation The point in time when the delegate is being called. The callback delegate.
public static method enableRx (byte channel,long at,long until) Enable receiver at specified on given channel and stop receive at deadline. Parameters type byte
name channel
long
at
long
until
documentation The radio is receiving on this channel when receive mode is started. This number is a platform specific channel index. The point in time when to the receiver of the radio is actually enabled. Receive mode is stopped at this point in time.
56
Exceptions exception com.ibm.saguaro.system.SystemException With reason code WRONG STATE if the Radio is busy performing a previous task. public static method transmit (uint mode,byte[] pdu,uint beg,uint len,RadioTxDone onTxDone) Transmit given data immediately. Parameters type uint byte[] uint uint RadioTxDone
name mode pdu
documentation Transmission mode details. Default behavior is value 0. A buffer that holds the radio frame. The frame must not contain the FCS. This is automatically added by the operating system. beg Start of the radio frame. len Length of the radio frame. The minimum frame depends on the IEEE 8023.15.4 header configuration. onTxDoneThe callback to be invoked when transmission completed.
Exceptions exception com.ibm.saguaro.system.ArgumentException With reason code ILLEGAL VALUE if message length is too big. exception com.ibm.saguaro.system.SystemException With reason code WRONG STATE if the Radio is busy performing a previous task. public static method reset () Reset the radio hardware and the radio module of the operating system. This aborts the current task and resets all internal state (modes, addresses etc) to their initial default values. public static method transmit (uint mode,byte[] pdu1,uint len1,byte[] pdu,uint beg,uint len,RadioTxDone onTxDone) Transmit given data immediately.
57
Parameters type uint byte[] uint byte[] uint uint RadioTxDone
name mode pdu1 len1 pdu
documentation Transmission mode details. Default behavior is value 0. A buffer holding optional header data. Header starts at index 0. The length of the header data. If zero then pdu1 may be null. A buffer that holds the radio frame. The frame must not contain the FCS. This is automatically added by the operating system. beg Start of the radio frame. len Length of the radio frame. The minimum frame depends on the IEEE 8023.15.4 header configuration. onTxDoneThe callback to be invoked when transmission completed.
Exceptions exception com.ibm.saguaro.system.ArgumentException With reason code ILLEGAL VALUE if message length is too big. exception com.ibm.saguaro.system.SystemException With reason code WRONG STATE if the Radio is busy performing a previous task. public static int std2chnl (int pageChnl) Convert an IEEE 802.15.4 channge page and channel number specification into an internal channel index. Internal channel indices start at 0 upto a platform specific maximum. Parameters type int
name documentation pageChnl The high byte encodes the channel page and the low byte the channel number within this page. Currently, IEEE 802.15.4 specifies channel pages 0, 1, and 2 with each channels in different frequency bands and with different symbol encodings.
Return Value int
The platform specific channel index or -1 if this channel page/number combination is not supported by the mote.
58
public static method enablePromiscuous () Turn on the promiscuous mode of the receiver and download all decodable frames. Such a mode can be used to implement a radio sniffer which is observing the traffic between other motes. If this mode is not supported on the underlying hardware platform an exception is thrown. The rado must not be busy with some task when enabling this mode. While in promiscuous mode not other task may be started. To abort promiscuous mode you have to call either cancel() or reset(). Frames are delivered via the receive callback as in normal receive mode. An LQI value of zero and a frame length of zero means that some corrupted packet has been picked up. Exceptions exception com.ibm.saguaro.system.SystemException With reason code WRONG STATE if the Radio is busy performing a previous task. public static method energyDetect (byte channel,long until,RadioDone onDone) Detect energy on the given channel from now until a point in time in the future. Note, depending on the radio state changing the channel might require a small amount of time. Parameters type byte
name channel
long RadioDone
until onDone
documentation The channel the energy is measured on. This parameter is platform specific. The point in time until energy is measured. The callback delegate which is invoked at the end of the measurement. The low byte of the parameter info contains the value of the measurement (0 = no energy measured, 255 = maximum energy measured). The interpretation of the measurement depends on the platform.
public static method transmit (uint mode,byte[] pdu,uint beg,uint len,long time,RadioTxDone onTxDone) Transmit given data at specified point in time.
59
Parameters type uint byte[] uint uint long RadioTxDone
name mode pdu
documentation Transmission mode details. Default behavior is value 0. A buffer that holds the radio frame. The frame must not contain the FCS. This is automatically added by the operating system. beg Start of the radio frame. len Length of the radio frame. The minimum frame depends on the IEEE 8023.15.4 header configuration. time The point in time when to start transmission. Note, this is not a time span but a time point. onTxDoneThe callback to be invoked when transmission completed.
Exceptions exception com.ibm.saguaro.system.ArgumentException With reason code ILLEGAL VALUE if message length is too big. exception com.ibm.saguaro.system.SystemException With reason code WRONG STATE if the Radio is busy performing a previous task. public static method stopRx () Immediately stop receive mode of radio chip. This prevents download of further PDUs. A started reception will be finished. Although, receive mode is disabled the receive callback might be invoked for PDUs already downloaded and buffered. In any case the timeout callback is invoked to confirm this action. public static method activate (byte channel,RadioDone onDone) Put radio into ACTIVE state on given channel. This operation might take some time. Once the radio has reached ACTIVE state the specified callback will be invoked. Parameters type byte
name channel
RadioDone
onDone
documentation The radio is operating on this channel when ACTIVE. This number is a platform specific channel index. The callback invoked when the radio is in ACTIVE state.
Exceptions
60
exception com.ibm.saguaro.system.SystemException With reason code WRONG STATE if the Radio is busy performing a previous task. public static method activate (byte channel,long at,RadioDone onDone) Put radio into ACTIVE state on given channel at specified time. Once the radio has reached ACTIVE state the specified callback will be invoked. Parameters type byte
name channel
long RadioDone
at onDone
documentation The radio is operating on this channel when ACTIVE. This number is a platform specific channel index. The time when the radio is supposed to be in ACTIVE state. The callback invoked when the radio is in ACTIVE state.
Exceptions exception com.ibm.saguaro.system.SystemException With reason code WRONG STATE if the Radio is busy performing a previous task. public static method transmit (uint mode,byte[] pdu1,uint len1,byte[] pdu,uint beg,uint len,long time,RadioTxDone onTxDone) Transmit given data at specified point in time. Parameters type uint byte[] uint byte[] uint uint long RadioTxDone
name mode pdu1 len1 pdu
documentation Transmission mode details. Default behavior is value 0. A buffer holding optional header data. Header starts at index 0. The length of the header data. If zero then pdu1 may be null. A buffer that holds the radio frame. The frame must not contain the FCS. This is automatically added by the operating system. beg Start of the radio frame. len Length of the radio frame. The minimum frame depends on the IEEE 8023.15.4 header configuration. time The point in time when to start transmission. Note, this is not a time span but a time point. onTxDoneThe callback to be invoked when transmission completed.
Exceptions
61
exception com.ibm.saguaro.system.ArgumentException With reason code ILLEGAL VALUE if message length is too big. exception com.ibm.saguaro.system.SystemException With reason code WRONG STATE if the Radio is busy performing a previous task.
62
4.1.13
public class OutOfResourcesException
Out of memory. Some resource is exhausted. This exception usually has a non-zero reason code. fields STACK OVERFLOW NO BUFFERS
THEAP FULL QUEUE FULL
TABLE FULL
methods throwIt
public static sealed uint STACK OVERFLOW [default: 0x01] Some method call failed because there is not enough space left on VM stack. public static sealed uint THEAP FULL [default: 0x02] Transient heap is full. Cannot allocate any more new objects. public static sealed uint TABLE FULL [default: 0x03] Table is full. Type of table is context specific. public static sealed uint NO BUFFERS [default: 0x04] No more network buffers available. public static sealed uint QUEUE FULL [default: 0x05] Queue is full. public constructor OutOfResourcesException (uint reason) Parameters type uint
name reason
documentation
public static method throwIt (uint reason) Parameters type uint
name reason
documentation
63
4.1.14
public class NullReferenceException
Runtime cast check failed. This exception usually has a zero reason code. methods throwIt
public constructor NullReferenceException (uint reason) Parameters type uint
name reason
documentation
public static method throwIt (uint reason) Parameters type uint
name reason
documentation
64
4.1.15
public class MoteException
This is the root object for all exceptions thrown on the mote. This class extends a language specific superclass. This superclass and its anchestors may not be used in application code because they have no representation at runtime. fields reason
methods throwIt
public uint reason The reason value associated with this exception object. public constructor MoteException () Create exception object with reason code 0 public constructor MoteException (uint reason) Create exception object with some reason code Parameters type uint
name reason
documentation The reason code to be set.
public static method throwIt (uint reason) Throw system singleton object. The singleton object will be adjusted to reflect this class and the specified reason code. Note, this is an efficient way of throwing exception without dymaically allocating memory. Parameters type uint
name reason
documentation
65
4.1.16
public class Mote
This class represents the mote itself. It allows to query properties global to the mote. fields TRANSIENT HEAP SIZE VMSTACK SIZE FWBUILD PLATFORM ANY PLATFORM RZUSBSTICK PLATFORM CORTEX DEBUG ERROR
TRANSIENT HEAP FREE VMSTACK FREE PLATFORM PLATFORM IRIS PLATFORM NICTOR PLATFORM WASPMOTE INFO
TRANSIENT HEAP UNIT FWVERSION BATTERY STATUS PLATFORM AVRRAVEN PLATFORM DUSTNETWORKS PLATFORM MSP430 WARN
methods queryInfo
log
reset
public static sealed uint TRANSIENT HEAP SIZE [default: 0x01] Query total size of transient heap in transient heap units. Heaps can be bigger than 64K and size are then expresses in multiples of heap units. public static sealed uint TRANSIENT HEAP FREE [default: 0x02] Query free size of the transient heap. public static sealed uint TRANSIENT HEAP UNIT [default: 0x03] Query size of a transient heap unit. This is always a power of 2. public static sealed uint VMSTACK SIZE [default: 0x04] Query total size of VM stack in bytes. public static sealed uint VMSTACK FREE [default: 0x05] Query free size of VM stack in bytes. public static sealed uint FWVERSION [default: 0x06] Query firmware version. Returned 16-bit value encodes in high 8-bit the major version and in low 8-bit the minor version.
66
public static sealed uint FWBUILD [default: 0x07] Query firmware build identifier. Returned 16-bit value is a unique number that identifies the firmware build. public static sealed uint PLATFORM [default: 0x08] Query platform identifier. Returned 16-bit value describes the underlying hardware platform. public static sealed uint BATTERY STATUS [default: 0x09] Battery status. Returned 16-bit value with the following bits: Bits 0-7 specify the battery charge, where 1-255 maps to 1Bit 15: 1=mains powered. Bit 14: 1=charging. Bit 13: 1=critical low power. public static sealed uint PLATFORM ANY [default: 0x00] Unspecified public static sealed uint PLATFORM IRIS [default: 0x01] Crossbow Iris mote public static sealed uint PLATFORM AVRRAVEN [default: 0x03] Atmel Raven development kit LCD module public static sealed uint PLATFORM RZUSBSTICK [default: 0x04] Atmel Raven development kit USB stick public static sealed uint PLATFORM NICTOR [default: 0x05] Nictor Mote Platform public static sealed uint PLATFORM DUSTNETWORKS [default: 0x06] Dust Networks / ucOS-II public static sealed uint PLATFORM CORTEX [default: 0x07] ARM Cortex public static sealed uint PLATFORM WASPMOTE [default: 0x08] Libelium Waspmote
67
public static sealed uint PLATFORM MSP430 [default: 0x09] MSP430 public static sealed byte DEBUG [default: 0x01] Severity level for log messages. public static sealed byte INFO [default: 0x02] Severity level for log messages. public static sealed byte WARN [default: 0x03] Severity level for log messages. public static sealed byte ERROR [default: 0x04] Severity level for log messages. public static uint queryInfo (uint mode) Query state of system resources or other settings. Parameters type uint
name mode
documentation
Return Value uint
public static method log (byte[] msg,byte len) Report some message to some attached media. It is device specific where this message is displayed. On motes attached via LIP (serial cable, USB) or WLIP (radio equivalent for a cale) to some host this message is forwarded to the host side software stack which will display it. On purely wireless motes this message is either shown on a local display or is silently discarded. There is an optional assembly that helps formatting log messages. This is a barebones method to avoid increasing system footprint with debug related features. The auxiliary logger assembly provides as more comfortable API while consuming some addiotional system resources (some flash, and a buffer for the assembled log message).
68
Parameters type byte[]
name msg
byte
len
documentation This buffer holds the log message. The first byte encodes the severity level and the remaining bytes are the characters of a UTF-8 string. The byte array must be in transient memory. It must not be a persistent array. The length of the data in the buffer.
public static method reset () Reset the mote. This call does not return.
69
4.1.17
public sealed class LIP
This class represents a protocol linking this mote to some host (LIP = LInk Protocol). The link usually is a serial or USB cable. If a USB cable is being used then either a Serial (RS232) over USB or the HID (Human Interface Device) protocol is being used depending on the hardware capabilities of the mote. There is also a wireless link protocol which allows to do maintenance without having to hook motes up to a cable. It is a very simple, single hop, not power efficient protocol meant only for setting up motes. A link data frame consists of a header and some payload. The interpretation of the host specific parts (first 6 bytes) are dependent on the host software. Normally, the first four bytes are interpreted as a IPv4 host address and the next two bytes are a UDP port number (both in big endian byte order). The last byte of the header is the LIP port number on the mote. The first 64 ports (0 - 63) are reserved for addressing assemblies using their assembly id. The assembly id depends on the load order. The Mote Manager can be queried to report a list of assembly id and assembly idendities (major.minor/name/build). Ports above 63 can be opened freely by assemblies. Bytes Symbol Description 0..3 HOST ADDR=0 Host address (32 bit, big endian) 4..5 HOST PORT=4 Host port (16 bit, big endian) 6 MOTE PORT=6 Link port on Mote (8 bit) 7.. PAYLOAD Start of payload fields HOST ADDR PAYLOAD RS232 WLIPBC
HOST PORT ANY PORT HID
MOTE PORT NONE WLIP
methods dispatch setDataHandler open send
makeHeader getPort getMaxPDU isAvailable
send close send
public static sealed uint HOST ADDR [default: 0x00] Offset to 32 bit host address. public static sealed uint HOST PORT [default: 0x04] Offset to 16-bit host port. public static sealed uint MOTE PORT [default: 0x06] Offset to 8 bit mote port. 70
public static sealed uint PAYLOAD [default: 0x07] Offset to payload of link data frame. public static sealed uint ANY PORT [default: 0x00] Application wants to open an arbitrary free LIP port. public static sealed int NONE [default: 0x00] No link protocol available. public static sealed int RS232 [default: 0x01] Link protocol uses a serial protocol RS232. public static sealed int HID [default: 0x02] Link protocol uses a HID (Human Interface Device protocol) over USB. public static sealed int WLIP [default: 0x03] Link protocol uses a wireless protocol to mimick a host link. public static sealed int WLIPBC [default: 0x04] Protocol indicator: WLIP message received via broadcast. public static int dispatch (int flags,byte[] data,uint len) Called by the OS to dispatch incoming link protocol messages. Parameters type int
name flags
byte[] uint
data len
documentation This value denotes the link or underlying protocol that received the frame. The data buffer holding the message to be dispatched. The length of the data in bytes.
Return Value int
71
public static method makeHeader (uint handle,long hostAddr,uint hostPort,byte[] buf,uint off) Create the seven byte LIP header structure.The mote port information is inserted into the header. Parameters type uint long uint byte[] uint
name handle hostAddr hostPort buf off
documentation A valid LIP port handle obtained by DataHandler)v. The host address information. The host port being addressed by the LIP frame. The buffer receiving the header structure. The offset where the inserted header starts.
public static method send (uint handle,byte[] msgbuf,uint msgbeg,uint msglen) Send some LIP message. The source port information is inserted by this method. The destination (first 6 bytes) must be provided the caller. Parameters type uint byte[] uint uint
name handle msgbuf msgbeg msglen
documentation A valid LIP port handle obtained by DataHandler)v. The buffer holding the message to be sent. The start index of the message. The length of the message.
public static method setDataHandler (uint handle,DataHandler dh) Set the method which handles incoming data. This callback is used to process data packets. If no such a callback is registered then incoming messages are dropped. Parameters type uint
name handle
DataHandler
dh
documentation The handle to access port specific functionality obtained by DataHandler)v. A pointer to the method handling incoming data frames.The int value returned by the method indicates how many bytes are sent back.
public static byte getPort (uint handle) Retrieve the port number.
72
Parameters type uint
name handle
documentation The handle to access port specific functionality obtained by DataHandler)v.
Return Value byte
public static method close (uint handle) Close the LIP port. Parameters type uint
name handle
documentation The handle to access port specific functionality obtained by DataHandler)v.
public static uint open (byte port,DataHandler dh) Open a new link protocol port. Parameters type byte
name port
DataHandler
dh
documentation The port number to open. A value ANY PORT lets the system chose any free port number. Data handler function. Called when LIP data frames arrive.
Return Value uint
A handle for access to port specific functionality, e.g., DataHandler)v .
Exceptions exception com.ibm.saguaro.system.ArgumentException If the specified port is already used (reason code RESOURCE BUSY) or if the number is illegal (ILLEGAL VALUE). You should use only ports greater than 1024. public static uint getMaxPDU () Query the maximum PDUs size the LIP is capabable of transporting (in/out).
73
Return Value uint
public static method send (byte[] msgbuf,uint msgbeg,uint msglen) Send some LIP message. The first few bytes describe the destination (6 bytes) of the message. The interpretation is dependent on the off-mote software running on the host. Usually, the first 4 bytes are viewed as an IPv4 host address in big endian byte order and the subsequent 2 bytes are a UDP port number (also big endian). The next byte is the sender LIP port on the mote. Parameters type byte[] uint uint
name msgbuf msgbeg msglen
documentation The buffer holding the message to be sent. The start index of the message. The length of the message.
public static method send (byte[] header,uint hdrlen,byte[] msgbuf,uint msgbeg,uint msglen) Send some LIP message. This function concatenates the contents of the two buffers and sends it. The first buffer can be used to prefix some header while the second buffer contains data provided elsewhere. This goal of this two buffer API is to save data copying. Parameters type byte[] uint byte[] uint uint
name header hdrlen msgbuf msgbeg msglen
documentation A buffer holding the first part of the message to be sent. Length of the first part. It starts at index zero. A buffer holding the second part of message to be sent. The start index of 2nd part. The length of 2nd part.
public static int isAvailable () Is LIP available (aka is the mote attached to some wired link (e.g. serial/USB). Return Value int
The type of link protocol available (i.e., none, RS232, HID, or WLIP)
74
4.1.18
public class LED
LED - Light emitting diode. methods getNumLEDs getState
getColor
setState
public static uint getNumLEDs () Retrieve the number of LEDs available on this mote. Return Value uint
public static byte getColor (byte no) Retrieve the color of some LED. The 8 bits of the returned value is encoded like this ZZRRGGBB where R=red, G=green, B=blue, and Z=0. Z!=0 is RFU Parameters type byte
name no
documentation
Return Value byte
public static method setState (byte no,byte state) Set the state of some LEDs: 0=off, 1=on Parameters type byte byte
name no state
documentation
public static uint getState (byte no) Retrieve the state of some LED: 0=off, 1=on
75
Parameters type byte
name no
documentation
Return Value uint
76
4.1.19
public class InvalidCastException
Runtime cast check failed. This exception usually has a zero reason code. methods throwIt
public constructor InvalidCastException (uint reason) Parameters type uint
name reason
documentation
public static method throwIt (uint reason) Parameters type uint
name reason
documentation
77
4.1.20
public class IndexOutOfRangeException
Some array index was greater or equal to the array length. Note, Mote Runner treats array indices as unsigned integers. Signed integers are array indices are implicitly cast to unsigned integer by the system. Thus, a negative integer v is reinterpreted by the system as an index 65536-v. Usually, this exception has a reason code of zero. methods throwIt
public static method throwIt (uint reason) Parameters type uint
name reason
documentation
78
4.1.21
public sealed class Err
Symbolic names for error constants used throughout various APIs. fields TOO LATE NO BUFFERS ILLEGAL VALUE RESOURCES BUSY
TOO SMALL BAD ALIGNMENT NOT SUPPORTED TABLE FULL
TOO BIG PERSISTENT OBJECT NULL REFERENCE
public static sealed uint TOO LATE [default: 0xf3] public static sealed uint TOO SMALL [default: 0xe8] public static sealed uint TOO BIG [default: 0xb8] public static sealed uint NO BUFFERS [default: 0xc4] public static sealed uint BAD ALIGNMENT [default: 0xc8] public static sealed uint PERSISTENT OBJECT [default: 0xb3] public static sealed uint ILLEGAL VALUE [default: 0xd8] public static sealed uint NOT SUPPORTED [default: 0xa9] public static sealed uint NULL REFERENCE [default: 0x87] public static sealed uint RESOURCES BUSY [default: 0xd3] public static sealed uint TABLE FULL [default: 0xb4]
79
4.1.22
sealed public delegate DataHandler
A generic callback delegate used to notify about some data. methods com.ibm.saguaro.system
public abstract int DataHandler (int info,byte[] data,uint len) A generic callback delegate used to notify about some data. Parameters type int byte[] uint
name info data len
documentation Some info value accompanying the data. A byte array holding some data. The length of the relevant data.
Return Value int
An application specific signed int. E.g., in the DataHandler set by DataHandler it is used to indicate the number of bytes to send back.
80
4.1.23
public sealed class Assembly
The super class of the runtime representation of an assembly. This is the superclass for all loaded assemblies. Assemblies are the basic load and management units for MoteRunner motes. They can be loaded, deleted, and configured using a communication protocol with the MoteManager. An assembly has a name, a version number (major/minor/build identifier), and contains a set of classes. It may expose these classes and methods for use by other assemblies. fields SYSEV DELETED
MAX ASMID
methods setSystemInfoCallback register getExecutingAsmId
setDataHandler getCallerAsmId getAsmObj
setCalleeAsActive getActiveAsmId setMeAsActive
public static sealed int SYSEV DELETED [default: 0x01] System event: assembly is scheduled for delete. Last change to clean some things up public static sealed uint MAX ASMID [default: 0x40] Legal assembly IDs range from 0..(MAX ASMID-1). Note, MAX ASMID is of the form 2ˆk with k¿=2. public static method setSystemInfoCallback (SystemInfo evcb) Set callback for system info events for the currently activated assembly. This callback is used by the operating system to interact with an assembly. It is used e.g. to signal certain system states. Parameters type SystemInfo
name evcb
documentation The delegate to be set for the currently activated assembly
public static method setDataHandler (DataHandler dh) Set callback for data frames addressed directly to this assembly. This callback is used by the LIP protocol to forward data packets to an assembly. If the assembly does not register such a callback then incoming messages are dropped.
81
Parameters type DataHandler
name dh
documentation The pointer to the method handling incoming data frame for the current assembly.
public static method setCalleeAsActive () The next method invocation will also change the active assembly to the called assembly. This property is valid only for the next call. If desired for more than one method invocation it needs to be requested before each call. If no method is being called this property is automatically cleared when the current method terminates. public static long register (Assembly asmobj) Constructor of system assembly object. This is called by an assembly specific instance subclassing this class. The call to this method is automatically generated by Saguaro assembler as part of the assembly constructor code. Calling this method a second time will result in an error. Parameters type Assembly
name asmobj
documentation The newly allocated assembly specific instance.
Return Value long
Exceptions exception com.ibm.saguaro.system.SystemException With reason code ALREADY DONE if the current assembly already has been registered public static byte getCallerAsmId () Query the system ID of the code having called the method performing the call this method. Return Value byte
Returns a valid assembly id (a value 0..MAX ASMID)
82
public static byte getActiveAsmId () Query system ID of currently activated assembly. This might differ from the assembly having called this method. Return Value byte
Returns a valid assembly id (a value 0..MAX ASMID)
public static byte getExecutingAsmId () Query system ID of assembly performing the call to this method. This might differ from the activated assembly. Return Value byte
Returns a valid assembly id (a value 0..MAX ASMID)
public static r:com.ibm.saguaro.system.Assembly getAsmObj (uint asmid) Retrieve the assemby object for a given id. Parameters type uint
name asmid
documentation The assembly id. Only the least k bits are evaluated. Where MAX ASMID=2ˆ k.
Return Value Assembly
Returns the assembly object or null if id is not in use.
public static method setMeAsActive () Make the assembly calling this method the active one. Certain access control in the OS checks against the currently active assembly. By default the active assembly is the one which got called when the VM started. This call can be used change the active assembly. The active assembly will be automatically reverted to one before this call when the method that called setMeAsActive() terminates.
83
4.1.24
public class ArrayTypeMismatchException
Array element type does not match array type. This exception has a reason code of zero. methods throwIt
public static method throwIt (uint reason) Parameters type uint
name reason
documentation
84
4.1.25
public class ArithmException
Arithmetic error (division by zero). This exception usually has a zero reason code. methods throwIt
public constructor ArithmException (uint reason) Parameters type uint
name reason
documentation
public static method throwIt (uint reason) Parameters type uint
name reason
documentation
85
4.1.26
public class ArgumentException
Some argument to a function was wrong. This exception usually has a non-zero reason code. fields BYTE ARRAY REQUIRED BAD ALIGNMENT
ARRAY TYPE REQUIRED ILLEGAL VALUE
TOO BIG TOO SMALL
methods throwIt
public static sealed uint BYTE ARRAY REQUIRED [default: 0x01] Some method parameter (declared as Object) is expected to be a bytearray object. public static sealed uint ARRAY TYPE REQUIRED [default: 0x02] Some method parameter (declared as Object) is expected to be of some array type. public static sealed uint TOO BIG [default: 0x03] Some method parameter is too big. public static sealed uint BAD ALIGNMENT [default: 0x04] Some method parameter expresses bad alignment. public static sealed uint ILLEGAL VALUE [default: 0x05] Some method parameter has illegal value. public static sealed uint TOO SMALL [default: 0x06] Some method parameter is too small. public constructor ArgumentException (uint reason) Parameters type uint
name reason
documentation
86
public static method throwIt (uint reason) Parameters type uint
name reason
documentation
87
4.1.27
public class AccessException
Access to an object or system resource denied. This exception usually has a non-zero reason code. fields READONLY OBJECT STORE TEMP OBJECT TOO LATE
RETURN STACK OBJECT RESOURCE BUSY
PERSISTENT OBJECT RESOURCE STALE
methods throwIt
public static sealed uint READONLY OBJECT [default: 0x01] Trying to modify an object flagged as read only. public static sealed uint RETURN STACK OBJECT [default: 0x02] Returning an object that was created in the current function on the stack. public static sealed uint PERSISTENT OBJECT [default: 0x03] Trying to modify a persistent object or access a persistent object where only transients allowed. public static sealed uint STORE TEMP OBJECT [default: 0x04] Trying to store the reference of a temporary object on other than stack. public static sealed uint RESOURCE BUSY [default: 0x05] Some resource is busy and can’t be accessed right now. public static sealed uint RESOURCE STALE [default: 0x06] Resource is stale. public static sealed uint TOO LATE [default: 0x07] Access is too late with respect to some deadline.
88
public constructor AccessException (uint reason) Parameters type uint
name reason
documentation
public static method throwIt (uint reason) Parameters type uint
name reason
documentation
89
Chapter 5
Baseterms 5.1
byte
Short Description Small unsigned integer type Long Description The type byte represents a 8 bit unsigned integer number. It can hold values from 0 (0x0) to 256 (0xFF). If you are programming in Java this type is signed (see sbyte). Java only has signed data types. Unsigned data type operations must be mimicked in Java (see uint).
5.2
byte[]
Short Description Array of small integer types. Long Description Objects of this type hold an array of octets interpreted as signed byte or unsigned byte values depending on type annotation. Both, byte and sbyte only exist for C# programmers. Java only defines byte and is equivalent to C#’s sbyte. At runtime there is no distinction between a byte[] and a sbyte[]. Both types refer to arrays holding octet values. You can convert between both array types at compile time using the following functions: sbyte[] com.ibm.saguaro.system.csr.byte2sbyte(byte[]) byte[] com.ibm.saguaro.system.csr.sbyte2byte(sbyte[])
90
5.3
sbyte
Short Description Small singed integer type Long Description The type sbyte represents a 8 bit signed integer number. It can hold values from -128 (0x80) to 127 (0x7F). This type name is only defined for C#. The equivalent type in Java is byte.
5.4
sbyte[]
Short Description Array of small integer types. Long Description See byte[].
5.5
int
Short Description Default signed integer type Long Description The type int represents a 16 bit signed integer number. It can hold values from -32768 (0x8000) to 32765 (0x7FFF). Note that runtime environments on big computers have a data size of 32 bit for this data type.
5.6
int[]
Short Description Array of integer types.
91
Long Description Objects of this type hold an array of 16-bit words interpreted as signed integer or unsigned integer values depending on type annotation. Both, int and uint only exist for C# programmers. Java only defines byte and is equivalent to C#’s sbyte. At runtime there is no distinction between a int[] and a uint[]. Both types refer to arrays holding 16-bit values. You can convert between both array types at compile time using the following functions: uint[] com.ibm.saguaro.system.csr.int2uint(int[]) int[] com.ibm.saguaro.system.csr.uint2int(uint[])
5.7
uint
Short Description Default unsigned integer type Long Description The type uint represents a 16 bit unsigned integer number. It can hold values from 0 to 65535 (0xFFFF). Mote Runner treats a number of system parameters and runtime elements as unsigned integer data types. E.g. array indices and lengths are unsigned int. If you program for Mote Runner in the Java language then you do not have an unsigned integer available. Although many operations are identical for signed and unsigned.
Operators
operators on uint
equivalent operations using int
+ - * & | ˆ << /% < <= > >= <<
a a a a
a op b ((long)a&0xFFFFL)op((long)b&0xFFFFL) (aˆ0x8000)op(bˆ0x8000) a <<