• : Function ereg() is deprecated in /home/project-web/tinyos8051wg/htdocs/includes/ on line 647.
  • : Function ereg() is deprecated in /home/project-web/tinyos8051wg/htdocs/includes/ on line 647.
  • : Function ereg() is deprecated in /home/project-web/tinyos8051wg/htdocs/includes/ on line 647.
  • : Function ereg() is deprecated in /home/project-web/tinyos8051wg/htdocs/includes/ on line 647.
  • : Function ereg() is deprecated in /home/project-web/tinyos8051wg/htdocs/includes/ on line 647.
  • : Function ereg() is deprecated in /home/project-web/tinyos8051wg/htdocs/includes/ on line 647.

6. Support Libraries

The common/lib directory contains a number of general purpose support libraries for debug, development or additional services.

6.1 StdOut

A minimalisting prety printing library (not entirely unlike printf). will be able to print human readable text to the UART defined for the platform in UartC. In addition to printing strings the interface provides methods for printing integers in different bases: base 16 (hex), base 10, base 2 (binary).

StdOut.print("Helo worl\n\r");

An application wires a StdOut interface to the component StdOutC or to disable printing the application can later wire to StdNull. The strings are copied to an internal print buffer, but no concurrency checks are performed - if a program call print to often the output will be garbled.

