]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - doc/txt/tep114.txt
debug: add cfprintf macro
[tinyos-2.x.git] / doc / txt / tep114.txt
index 56e975914c8255cb33e7a1fb750c492c167e37fb..235bf78794a73a5b690b3739c806501bc70de4e9 100644 (file)
@@ -5,15 +5,10 @@ SIDs: Source and Sink Independent Drivers
 :TEP: 114
 :Group: Core Working Group
 :Type: Documentary 
-:Status: Draft
+:Status: Final
 :TinyOS-Version: 2.x
 :Author: Gilman Tolle, Philip Levis, and David Gay
 
-:Draft-Created: 30-Oct-2005
-:Draft-Version: $Revision$
-:Draft-Modified: $Date$
-:Draft-Discuss: TinyOS Developer List <tinyos-devel at mail.millennium.berkeley.edu>
-
 .. Note::
 
    This memo documents a part of TinyOS for the TinyOS Community, and
@@ -30,15 +25,16 @@ for data sources and sinks in TinyOS 2.x.
 1. Introduction
 ====================================================================
 
-Sensing is an integral part of any sensor network application.  Having
-a wide variety of sensor interfaces usually does not impose a large
-burden on an application developer, as any given application uses a
-small and static set. However, applications often build on top of more
-general systems, such as management or database layers, which may need
-to sample sensors. Since these are general and sensor-independent
-systems, they require a sensor-independent interface. TinyOS 2.0
-therefore has telescoping sensor abstractions, providing both simple
-and sensor-independent as well as sensor-specific interfaces.
+Sensing is an integral part of any sensor network application. The
+diversity of sensors can lead to a wide variety of different software
+interfaces to these sensors. However, the burden of connecting a
+general sensor data management application to every one of these
+different interfaces suggests that sensors also provide a simple,
+general-purpose interface for data acquisition. Therefore, TinyOS 2.0
+has telescoping sensor abstractions, providing both sensor-independent
+and sensor-specific interfaces. This memo documents a set of hardware-
+and sensor-independent interfaces for data sources and sinks in TinyOS
+2.x.
 
 2. Sensors in TinyOS 1.x
 ====================================================================
@@ -52,54 +48,71 @@ interrupt-driven sampling.  All of its commands and events are async
 and sensor values are always 16 bits, although only some subset of the
 bits may be significant (e.g., a 12-bit value).
 
-Because sensing can be a part of high-level application logic,
-the asynchronicity of these events means that high-level components
-must deal with atomic sections and possible race conditions, even
-if the sampling rate is very low (e.g., every five minutes)
-and so could be easily placed in a task.
+Because sensing is an integral part of high-level application logic,
+having asynchronous events means that high-level components
+must work with atomic sections, even if the sampling rate is very low
+(e.g., every five minutes) and so could be easily placed in a
+task. Race conditions are problematic and possible in any real time
+multi-tasking design. Race conditions are a failure in design, and
+especially difficult to detect at low sampling rates. 
 
 Additionally, not all sensors require ADC conversions from the MCU.
 Many sensors today are digital. To sample these sensors, the MCU sends
 a sample command and receives the corresponding data over a bus (e.g.,
 SPI, I2C). The latency involved, combined with possible Resource
-arbitration [_tep108], means that these bus operations are often
+arbitration [1]_, means that these bus operations are often
 synchronous code. In the command direction, this can force a task
 allocation to convert async to sync; in the event direction, the
 application has to deal with async code even though the event is, in
 practice, in a task.
 
