public class PtinyOSDirector extends Director
TinyOS is an event-driven operating system designed for sensor network nodes that have very limited resources (e.g., 8K bytes of program memory, 512 bytes of RAM). (More info at http://www.tinyos.net).
nesC is an extension to the C programming language designed to embody the structuring concepts and execution model of TinyOS. (More info at http://nescc.sourceforge.net).
TOSSIM is a C-based simulator for homogeneous TinyOS networks, where all nodes run the same TinyOS program. (More info at http://www.cs.berkeley.edu/~pal/research/tossim.html).
This version of the PtinyOSDirector is for use with TinyOS 1.x only. It is not compatible with TinyOS 2.x.
When embedded in a model containing nesC components (component descriptions converted to MoML from the TinyOS 1.x library using $PTII/ptolemy/domains/ptinyos/util/nc2moml/nc2moml), this director can generate the top-level nesC application file (.nc). This director can also compile the nesC application for use with any TinyOS 1.x-compatible hardware (e.g., mica), or for simulation within Ptolemy II.
When this director is used for code generation only, and not simulation, the user sets the PtinyOSDirector target parameter to a string such as "mica", "mica2", "pc", or another TinyOS 1.x-compatible target. The director will generate a nesC application file (.nc) and a makefile for the application.
When this director is used in simulation mode, the user sets the
PtinyOSDirector target parameter to the string "ptII". In
addition to the previously mentioned nesC application file (.nc)
and a makefile for the application, the director will generate a
Java loader file (.java). This loader file implements PtinyOSLoader
, which is used as a
wrapper for calls to JNI methods in TOSSIM. The director uses the
nesC compiler to compile the .nc file into a pre-processed C file.
It then uses a C compiler to compile the C file into a shared
object (the TOSSIM shared object). The C compiler is usually gcc,
though it can use another compiler if $PTCC (defined in
$PTII/mk/ptII.mk and used in
$TOSROOT/contrib/ptII/ptinyos/tools/make/ptII/ptII.rules) is
modified. The director then uses the Java compiler to compile the
Java loader file into a .class file. Finally, this director loads
the resulting .class using the Java loader, which loads the TOSSIM
shared object.
For more information on compilation rules, see: $TOSROOT/contrib/ptII/ptinyos/tools/make/ptII/ptII.rules
TOSSIM contains its own discrete event simulation engine, which consists of a main scheduling loop and a discrete event queue. Events in this queue are ordered by timestamp, which is implemented as a long long (a 64-bit integer on most systems; this is a standard type used in gcc). The timestamp value is a representation of the number of ticks of a 4 MHz clock (the original CPU frequency of the Rene/Mica motes). After initializing its data structures and performing other initialization routines, TOSSIM creates a boot-up event and places the event in its event queue. The version of TOSSIM compiled by this director contains additional calls that are not in the original version of TOSSIM. These calls are JNI calls that cause the TOSSIM scheduler to communicate all events to the PtinyOSDirector, and allow events (and sensor values) generated by Ptolemy II to be passed to the TOSSIM scheduler.
Since TOSSIM operates on a 4MHz clock, users will usually set the timeResolution parameter of this director to the value 0.25E-6, since TOSSIM cannot detect changes in sensor values with time differences less than this time resolution.
When the nesC compiler generates the pre-processed C file for TOSSIM, it automatically generates support for homogeneous networks by instrumenting all component state variables with an array. The array stores the state for each node. Therefore, array index 0 stores the state for node 0, and so on. This director only uses one node per instance of TOSSIM, and hence, only uses array index 0 for all variables. Models containing multiple nodes are created by using a separate PtinyOSDirector (and hence a separate instance of TOSSIM) for each node. In TOSSIM, node 0 is the base station, which is the sink for routing. This director overrides the built-in id number using the nodeID and baseStation parameters, and passes a node ID value to the nesC compiler so that it is hard coded into TOSSIM.
TOSSIM uses TCP/IP sockets attached to network ports for commands and events in order to communicate with external tools, such as TinyViz, a Java-based visualization tool for TOSSIM. We retain these ports for backwards compatibility with TinyViz and other tools. The port numbers are set in commandPort and eventPort. Because of limitations in the implementation of TOSSIM, a separate instance of TinyViz must be attached to each instance of TOSSIM.
NamedObj.ContainedObjectsIterator
Modifier and Type | Field and Description |
---|---|
SharedParameter |
baseStation
Specifies the name of the base station as a string value.
|
Parameter |
bootTimeRange
TOSSIM setting for the number of seconds over which nodes may
boot.
|
PtinyOSNodeParameter |
commandPort
Port number for the TOSSIM command server socket.
|
Parameter |
confirmOverwrite
Flag to ask for confirmation before overwriting.
|
FileParameter |
destinationDirectory
Output directory for generated code.
|
Parameter |
eventPort
Port number for the TOSSIM event server socket.
|
PtinyOSNodeParameter |
nodeID
Node ID of this node.
|
Parameter |
numberOfNodes
Number of nodes to simulate per instance of TOSSIM.
|
StringParameter |
pflags
Additional flags passed to the nesC compiler.
|
SharedParameter |
simulate
Flag for choosing whether to simulate the model in ptII.
|
StringParameter |
target
Compilation target for the generated nesC code.
|
FileParameter |
tosDir
Path to the tos directory of the TinyOS tree.
|
FileParameter |
tosRoot
Path to the root of the TinyOS tree.
|
_actorsFinishedExecution, _aspectForActor, _aspectsPresent, _defaultMicrostep, _executionAspects, _finishRequested, _initializables, _nextScheduleTime, _stopRequested, _tokenSentToCommunicationAspect, _zeroTime, localClock, startTime, stopTime
_changeListeners, _changeLock, _changeRequests, _debugging, _debugListeners, _deferChangeRequests, _elementName, _isPersistent, _verbose, _workspace, ATTRIBUTES, CLASSNAME, COMPLETE, CONTENTS, DEEP, FULLNAME, LINKS
COMPLETED, NOT_READY, STOP_ITERATING
Constructor and Description |
---|
PtinyOSDirector()
Construct a director in the default workspace with an empty string
as its name.
|
PtinyOSDirector(CompositeEntity container,
java.lang.String name)
Construct a director with the specified container and name.
|
PtinyOSDirector(Workspace workspace)
Construct a director in the workspace with an empty name.
|
Modifier and Type | Method and Description |
---|---|
java.nio.channels.SocketChannel |
acceptConnection(java.nio.channels.SelectableChannel serverSocketChannel)
Accept a connection on a
java.nio.channels.ServerSocketChannel.
|
void |
enqueueEvent(java.lang.String newTime)
Enqueue the next TOSSIM event into ptII at the specified time
by calling fireAt().
|
void |
fire()
If the
simulate parameter is true, process one event in
the TOSSIM event queue and run tasks in task queue. |
char |
getCharParameterValue(java.lang.String parameter)
Get a DoubleToken from the named parameter and convert it
to a char.
|
void |
initialize()
If the
simulate parameter is true, then load the
TOSSIM shared library and call TOSSIM main(), by using Java
loader calls. |
boolean |
postfire()
Return true if simulation is requested, so that simulated
event handling can proceed.
|
void |
preinitialize()
Generate nesC code in a .nc file.
|
void |
receivePacket(java.lang.String packet)
If the
simulate parameter is true, notify the loader
that a packet has been received. |
void |
selectorClose(java.nio.channels.Selector selector)
Close the java.nio.channels.Selector.
|
java.nio.channels.Selector |
selectorCreate(java.net.ServerSocket serverSocket,
boolean opAccept,
boolean opConnect,
boolean opRead,
boolean opWrite)
Create a java.nio.channels.Selector and register the
ServerSocketChannel of the ServerSocket with the Selector.
|
void |
selectorRegister(java.nio.channels.Selector selector,
java.nio.channels.SelectableChannel socketChannel,
boolean opAccept,
boolean opConnect,
boolean opRead,
boolean opWrite)
Register the channel with the java.nio.channels.Selector.
|
java.nio.channels.SelectableChannel |
selectSocket(java.nio.channels.Selector selector,
boolean[] notNullIfClosing,
boolean opAccept,
boolean opConnect,
boolean opRead,
boolean opWrite)
Returns a selected channel, or null if none found.
|
boolean |
sendToPort(java.lang.String portName,
java.lang.String expression)
Send an expression to a ptII port.
|
void |
serverSocketClose(java.net.ServerSocket serverSocket)
Close the java.net.ServerSocket.
|
java.net.ServerSocket |
serverSocketCreate(short port)
Create a non-blocking server socket and check for connections on the
port specified by port.
|
void |
socketChannelClose(java.nio.channels.SelectableChannel socketChannel)
Close the java.nio.channels.SocketChannel.
|
int |
socketChannelRead(java.nio.channels.SocketChannel socketChannel,
byte[] readBuffer)
Read from a java.nio.channels.SocketChannel into readBuffer.
|
int |
socketChannelWrite(java.nio.channels.SocketChannel socketChannel,
byte[] writeBuffer)
Write the bytes in writeBuffer to a
java.nio.channels.SocketChannel.
|
void |
tosDebug(java.lang.String debugMode,
java.lang.String message,
java.lang.String nodeID)
Print a debug message.
|
void |
wrapup()
If the
simulate parameter is true, call wrapup() in
TOSSIM to shut down threads created in initialize(). |
_actorFinished, _consultTimeRegulators, _description, _isEmbedded, _isTopLevel, _schedule, _transferInputs, _transferOutputs, addInitializable, attributeChanged, clone, createSchedule, defaultDependency, delayDependency, elapsedTimeSinceStart, finish, fireAt, fireAt, fireAt, fireAtCurrentTime, fireContainerAt, fireContainerAt, getCausalityInterface, getCurrentTime, getDeadline, getEnvironmentTime, getExecutionAspect, getGlobalTime, getModelNextIterationTime, getModelStartTime, getModelStopTime, getModelTime, getNextIterationTime, getStartTime, getStopTime, getTimeResolution, implementsStrictActorSemantics, initialize, invalidateResolvedTypes, invalidateSchedule, isEmbedded, isFireFunctional, isStopRequested, isStrict, iterate, mutexLockObject, newReceiver, notifyTokenSentToCommunicationAspect, prefire, preinitialize, removeInitializable, requestInitialization, resume, resumeActor, scheduleContainedActors, setContainer, setCurrentTime, setEmbedded, setModelTime, setTimeResolution, stop, stopFire, suggestedModalModelDirectors, supportMultirateFiring, suspend, terminate, transferInputs, transferOutputs, transferOutputs
_checkContainer, _getContainedObject, _propagateExistence, getContainer, moveDown, moveToFirst, moveToIndex, moveToLast, moveUp, setName, updateContent
_addAttribute, _adjustOverride, _attachText, _cloneFixAttributeFields, _containedDecorators, _copyChangeRequestList, _debug, _debug, _debug, _debug, _debug, _executeChangeRequests, _exportMoMLContents, _getIndentPrefix, _isMoMLSuppressed, _markContentsDerived, _notifyHierarchyListenersAfterChange, _notifyHierarchyListenersBeforeChange, _propagateValue, _removeAttribute, _splitName, _stripNumericSuffix, _validateSettables, addChangeListener, addDebugListener, addHierarchyListener, attributeDeleted, attributeList, attributeList, attributeTypeChanged, clone, containedObjectsIterator, decorators, deepContains, depthInHierarchy, description, description, event, executeChangeRequests, exportMoML, exportMoML, exportMoML, exportMoML, exportMoML, exportMoMLPlain, getAttribute, getAttribute, getAttributes, getChangeListeners, getClassName, getDecoratorAttribute, getDecoratorAttributes, getDerivedLevel, getDerivedList, getDisplayName, getElementName, getFullName, getModelErrorHandler, getName, getName, getPrototypeList, getSource, handleModelError, isDeferringChangeRequests, isOverridden, isPersistent, lazyContainedObjectsIterator, message, notifyOfNameChange, propagateExistence, propagateValue, propagateValues, removeAttribute, removeChangeListener, removeDebugListener, removeHierarchyListener, requestChange, setClassName, setDeferringChangeRequests, setDerivedLevel, setDisplayName, setModelErrorHandler, setPersistent, setSource, sortContainedObjects, toplevel, toString, uniqueName, validateSettables, workspace
public SharedParameter baseStation
public Parameter bootTimeRange
public PtinyOSNodeParameter commandPort
public Parameter confirmOverwrite
public FileParameter destinationDirectory
public Parameter eventPort
public PtinyOSNodeParameter nodeID
public Parameter numberOfNodes
public StringParameter pflags
public SharedParameter simulate
public StringParameter target
public FileParameter tosDir
public FileParameter tosRoot
public PtinyOSDirector() throws IllegalActionException, NameDuplicationException
NameDuplicationException
- If construction of Time objects fails.IllegalActionException
- If construction of Time objects fails.public PtinyOSDirector(Workspace workspace) throws IllegalActionException, NameDuplicationException
workspace
- The workspace of this object.NameDuplicationException
- If construction of Time objects fails.IllegalActionException
- If construction of Time objects fails.public PtinyOSDirector(CompositeEntity container, java.lang.String name) throws IllegalActionException, NameDuplicationException
container
- The container.name
- The name of the director.IllegalActionException
- If the director is not of an
acceptable attribute for the container.NameDuplicationException
- If the name coincides with
an attribute already in the container.public void enqueueEvent(java.lang.String newTime)
This is a JNI method that gets called by TOSSIM through the Java loader.
newTime
- A string representation of the time of the next
event. In TOSSIM, unit of time is a tick of a 4MHz clock, and
time is stored in a long long in C (a 64-bit integer on most
systems).public void fire() throws IllegalActionException
simulate
parameter is true, process one event in
the TOSSIM event queue and run tasks in task queue. This
method gets the model time from the director and calls PtinyOSLoader.processEvent(long)
with the time as the argument, which invokes TOSSIM.fire
in interface Executable
fire
in class Director
IllegalActionException
- If the fire() method of the
super class throws it, or getting a token from the
simulateparameter throws it.public char getCharParameterValue(java.lang.String parameter)
This is a JNI method that gets called by TOSSIM through the Java loader to get a sensor value.
parameter
- The parameter.public void initialize() throws IllegalActionException
simulate
parameter is true, then load the
TOSSIM shared library and call TOSSIM main(), by using Java
loader calls.
The sequence of calls is as follows (assuming simulate is true):
initialize
in interface Initializable
initialize
in class Director
IllegalActionException
- If there is a problem initializing
the director, such as a problem loading the JNI loader.public boolean postfire() throws IllegalActionException
postfire
in interface Executable
postfire
in class Director
IllegalActionException
- If thrown while reading the
simulate parameter.public void preinitialize() throws IllegalActionException
target
parameter is
non-empty then a .java loader file and a makefile are created.
This methods then compiles the .nc and .java files by calling
make. The .java file implements the PtinyOSLoader
interface.
The sequence of calls is as follows:
preinitialize
in interface Initializable
preinitialize
in class Director
IllegalActionException
- If the container is not
an instance of CompositeActor, the destination directory
does not exist and cannot be created, or the nesC file
cannot be written.public void receivePacket(java.lang.String packet) throws IllegalActionException
simulate
parameter is true, notify the loader
that a packet has been received. The PtinyOSCompositeActor.fire()
method calls this method with the string value of the input
packet.
The sequence of calls is as follows:
This is a wrapper for a native method, where the PtinyOSDirector calls this method (Java) to activate routines in TOSSIM (C).
packet
- The string value of the packet to send to TOSSIM.IllegalActionException
- If there is a problem reading
the simulate
parameter.public boolean sendToPort(java.lang.String portName, java.lang.String expression)
This is a JNI method that gets called by TOSSIM through the Java loader to send a value to a ptII port.
The sequence of calls is as follows:
portName
- The name of the port.expression
- The expression to send to the ptII port.public void tosDebug(java.lang.String debugMode, java.lang.String message, java.lang.String nodeID)
This is a JNI method that gets called by TOSSIM through the Java loader to print a debug message.
debugMode
- A long long in C (currently unused).message
- A char * in C.nodeID
- A short in C.public void wrapup() throws IllegalActionException
simulate
parameter is true, call wrapup() in
TOSSIM to shut down threads created in initialize().
The sequence of calls is as follows:
This is a wrapper for a native method, where the PtinyOSDirector calls this method (Java) to activate routines in TOSSIM (C).
wrapup
in interface Initializable
wrapup
in class Director
IllegalActionException
- If the wrapup() method of
one of the associated actors throws it.public java.nio.channels.SocketChannel acceptConnection(java.nio.channels.SelectableChannel serverSocketChannel)
This is a JNI method that gets called by TOSSIM through the Java loader.
serverSocketChannel
- The ServerSocketChannel on which
connections are accepted.public void selectorClose(java.nio.channels.Selector selector)
This is a JNI method that gets called by TOSSIM through the Java loader.
selector
- The Selector that should be closed.public java.nio.channels.Selector selectorCreate(java.net.ServerSocket serverSocket, boolean opAccept, boolean opConnect, boolean opRead, boolean opWrite)
This is a JNI method that gets called by TOSSIM through the Java loader.
serverSocket
- The ServerSocket whose channel should be
registered with the Selector created.opAccept
- True if this SelectionKey option should be
enabled when registering the ServerSocketChannel to the
Selector.opConnect
- True if this SelectionKey option should be
enabled when registering the ServerSocketChannel to the
Selector.opRead
- True if this SelectionKey option should be
enabled when registering the ServerSocketChannel to the
Selector.opWrite
- True if this SelectionKey option should be
enabled when registering the ServerSocketChannel to the
Selector.public void selectorRegister(java.nio.channels.Selector selector, java.nio.channels.SelectableChannel socketChannel, boolean opAccept, boolean opConnect, boolean opRead, boolean opWrite)
This is a JNI method that gets called by TOSSIM through the Java loader.
selector
- The selector to which the channel should be
registered.socketChannel
- The SocketChannel that should be
registered.opAccept
- True if this SelectionKey option should be
enabled when registering the SocketChannel to the Selector.opConnect
- True if this SelectionKey option should be
enabled when registering the SocketChannel to the Selector.opRead
- True if this SelectionKey option should be
enabled when registering the SocketChannel to the Selector.opWrite
- True if this SelectionKey option should be
enabled when registering the SocketChannel to the Selector.public java.nio.channels.SelectableChannel selectSocket(java.nio.channels.Selector selector, boolean[] notNullIfClosing, boolean opAccept, boolean opConnect, boolean opRead, boolean opWrite)
selectorClose(Selector)
, Selector.close() is
called, but because of a bug in J2SE described in http://forum.java.sun.com/thread.jspa?threadID=293213&messageID=2671029,
the call to Selector.close() in selectorClose(Selector)
may never return because a thread is
blocked in the call to Selector.select() in this method. So,
selectorClose(Selector)
also calls Selector.wakeup(),
but we have to make sure that this method (and the call to
Selector.select()) is not called again, before the Selector is
closed, especially since the call to this method will usually
be in a loop. We use notNullIfClosing as a flag to indicate
that this method should not be called again. We assume that
notNullIfClosing is a boolean array of at least size 1.
notNullIfClosing[0] is set to true if this method should not
be called again, otherwise it is not modified.
This is a JNI method that gets called by TOSSIM through the Java loader.
selector
- The channel selector.notNullIfClosing
- notNullIfClosing[0] set to TRUE if
returning NULL, otherwise left as is.opAccept
- True if this SelectionKey option should be
enabled when returning a non-null SelectableChannel.opConnect
- True if this SelectionKey option should be
enabled when returning a non-null SelectableChannel.opRead
- True if this SelectionKey option should be
enabled when returning a non-null SelectableChannel.opWrite
- True if this SelectionKey option should be
enabled when returning a non-null SelectableChannel.public void serverSocketClose(java.net.ServerSocket serverSocket)
This is a JNI method that gets called by TOSSIM through the Java loader.
serverSocket
- The ServerSocket to be closed.public java.net.ServerSocket serverSocketCreate(short port)
This is a JNI method that gets called by TOSSIM through the Java loader.
port
- The port number on which to create a server
socket.public void socketChannelClose(java.nio.channels.SelectableChannel socketChannel)
This is a JNI method that gets called by TOSSIM through the Java loader.
socketChannel
- The SocketChannel to close.public int socketChannelRead(java.nio.channels.SocketChannel socketChannel, byte[] readBuffer)
This is a JNI method that gets called by TOSSIM through the Java loader.
socketChannel
- SocketChannel from which to read.readBuffer
- The bytes read.public int socketChannelWrite(java.nio.channels.SocketChannel socketChannel, byte[] writeBuffer)
This is a JNI method that gets called by TOSSIM through the Java loader.
socketChannel
- The SocketChannel on which to write.writeBuffer
- The bytes to write.