configuration TestAppC {
} implementation {
  components TestAppP;
  components StdOutC;
  //components StdNull as StdOutC;
  TestAppP.StdOut -> StdOutC;


module TestAppP {
  uses interface StdOut;
} implementation {
 async event void StdOut.get( uint8_t byte ) {
 call StdOut.print("Hello World\n\r");
 call StdOut.printBase10uint16(x);
 call StdOut.printBase2uint16(x);

6.2 SimpleMac

An minimalistic interface to access 802.15.4 like radios (without the
802.15.4 protocol layer. It uses a very simple addressing scheme that is incompatible with regular 802.15.4 addressing. SimpleMac uses 802.4.15 hardware, but packets are broadcast to all listening nodes, using beacon frames in order to circumvent 802.15.4 addressing. The addressing is archived by using the "panid" feature from 802.15.4.

Packets are transmitted using this simple abstractions:

interface SimpleMac {
   command error_t sendPacket(packet_t *packet);
   event void sendPacketDone(packet_t *packet, error_t result);
   event packet_t *receivedPacket(packet_t *packet);

6.2.1 Example

A simple example from the TTX demo setting up a simple sender and receiver looks like this:

Base (reciver)

module SampleForwardM {
  uses interface SimpleMac;
} implementation {
  mac_addr_t adr = 0x000B;
  event void Boot.booted() {
    call SimpleMac.setChannel(20);
    call SimpleMacControl.start();      
    call SimpleMac.setPanAddress(&adr);
  event packet_t * SimpleMac.receivedPacket(packet_t *packet){
    for (i = 0; i < packet->length - 9; ) {
      call StdOut.printHex(packet->data[i++]);
   return packet;

Node (sender)

module SampleForwardM {
} implementation {
  packet_t transmitPacket;
  event void Boot.booted() {
    call SimpleMac.setChannel(20);
    call SimpleMacControl.start();      
  command error_t Init.init() {
    transmitPacket.length = 7 + SAMPLES * 6 + 2;
    transmitPacket.fcf = 0x0000;
    transmitPacket.data_seq_no = 0x00;
    transmitPacket.dest = 0x000B;
    transmitPacket.src = 0;
event error_t ThreeAxisAccel.dataReady(){
        call SimpleMac.sendPacket(&transmitPacket);

6.2.2 Debug output

The SimpleMac component indicates transmission errors on UartC uart, e.g.:
MAC: CRC Failed
MAC: Buffer flushed

6.3 USB Stack for TinyOS

A simple portable USB stack, providing a Communications Class Device (CDC) implementation emulating a simple UART over USB. Presently the stack only supports the SiLabs CIP51 MCU. This directory contains a simple USB stack for TinyOS. It was developed for the SiLabs c808051f34x, but it should general enough to encompass any device with a built in USB port. Each such system will have to provide a USBControl interface and all endpoints using USBEndpoint interfaces.

We provide a USB serial port emulator (conforming to the Communications Class Device - CDC) that should work with any operating system claiming to support USB. The implementation is split in two: a byte level and a packet level interface.

The byte level version is limited in performance due to the way the individual bytes are tranferred over the USB bus: each
SerialByteComm.put() results in one USB packet per byte, the USB packets are spaced one per ms. Essentially limiting the outbound bandwidth to 8 kbit. This means that for example a simple echo application will fail horribly if the bytes are transmitted to the device at full speed, since it will not be able to return bytes at the same rate.

The driver is setup in the following heirachy (using the serial driver as example):

  |               USBSerialCDC                    |
                       | PacketComm
  |            USBCommunicationClassDevice        |
           | USBDevice       |          |
  +--------+--------------+  |          |
  |   USBControlEndpoint  |  |Endpoint1 |Endpoint2
  +-+-----------+---------+  |          |
    |USBControl |Endpoint0   |          |
  |                  PlatformUSB                  |

The code here is inspired by a couple of sources, first the SiLabs examples and secondly a CDC implementation provided in the Cygnal forum:

The CDC spcification can be found here:

And the USB-2.0 specification can be found here:

6.4 BufferManager

This generic buffer manager for memory management in a traditional get/free semantics, not unlike malloc/free, but with buffer sizes fixed at compiletime. It is based on the ideas proposed in The Case for Buffer Allocation in TinyOS (Klaus S. Madsen) and the implementation is inspired by the one used by Jan Flora in his IEEE 802.15.4 stack TinyFour. The BufferManager interface is accessed through to simple methods, to get a new buffer simply call the get() method, which will return NULL if no buffer is available.

interface BufferManager<page_t> {
   command page_t * get(); // Return NULL if no buffer is available
   command error_t free(page_t* p);
   command uint8_t freeBuffers();

We provide two implementations of the BufferManager interface:

  • FIFOBufferManagerP: This buffer manager implements a simple queue to hold free buffer, new and free call simply pop or push a pointer from the queue. The queue implementation is borrowed from the TinyOS queue implementation and duplicated here, since we simply want a dequeue on an empty queue to return a NULL pointer. <br>It is implemented as a queue and /no/ safeguards are implemented on free - as a result freeFail will never be signaled.
  • SafeBufferManagerP: This buffer manager ensures that no buffer can be released twice, it's slightly slower than FIFOBufferManager, but should be slightly safer too.

configuration TestAppC{
   component TestAppP,
        FIFOBufferMangerP as BufferManager;

   MainC.SoftwareInit -> BufferManagerP.Init;
   TestAppP -> BufferManager;


module USBCommunicationClassDeviceP{
   uses interface BufferManager<buffer_t> as BufferManager;
  buffer_t *bufM
  buf = call BufferManager.get();
  if (buf != NULL) {

6.5 Compression

A simple compression library with pluggable compression algorithms library. It compresses 3 samples at a time using one of 4
algorihms. It uses an internal buffer that must be copies to a separate location for transmission, storrate, etc. The algoritms are:

  • LZ77
  • Huffmann
  • Simple
  • Passthrough

You can include this in your own applications and test it using CompressionTest (apps/CompresisonTest). See readme file in this directory for more.

To use this compression library:

  • link "compressor.h" to one of the available algorithms (in the lib directory):

lz77.h simple.h huffman.h huffman_diff.h huffman_whole.h passthru.h

  • Include the interface "Compressor" in your application and wire it to
  • Call Compressor.Init() from "Booted"
  • Each consecutive call to "Compress" stores the samples in an internal buffer until its full (default size = 256 bytes).
  • When the buffer is full the Compressor.bufferFull event is signaled. In this event the content must be copied since it will be overwritten by Compress on the next call.
  • To return the buffer earlier call "Compressor.flush" - its unclear how to figure out how many bytes are present in the buffer in this case

6.6 LogRecorder: Transparent log recording layer.

An event tracing library for debuging and application characterization, described in this paper paper The log recording layer is used to record the accumulated time used in different mote states, such as on, transmitting, receiving, etc. The states are numbered by connecting I/O pins from one pin two an other
and recording the time spent in each state on the second mote.

The recording layer has two parts:

  1. The library in this directory that is to be linked with a target application and used on a target mote
  2. The LogRecorder application in the apps directory. This application records the state transitions on the target mote via the I/O pins.

To use this on a target application:

  • Change the top level wiring file to point to the log-component instead of the real components. For example to record the use of the Msp430 internal temperature sensor:

  components new Msp430InternalTemperatureC();
  components new ReadLoggerC(uint16_t);
  DataAcquisitionP.Read -> ReadLoggerC;
  ReadLoggerC.ReadIn -> Msp430InternalTemperatureC;
  • Link log.extra to support/make/<your platform>/
  • make <your platform> log

Which output pins are bound to which states is configured in the component LoggerPinsC found in the platform directory.