-Finallly, the simplicity of the ADC interface has led many sensors to
-introduce several new ones for calibration and control, such as
-``Mic`` and ``MagSetting``. Because ADCs generally do not have error
-conditions, the ADC interface has no way to signal that a sample
-failed. This turns out to be important for sensors where the sampling
-request is split-phase, such as sensors over a bus. In these cases, it
-is possible that the driver accepts the request to sample, but once
-acquiring the bus discovers something is wrong with the sensor. This
-property has led bus-based sensors to also have a separate
-``ADCError`` interface; this interface breaks the basic TinyOS pattern
-of a tight coupling between split-phase commands and their completion
-events, as the command is in ADC but the completion event is in
-ADCError.
-
-All of these complications can make it difficult to write high-level
-code that is sensor independent, unless the sensor is a simple ADC
-reading. Sensors, when possible, should follow an approach similar to
-the HAA[_haa], where they have sensor- or sensor-class-specific
-interfaces for high performance or special case use, but also simple
-and common interfaces for basic and portable use. Providing a
-telescoping sensor abstraction allows both classes of use.
+Finally, the simplicity of the ADC interface has led many sensor
+modules to introduce several new interfaces for calibration and
+control, such as ``Mic`` and ``MagSetting``. Because ADCs generally do
+not have error conditions, the ADC interface has no way to signal that
+a sample failed. This turns out to be important for sensors where the
+sampling request is split-phase, such as sensors over a bus. In these
+cases, it is possible that the driver accepts the request to sample,
+but once acquiring the bus discovers something is wrong with the
+sensor. This property has led bus-based sensors to also have a
+separate ``ADCError`` interface; this interface breaks the basic
+TinyOS pattern of a tight coupling between split-phase commands and
+their completion events, as the command is in ADC but the completion
+event is in ADCError.
+
+All of these complications provide the context of the challenge to
+write high-level code that is sensor independent. Sensors, when
+possible, should follow an approach similar to the HAA[_haa], where
+they have sensor- or sensor-class-specific interfaces for high
+performance or special case use, but also simple and common interfaces
+for basic and portable use. Providing a telescoping sensor abstraction
+allows both classes of use.
 
 3. Sensors in TinyOS 2.x
 ====================================================================
 
-TinyOS 2.x has several sensor-independent interfaces, which cover a
-range of common use cases. These interfaces can be used to write a
-Source- or Sink-Independent Driver (SID). A SID is source/sink
-independent because its interfaces do not themselves contain
-information on the sort of sensor or device they sit on top of.  A SID
-SHOULD provide one or more of the interfaces described in this
-section, depending on its expected uses and underlying data model.
+TinyOS 2.x contains several nesC interfaces that can be used to
+provide sensor-independent interfaces which cover a range of common
+use cases. This document describes these interfaces, and explains how
+to use these interfaces to write a Source- or Sink-Independent Driver
+(SID). A SID is source/sink independent because its interfaces do not
+themselves contain information on the sort of sensor or device they
+sit on top of.  A SID SHOULD provide one or more of the interfaces
+described in this section.
+
+This table summarizes the SID interfaces:
+
++------------------------+-----------+-----------+-----------+
+| Name                   | Phase     | Data type | Section   |
++------------------------+-----------+-----------+-----------+
+| Read                   | Split     | Scalar    | 3.1       |
++------------------------+-----------+-----------+-----------+
+| Get                    | Single    | Scalar    | 3.2       |
++------------------------+-----------+-----------+-----------+
+| Notify                 | Trigger   | Scalar    | 3.3       |
++------------------------+-----------+-----------+-----------+
+| ReadStream             | Split     | Stream    | 3.4       |
++------------------------+-----------+-----------+-----------+
 
 3.1 Split-Phase Small Scalar I/O
 --------------------------------------------------------------------
@@ -111,125 +124,37 @@ The first set of interfaces can be used for low-rate scalar I/O::
     event void readDone( error_t result, val_t val );
   }
 
-  interface Write<val_t> {
-    command error_t write( val_t val );
-    event void writeDone( error_t result );
-  }
-
-A component that provides both read and write functionality might want
-to use a combined version of the interface, to reduce the amount of
-wiring required by the client application::
-
-  interface ReadWrite<val_t> {
-    command error_t read();
-    event void readDone( error_t result, val_t val );
-
-    command error_t write( val_t val );
-    event void writeDone( error_t result );
-  }
-
-A component that can support concurrent reads and writes SHOULD
-provide separate Read/Write interfaces. A component whose internal
-logic will cause a read to fail while a write is pending or a write to
-fail while a read is pending MUST provide a ReadWrite interface.
-
 If the ``result`` parameter of the ``Read.readDone`` and
 ``ReadWrite.readDone`` events is not SUCCESS, then the memory of the
 ``val`` parameter MUST be filled with zeroes.
 
