[Tinyos-2-commits] CVS: tinyos-2.x/doc/txt tep111.txt, 1.1.2.8,
1.1.2.9
Phil Levis
scipio at users.sourceforge.net
Thu Jun 1 12:31:42 PDT 2006
- Previous message: [Tinyos-2-commits]
CVS: tinyos-2.x/tos/platforms/intelmote2/chips/pxa271
BlockStorageC.nc, NONE, 1.1.2.1 Flash.nc, NONE,
1.1.2.1 FlashC.nc, NONE, 1.1.2.1 HalP30P.nc, NONE,
1.1.2.1 Storage_chip.h, NONE, 1.1.2.1
- Next message: [Tinyos-2-commits] CVS: tinyos-2.x/tos/interfaces LogRead.nc,
1.1.2.6, 1.1.2.7 LogWrite.nc, 1.1.2.5, 1.1.2.6
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/tinyos/tinyos-2.x/doc/txt
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv24354
Modified Files:
Tag: tinyos-2_0_devel-BRANCH
tep111.txt
Log Message:
Rewrote section 3.
Index: tep111.txt
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/doc/txt/Attic/tep111.txt,v
retrieving revision 1.1.2.8
retrieving revision 1.1.2.9
diff -C2 -d -r1.1.2.8 -r1.1.2.9
*** tep111.txt 17 May 2006 00:26:40 -0000 1.1.2.8
--- tep111.txt 1 Jun 2006 19:31:39 -0000 1.1.2.9
***************
*** 53,106 ****
definition of TOS_Msg, which a platform (e.g., the micaZ) can
redefine to match its radio. For example, a mica2 mote uses the standard
! definition, which is
! | ``typedef struct TOS_Msg {``
! | ``// The following fields are transmitted/received on the radio.``
! | ``uint16_t addr;``
! | ``uint8_t type;``
! | ``uint8_t group;``
! | ``uint8_t length;``
! | ``int8_t data[TOSH_DATA_LENGTH];``
! | ``uint16_t crc;``
! |
! | ``// The following fields are not actually transmitted or received``
! | ``// on the radio! They are used for internal accounting only.``
! | ``// The reason they are in this structure is that the AM interface``
! | ``// requires them to be part of the TOS_Msg that is passed to``
! | ``// send/receive operations.``
! |
! | ``uint16_t strength;``
! | ``uint8_t ack;``
! | ``uint16_t time;``
! | ``uint8_t sendSecurityMode;``
! | ``uint8_t receiveSecurityMode;``
! | ``} TOS_Msg;``
! while on a mote with a CC420 radio (e.g., micaZ), TOS_Msg is defined as:
! | ``typedef struct TOS_Msg {``
! | ``// The following fields are transmitted/received on the radio.``
! | ``uint8_t length;``
! | ``uint8_t fcfhi;``
! | ``uint8_t fcflo;``
! | ``uint8_t dsn;``
! | ``uint16_t destpan;``
! | ``uint16_t addr;``
! | ``uint8_t type;``
! | ``uint8_t group;``
! | ``int8_t data[TOSH_DATA_LENGTH];``
! |
! | ``// The following fields are not actually transmitted or received``
! | ``// on the radio! They are used for internal accounting only.``
! | ``// The reason they are in this structure is that the AM interface``
! | ``// requires them to be part of the TOS_Msg that is passed to``
! | ``// send/receive operations.``
! |
! | ``uint8_t strength;``
! | ``uint8_t lqi;``
! | ``bool crc;``
! | ``uint8_t ack;``
! | ``uint16_t time;``
! | ``} TOS_Msg;``
There are two basic problems with this approach. First, exposing all of
--- 53,105 ----
definition of TOS_Msg, which a platform (e.g., the micaZ) can
redefine to match its radio. For example, a mica2 mote uses the standard
! definition, which is::
! typedef struct TOS_Msg {
! // The following fields are transmitted/received on the radio.
! uint16_t addr;
! uint8_t type;
! uint8_t group;
! uint8_t length;
! int8_t data[TOSH_DATA_LENGTH];
! uint16_t crc;
! // The following fields are not actually transmitted or received
! // on the radio! They are used for internal accounting only.
! // The reason they are in this structure is that the AM interface
! // requires them to be part of the TOS_Msg that is passed to
! // send/receive operations.
! uint16_t strength;
! uint8_t ack;
! uint16_t time;
! uint8_t sendSecurityMode;
! uint8_t receiveSecurityMode;
! } TOS_Msg;
! while on a mote with a CC420 radio (e.g., micaZ), TOS_Msg is defined as::
!
! typedef struct TOS_Msg {
! // The following fields are transmitted/received on the radio.
! uint8_t length;
! uint8_t fcfhi;
! uint8_t fcflo;
! uint8_t dsn;
! uint16_t destpan;
! uint16_t addr;
! uint8_t type;
! uint8_t group;
! int8_t data[TOSH_DATA_LENGTH];
!
! // The following fields are not actually transmitted or received
! // on the radio! They are used for internal accounting only.
! // The reason they are in this structure is that the AM interface
! // requires them to be part of the TOS_Msg that is passed to
! // send/receive operations.
!
! uint8_t strength;
! uint8_t lqi;
! bool crc;
! uint8_t ack;
! uint16_t time;
! } TOS_Msg;
There are two basic problems with this approach. First, exposing all of
***************
*** 143,159 ****
This format keeps data at a fixed offset, which is important when
passing a message buffer between two different link layers. If the
! data payload is at different offsets for different link layers, then
! passing a packet between two link layers requires a ``memmove(3)``
operation (essentially, a copy).
! The header, footer, and metadata fields are all opaque. Higher level
! components access their fields through interfaces. Section 3 discusses
! this in greater depth.
Every link layer defines its header, footer, and metadata
! structures. These structures MUST be external structs, and all of
! their fields MUST be external types, for two reasons. First, this
! ensures cross-platform compatibility. Second, it allows structures
! to be aligned on byte boundaries, circumventing issues with the
alignment of packet buffers and field offsets within them.
For example, the CC1000 radio implementation defines
--- 142,160 ----
This format keeps data at a fixed offset, which is important when
passing a message buffer between two different link layers. If the
! data payload were at different offsets for different link layers, then
! passing a packet between two link layers would require a ``memmove(3)``
operation (essentially, a copy).
! The header, footer, and metadata formats are all opaque. Source code
! cannot access fields directly. Instead, data-link layers provide access
! to fields through nesC interfaces. Section 3 discusses this in
! greater depth.
Every link layer defines its header, footer, and metadata
! structures. These structures MUST be external structs (``nx_struct``),
! and all of their fields MUST be external types (``nx_*``), for two
! reasons. First, external types ensure cross-platform compatibility.
! Second, it forces structures to be aligned on byte boundaries,
! circumventing issues with the
alignment of packet buffers and field offsets within them.
For example, the CC1000 radio implementation defines
***************
*** 184,282 ****
multiple link layers, and so only it can resolve which structures are
needed. These definitions MUST be in a file in a platform directory
! named ``platform_message.h``. The mica2 platform is a simple example,
! as it has only a CC1000 radio. Its platform_message.h looks like this::
! typedef cc1000_header_t message_header_t;
! typedef cc1000_footer_t message_footer_t;
! typedef cc1000_metadata_t message_metadata_t;
For a more complex example, consider a fictional platform named
'megamica' that has both a CC1000 and a CC2420 radio. Its
! platform_message.h looks like this::
typedef union mega_mica_header {
cc1000_header_t cc1k;
cc2420_header_t cc2420;
! } mega_mica_header_t;
typedef union mega_mica_footer {
cc1000_footer_t cc1k;
cc2420_footer_t cc2420;
! } mega_mica_footer_t;
typedef union mega_mica_metadata {
cc1000_metadata_t cc1k;
cc2420_metadata_t cc2420;
! } mega_mica_metadata_t;
- typedef mega_mica_header_t message_header_t;
- typedef mega_mica_footer_t message_footer_t;
- typedef mega_mica_metadata_t message_metadata_t;
-
If a platform has more than one link layer, it SHOULD define each of the
message_t fields to be a union of the underlying link layer structures.
This ensures that enough space is allocated for all underlying link layers.
! 3. Message_t fields
====================================================================
! A TinyOS component MUST NOT access any message_t fields directly besides
! its top-level structures:
!
! * header
! * data
! * footer
! * metadata
!
! That is, a TinyOS component MUST NOT access any sub-fields of these
! structures. Components above the link layer MUST access packet fields
! through a nesC interface. For example, active messages have an interface
! named ``AMPacket`` which provides access commands to AM fields. In
! TinyOS 1.x, a component would directly access ``TOS_Msg.addr``;
! in TinyOS 2.x, a component calls ``AMPacket.getAddress(msg)``.
!
! 3.1 message_header_t
! ----------------------------------------------------------------
! Link layer components MAY handle packet fields differently than other
components, as they are aware of the actual packet format. They can
therefore implement the interfaces that provide access to the fields
! for other components.
!
! Link layer components MUST NOT directly access sub-fields
! of message_t. There are two reasons for this. First, whether
! each type is their link type or a union of link types is unknown,
! as it can change depending on the platform.
! Each of these cases has different C syntax, and in the union case the
! name of the field is unknown.
!
! Second, although the structures ensure that enough space is allocated,
! C's placement of the structures is not necessarily correct.
! Defining a message_t header as a union of the underlying link layer headers
! means that, in terms of C structures, a packet may not be contiguous. For
! example, consider this case::
! typedef struct header_a {
! nx_uint8_t a;
! } header_a_t;
! typedef struct header_b {
! nx_uint16_t b;
! } header_b_t;
! typedef union {
! header_a_t A;
! header_b_t B;
! } header_union_t;
! typedef header_union_t message_header_t;
! Given nesC nx_struct layout, when message_header_t is specified as a union
! of HeaderA and HeaderB, there will be a padding byte after ``header_a_t.a``.
! However, some radios require that packets passed to them are contiguous.
The packet for a link layer does not necessarily start at the beginning
--- 185,295 ----
multiple link layers, and so only it can resolve which structures are
needed. These definitions MUST be in a file in a platform directory
! named ``platform_message.h``. The mica2 platform, for example, has
! two data link layers: the CC1000 radio and the TinyOS serial
! stack (TEP 113). The serial packet format does not have a footer
! or metadata section. The ``platform_message.h`` of the mica2
! looks like this::
! typedef union message_header {
! cc1000_header_t cc1k;
! serial_header_t serial;
! } message_header_t;
+ typedef union message_footer {
+ cc1000_footer_t cc1k;
+ } message_footer_t;
+
+ typedef union message_metadata {
+ cc1000_metadata cc1k;
+ } message_metadata_t;
For a more complex example, consider a fictional platform named
'megamica' that has both a CC1000 and a CC2420 radio. Its
! ``platform_message.h`` would look like this::
typedef union mega_mica_header {
cc1000_header_t cc1k;
cc2420_header_t cc2420;
! serial_header_t serial;
! } message_header_t;
typedef union mega_mica_footer {
cc1000_footer_t cc1k;
cc2420_footer_t cc2420;
! } message_footer_t;
typedef union mega_mica_metadata {
cc1000_metadata_t cc1k;
cc2420_metadata_t cc2420;
! } message__metadata_t;
If a platform has more than one link layer, it SHOULD define each of the
message_t fields to be a union of the underlying link layer structures.
This ensures that enough space is allocated for all underlying link layers.
! 3. The message_t fields
====================================================================
! TinyOS 2.x components treat packets as abstract data types (ADTs),
! rather than C structures, obtaining all of the traditional benefits
! of this approach. First and foremost, clients of a packet layer
! do not depend on particular field names or locations, allowing the
! implementations to choose packet formats and make a variety of
! optimizations.
! Components above the basic data-link layer MUST always access
! packet fields through interfaces. A component that introduces
! new packet fields SHOULD provide an interface to those that
! are of interest to other components.
! For example, active messages have an interface named ``AMPacket``
! which provides access commands to AM fields. In TinyOS 1.x, a
! component would directly access ``TOS_Msg.addr``; in TinyOS 2.x,
! a component calls ``AMPacket.getAddress(msg)``.
! The most basic of these interfaces is Packet, which provides
! access to a packet payload. TEP 116 describes common TinyOS
! packet ADT interfaces.
! Link layer components MAY access packet fields differently than other
components, as they are aware of the actual packet format. They can
therefore implement the interfaces that provide access to the fields
! for other components.
! 3.1 Headers
! ----------------------------------------------------------------
! The message_t header field is an array of bytes whose size is
! the size of a platform's union of data-link headers.
! Because packets are stored contiguously, the layout of a packet
! in memory is not the same as the layout of its nesC structure.
! A packet header does not necessarily start at the beginning of
! the message_t. For example, consider the Telos platform::
! typedef union message_header {
! cc2420_header_t cc2420;
! serial_header_t serial;
! } message_header_t;
+ The CC2420 header is 11 bytes long, while the serial header is
+ 5 bytes long. The serial header ends at the beginning of the
+ data payload, and so six padding bytes precede it. This figure
+ shows the layout of message_t, a 12-byte CC2420 packet, and
+ a 12-byte serial packet on the Telos platform::
+ 11 bytes TOSH_DATA_LENGTH 7 bytes
+ +-----------+-----------------------------+-------+
+ message_t | header | data | meta |
+ +-----------+-----------------------------+-------+
+
+ +-----------+------------+ +-------+
+ CC2420 | header | data | | meta |
+ +-----------+------------+ +-------+
+
+ +-----+------------+
+ Serial | hdr | data |
+ +-----+------------+
! Neither the CC2420 nor the serial stack has packet footers, and
! the serial stack does not have any metadata.
The packet for a link layer does not necessarily start at the beginning
***************
*** 284,332 ****
data field. When a link layer component needs to read or write protocol
header fields, it MUST compute the location of the header as a negative
! offset from the data field. The padding bytes that C introduces for
! the different sized headers are at the beginning of message_t, not
! between the header and payload. For example, let us suppose that header_a
! has an interface ``APacket``, which provides a command ``a`` that
! returns the field ``a``. Its code looks like this::
! command uint8_t APacket.a(message_t* msg) {
! header_a_t* hdr = (header_a_t*)(msg->data - sizeof(header_a_t));
! return hdr->a;
}
- Because this code is a bit unwieldy, many data link layers have an
- internal helper function that just returns a pointer to a header::
-
- header_a_t* getHeader(message_t* msg) {
- return (header_a_t*)(msg->data - sizeof(header_a_t));
- }
- ...
- command uint8_t APacket.a(message_t* msg) {
- header_a_t* hdr = getHeader(msg);
- return hdr->a;
- }
-
! Note that this only works for the data link header. As discussed in
! TEP 116[_tep116], higher level protocols must use a payload offset.
! A common approach to provide accessors is to have a helper function
! which correctly casts the location of a structure into a structure pointer.
! We can trust the C compiler to optimize the call into a static offset
! memory load.
! The following code is incorrect, as it directly casts the header field.
! It is an example of what components MUST NOT do::
! command uint8_t APacket.a(message_t* msg) {
! HeaderA* hdr = (HeaderA*)(msg->header);
! return hdr->a;
! }
! 3.2 message_footer_t
----------------------------------------------------------------
--- 297,353 ----
data field. When a link layer component needs to read or write protocol
header fields, it MUST compute the location of the header as a negative
! offset from the data field. For example, the serial stack header has
! active message fields, such as the AM type. The command that returns
! the AM type, ``AMPacket.type()``, looks like this::
! serial_header_t* getHeader(message_t* msg) {
! return (serial_header_t*)(msg->data - sizeof(serial_header_t));
! }
! command am_id_t AMPacket.type(message_t* msg) {
! serial_header_t* hdr = getheader(msg);
! return hdr->type;
}
! Because calculating the negative offset is a little bit unwieldy, the
! serial stack uses the internal helper function getHeader(). Many
! single-hop stacks follow this approach, as it is very likely
! that nesC will inline the function, eliminating the possible overhead.
! In most cases, the C compiler also compiles the call into a simple
! memory offset load.
+ The following code is incorrect, as it directly casts the header field.
+ It is an example of what components MUST NOT do::
+ serial_header_t* getHeader(message_t* msg) {
+ return (serial_header_t*)(msg->header);
+ }
! In the case of Telos, for example, this would result in a packet
! layout that looks like this::
! 11 bytes TOSH_DATA_LENGTH 7 bytes
! +-----------+-----------------------------+-------+
! message_t | header | data | meta |
! +-----------+-----------------------------+-------+
!
! +-----+ +------------+
! Serial | hdr | | data |
! +-----+ +------------+
! 3.2 Data
! ----------------------------------------------------------------
+ The data field of message_t stores the single-hop packet payload.
+ It is TOSH_DATA_LENGTH bytes long. The default size is 28 bytes.
+ A TinyOS application can redefine TOSH_DATA_LENGTH at compile time
+ with a command-line option to ncc: ``-DTOSH_DATA_LENGTH=x``.
+ Because this value can be reconfigured, it is possible that two
+ different versions of an application can have different MTU sizes.
+ If a packet layer receives a packet whose payload size is
+ longer than TOSH_DATA_LENGTH, it MUST discard the packet.
! 3.3 Footer
----------------------------------------------------------------
***************
*** 335,438 ****
MTU-sized packets. Like headers, footers are not necessarily stored
where the C structs indicate they are: instead, their placement is
! implementation dependent. For example, a link layer can store a full
! packet as a contiguous area of memory. In this case, a short packet
! will store the footer within the ``data`` field of the structure.
!
! The placement of the packet footer is implementation dependent: it
! does not have to lie within the footer field. For example, if a link
! layer receives a short packet, the footer, if contiguous with the rest
! of the packet, might actually reside within the data field. It is up
! to the link layer implementation where the footer is stored;
! correspondingly, components other than the one responsible for its
! placement MUST access the footer only through interfaces.
!
! 3.3 message_metadata_t
! ----------------------------------------------------------------
!
! The message_metadata_t stores the data associated with a packet that
! is not part of a wire format. Fields in the message_metadata_t are
! never transmitted. Examples of fields that might be in a
! message_metadata_t are a timestamps, an acknowledgment bit, or a
! retransmission count.
! 3.4 message_t Layout
----------------------------------------------------------------
! The message_t structure is designed so that multiple link layers that
! have different header sizes can exchange packets without a data copy.
! Its definition ensures that there is sufficient allocation for every
! link layer. The layout of a packet in memory is not necessarily the
! same as the structure definition. The basic issue driving these
! design considerations is that the C naming layout of message_t fields
! is platform specific. As a data link implementation may be used on
! many platforms, an implementation cannot depend on a particular C
! naming. An implementation can depend on there being enough space for
! its header and footer in message_t.
!
! Following this approach means that the packet header and data payload
! are contiguous in memory, which allows other communication
! abstractions (such as a UART, see TEP 113[_tep113]) to easily
! encapsulate a packet.
!
! For example, consider the message_t layout on the Telos platform, which
! has two link layers: serial communication and the CC2420::
!
! typedef union message_header {
! cc2420_header_t cc2420;
! serial_header_t serial;
! } message_header_t;
!
! typedef union TOSRadioFooter {
! cc2420_footer_t cc2420;
! } message_footer_t;
!
! typedef union TOSRadioMetadata {
! cc2420_metadata_t cc2420;
! } message_metadata_t;
!
!
! The serial stack packets do not have a footer or metadata. The CC2420
! has several metadata fields (7 bytes), but no footer. These are the
! headers for the two link layers::
!
! typedef nx_struct serial_header {
! nx_am_addr_t addr;
! nx_uint8_t length;
! nx_am_group_t group;
! nx_am_id_t type;
! } serial_header_t;
!
! typedef nx_struct cc2420_header_t {
! nxle_uint8_t length;
! nxle_uint16_t fcf;
! nxle_uint8_t dsn;
! nxle_uint16_t destpan;
! nxle_uint16_t dest;
! nxle_uint16_t src;
! nxle_uint8_t type;
! } cc2420_header_t;
!
!
! The serial header is 5 bytes long, while the CC2420 header is 11 bytes
! long. This means that the message_t header is 11 bytes. When the
! serial stack builds a packet, it places the first byte of its header
! offset 6 bytes from the beginning of the message_t, so that its
! header is contiguous with the data payload. This shows the layout
! of a 12-byte packet for the CC2420 and serial stacks along side the
! full message_t structure::
!
! 11 bytes TOSH_DATA_LENGTH 7 bytes
! +-----------+-----------------------------++-------+
! message_t | header | data || meta |
! +-----------+-----------------------------++-------+
!
! +-----------+------------+ +-------+
! CC2420 | header | data | unused | meta |
! +-----------+------------+ +-------+
!
! +-----+------------+ +-------+
! Serial | hdr | data | unused | meta |
! +-----+------------+ +-------+
--- 356,380 ----
MTU-sized packets. Like headers, footers are not necessarily stored
where the C structs indicate they are: instead, their placement is
! implementation dependent. A single-hop layer MAY store the footer
! contiguously with the data region. For short packets, this can mean
! that the footer will actually be stored in the data field.
! 3.4 Metadata
----------------------------------------------------------------
! The metadata field of message_t stores data that
! a single-hop stack uses or collects does not transmit.
! This mechanism allows packet layers to store per-packet
! information such as RSSI or timestamps. For example, this is
! the CC2420 metadata structure::
+ typedef nx_struct cc2420_metadata_t {
+ nx_uint8_t tx_power;
+ nx_uint8_t rssi;
+ nx_uint8_t lqi;
+ nx_bool crc;
+ nx_bool ack;
+ nx_uint16_t time;
+ } cc2420_metadata_t;
- Previous message: [Tinyos-2-commits]
CVS: tinyos-2.x/tos/platforms/intelmote2/chips/pxa271
BlockStorageC.nc, NONE, 1.1.2.1 Flash.nc, NONE,
1.1.2.1 FlashC.nc, NONE, 1.1.2.1 HalP30P.nc, NONE,
1.1.2.1 Storage_chip.h, NONE, 1.1.2.1
- Next message: [Tinyos-2-commits] CVS: tinyos-2.x/tos/interfaces LogRead.nc,
1.1.2.6, 1.1.2.7 LogWrite.nc, 1.1.2.5, 1.1.2.6
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Tinyos-2-commits
mailing list