+If the call to ``read`` has returned SUCCESS, but the ``readDone``
+event has not yet been signaled, then a subsequent call to ``read``
+MUST return EBUSY or FAIL.  This simple locking technique, as opposed
+to a more complex system in which multiple read/readDone pairs may be
+outstanding, is intended to reduce the complexity of SID client code.
+
 Examples of sensors that would be suited to this class of interface
 include many basic sensors, such as photo, temp, voltage, and ADC
 readings.
 
-3.2 Split-Phase Large Scalar I/O 
---------------------------------------------------------------------
-
-If the SID's data object is too big to be passed efficienctly on the
-stack, it can provide read/write interfaces that pass parameters by
-pointer rather than value::
-
-  interface ReadRef<val_t> {
-    command error_t read( val_t* val );
-    event void readDone( error_t result, val_t* val );
-  }
-
-  interface WriteRef<val_t> {
-    command error_t write( val_t* val );
-    event void writeDone( error_t result, val_t* val );
-  }
-
-  interface ReadWriteRef<val_t> {
-    command error_t read( val_t* val );
-    event void readDone( error_t result, val_t* val );
-
-    command error_t write( val_t* val );
-    event void writeDone( error_t result, val_t* val );
-  }
-
-The caller is responsible for allocating storage pointed to by the val
-pointer which is passed to read() or write(). The SID MUST then
-take ownership of the storage, store a new value into it or copy a
-value out of it, and then relinquish it before signaling readDone() or
-writeDone(). If read or write() returns SUCCESS then the caller MUST
-NOT access or modify the storage pointed to by the val pointer until
-it handles the readDone() or writeDone() event.
-
-As is the case with the parameters by value, whether a component
-provides separate ReadRef and WriteRef or ReadWriteRef affects the
-concurrency it allows. If a component can allow the two to execute
-concurrently, then it SHOULD provide separate ReadRef and WriteRef
-interfaces. If the two cannot occur concurrently, then it MUST provide
-ReadWriteRef.
-
-If the ``result`` parameter of the ``ReadRef.readDone`` and
-``ReadWriteRef.readDone`` events is not SUCCESS, then the memory the
-``val`` parameter points to MUST be filled with zeroes. 
-
-Examples of sensors that are suited to this set of interfaces include
-those that generate multiple simultaneous readings for which
-passing by value is inefficient, such as a two-axis digital 
-accelerometer.
-
-3.4 Single-Phase Scalar I/O
+3.2 Single-Phase Scalar I/O
 --------------------------------------------------------------------
 
 Some devices may have their state cached or readily available. In
 these cases, the device can provide a single-phase instead of
 split-phase operation.  Examples include a node's MAC address (which
 the radio stack caches in memory), profiling information (e.g.,
-packets received), or a GPIO pin. These devices MAY use these
-single-phase interfaces::
+packets received), or a GPIO pin. These devices MAY use the
+Get interface::
 
   interface Get<val_t> {
     command val_t get();
   }
 
-  interface Set<val_t> {
-    command void set( val_t val );
-  }
 
-  interface GetSet<val_t> {
-    command val_t get();
-    command void set( val_t val );
-  }
-
-If a device's data object is readily available but still too large to
-be passed on the stack, then the device MAY use these interfaces::
 
-  interface GetRef<val_t> {
-    command error_t get( val_t* val );
-  }
-
-  interface SetRef<val_t> {
-    command error_t set( val_t* val );
-  }
-
-  interface GetSetRef<val_t> {
-    command error_t get( val_t* val );
-    command error_t set( val_t* val );
-  }
-
-3.5 Notification-Based Scalar I/O
+3.3 Notification-Based Scalar I/O
 --------------------------------------------------------------------
 
 Some sensor devices represent triggers, rather than request-driven
@@ -251,12 +176,16 @@ more platform- or hardware-specific async interfaces.
 The enable() and disable() command enable and disable notification
 events for the interface instance used by a single particular
 client. They are distinct from the sensor's power state. For example,
-if an enabled sensor is powered down, then when powered up it MUST
+if an enabled sensor is powered down, then when powered up it will
 remain enabled.
 
+If ``enable`` returns SUCCESS, the interface MUST subsequently
+signal notifications when appropriate. If ``disable`` returns SUCCESS,
+the interface MUST NOT signal any notifications.
+
 The val parameter is used as defined in the Read interface.
 
-3.7 Split-Phase Streaming I/O
+3.4 Split-Phase Streaming I/O
 --------------------------------------------------------------------
 
 Some sensors can provide a continuous stream of readings, and some
@@ -268,7 +197,7 @@ may provide data at a high rate that cannot be processed quickly
 enough when each new reading must be transferred from asynchronous to
 synchronous context through the task queue.
 
-The ReadStreaming interface MAY be provided by a device that can
+The ReadStream interface MAY be provided by a device that can
 provide a continuous stream of readings::
 
   interface ReadStream<val_t> {
@@ -295,36 +224,45 @@ building a linked list.
 
 After posting at least one buffer, the client can call read() with a
 specified sample period in terms of microseconds. The driver then
-begins to fill the buffers in the queue, signalling the bufferDone()
+begins to fill the buffers in the queue, signaling the bufferDone()
 event when a buffer has been filled. The client MAY call postBuffer()
 after read() in order to provide the device with new storage for
 future reads.
 
-If the device ever takes a sample that it cannot store (e.g., no
-buffers are available), it MUST signal readDone(). If an error occurs
-during a read, then the device MUST signal readDone() with an
-appropriate failure code. Before a device signals readDone(), it MUST
-signal bufferDone() for all outstanding buffers. If a readDone() is
-pending, calls to postBuffer MUST return FAIL.
-
-The following interface can be used for bulk writes::
-
-  interface WriteStream<val_t> {
+If the device ever takes a sample that it cannot store (e.g., due to
+buffer underrun), it MUST signal readDone() with an appropriate
+failure code. If an error occurs during a read, then the device MUST
+signal readDone() with an appropriate failure code. Before a device
+signals readDone(), it MUST signal bufferDone() for all outstanding
+buffers. If a readDone() is pending, calls to postBuffer MUST return
+FAIL.
+
+In the ReadStream interface, ``postBuffer`` returns SUCCESS if the buffer
+was successfully added to the queue, FAIL otherwise. A return value
+of SUCCESS from ``read`` indicates reading has begun and the interface
+will signal ``bufferDone`` and/or ``readDone`` in the future. A
+return value of FAIL means the read did not begin and the interface
+MUST NOT signal ``readDone`` or ``bufferDone``. Calls to ``read``
+MAY return EBUSY if the component cannot service the request.
+
+4. Implementation
+====================================================================
 
-    command error_t postBuffer( val_t* buf, uint16_t count );
+An implementation of the Read interface can be found in
+``tos/system/SineSensorC.nc`` and ``tos/system/ArbitratedReadC.nc``.
 
-    command error_t write( uint32_t period );
+An implementation of the Get interface can be found in
+``tos/platforms/telosb/UserButtonC.nc``.
 
-    event void bufferDone( error_t result, 
-                           val_t* buf, uint16_t count );
+An implementation of the ReadStream interface can be found in
+``tos/sensorboards/mts300/MageXStreamC.nc``.
 
-    event void writeDone( error_t result );
-  }
+Implementations of the Notify interface can be found in
+``tos/platforms/telosb/SwitchToggleC.nc`` and
+``tos/platforms/telosb/UserButtonP.nc``.
 
-postBuffer() and bufferDone() are matched in the same way described
-for the ReadStream interface, as are write() and writeDone().
 
-4. Summary
+5. Summary
 ====================================================================
 
 According to the design principles described in the HAA[_haa], authors
@@ -336,16 +274,16 @@ providing such an abstraction, driver authors can support developers
 who only need simple interfaces, and can reduce the effort needed to
 connect a sensor into a more general system.
 
-5. Author's Address
+6. Author's Address
 ====================================================================
 
 | Gilman Tolle
-| 2168 Shattuck Ave.
-| Arched Rock Corporation
-| Berkeley, CA 94704
+| 501 2nd St. Ste 410
+| Arch Rock Corporation
+| San Francisco, CA 94107
 |
-| phone - +1 510 981 8714
-| email - gtolle@archedrock.com
+| phone - +1 415 692 0828
+| email - gtolle@archrock.com
 |
 |
 | Philip Levis
@@ -367,3 +305,9 @@ connect a sensor into a more general system.
 | email - david.e.gay@intel.com
 |
 
+7. Citations
+============================================================================
+
+.. [1] TEP 108: Resource Arbitration.
+
+