CS 213: Advanced Topics in 

Distributed Embedded Systems

Assignment 2: Getting Started with TinyOS

Due Date: January 26th, 11:59pm PST

The purpose of this assignments is to get you familiarized with programming in TinyOS, the operating system for the Mote platform developed at U.C.Berkeley. Many of the steps involved in this assignment will be familiar to you from last weeks Em* assignment. However, the assignment that you are given here and the questions that are posed will differ slightly to give you a more diverse programming experience. As with the previous assignment, this one will require some setup, some implementation, and some testing to complete it.

TinyOS can be installed on both Windows(under cygwin) and Linux platforms and the assignment can be done on your home machine if you prefer. Detailed installation instructions are available at the TinyOS webpage. However, since our laboratory at UCLA is primarily Linux-oriented, you are unlikely to get assistance if you have problems with the Windows installation. You will be required to use only the simulator, Tossim/Nido, therefore, you need not install tools such as 'uisp' for the class assignments.

As with the first assignment, you can also work on the simulation machines (tobiko and dragon) that you used for the Em* assignment.

NOTE: If you are using the class machines for simulations, be warned that there may be contention for their use as the deadine approaches. So START EARLY!!

Part I: Setup

Step 1:

Log in to tobiko or dragon, and download the source code via anonymous CVS from the Sourceforge TinyOS Project page (see this page for a detailed explanation).
cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/tinyos login
When prompted for a password for anonymous, simply press the Enter key.
cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/tinyos co tinyos-1.x
Then, download the additional files to the tinyos-1.x/ directory, and untar them:
wget http://www.cens.ucla.edu/213/213-ps2.tgz
tar -xzvf 213-ps2.tgz

This should create two directories, 'apps/cs213-W04-Sample/' and 'apps/cs213-W04/' and install a bunch of files in each.

Once you have the files downloaded, build the system. Set the TOSDIR environment variable to the tos directory within tinyos-1.x as shown below. This "export" line is required each time you log in before building (you can add it to your .bashrc file if you prefer).
export TOSDIR=/home/your_username/tinyos-1.x/tos
At this point, you can test a small program to see if your installation has been succesfull.
cd apps/Blink
make pc
The 'make pc' should complete with no errors. All executables, object files, and libraries are stored in an architecture-specific directory: build/pc within the Blink directory.
./build/pc/main.exe --help
should give you a list of options while running the program in the simulator.
First, try running something.

./build/pc/main.exe 1
You should see a whole bunch of output about nodes being started, CLOCK components being initialized, etc.
If that works, try running the sample code in the cs213-W04-Sample directory. This is the example that was presented to you in class and shows the simple case of a Sink flooding a packet to a network, and all nodes receiving the flooded packet. Now, execute the below set of instructions.
cd apps/cs213-W04-Sample
make pc
export DBG=usr2
./build/pc/main.exe 5
You should see the following
3: Node 3 initialized
3: Node 3 started
0: Sink initialized
0: Node 0 started
2: Node 2 initialized
2: Node 2 started
1: Node 1 initialized
1: Node 1 started
4: Node 4 initialized
4: Node 4 started
0: Sink timer fired
1: Source received flood msg: cmd=PKT_TYPE_NODE_COUNT_REQ seqno=0
2: Source received flood msg: cmd=PKT_TYPE_NODE_COUNT_REQ seqno=0
4: Source received flood msg: cmd=PKT_TYPE_NODE_COUNT_REQ seqno=0
3: Source received flood msg: cmd=PKT_TYPE_NODE_COUNT_REQ seqno=0
0: Sink sent flood: status=1

Step 2:
The next step is to look at the documentation on Tossim (TinyOS simulator - also called Nido) and to read through the tutorial. It is especially important that you go through the tutorial Lesson 5 on Tossim. Also, carefully read through the Nido system description (you have a local copy of it too at /tinyos-1.x/doc/nido.pdf). Pay special attention to the section on Radio models (Section 3) Once you are done with this, you can start on your assignment.

Part II: Implementation

For this assignment, you will need to implement an application in TinyOS that counts the number of nodes in the system. To help you get started, the tar file we provided you contains a skeleton program with a few missing pieces, in 'apps/cs213-W04/'.

In class, we covered the Flooding component (lib/FloodM.nc) and its configuration file (lib/Flood.nc). The flooding module exposes the FloodData interface (lib/FloodData.nc). You will NOT need to modify any of the code in the above flooding components for this assignment. However, it will be useful for you to go through it to see how it is written.

The algorithm we use in this assignment makes use of the above flooding component. Node 0 is designated as the sink on startup, waits for a certain period of time and floods out a request messag to reach all other nodes in the system. Each node, upon receiving the request message, will flood a reply message. The sink receives the count of unique senders and can print out this number using a dbg() command.

Three lossy topology files are provided. '5x5-5.nss' is a 5 by 5 grid of nodes with grid separation 5 ft. Similarly, '5x5-20.nss' is a 5 by 5 grid with separation 20 ft and so on. Since the effective radio range of the Mote radio is approximately 50ft, each topology represents different lossy characteristics.

To run the code with one of these files, you will have to specify the filename in the command-line as follows:

./build/pc/main.exe -rf=5x5-10.nss 25

The lines written in red indicate questions to answer in your solution.

Step 1:

Familiarize yourself with the code provided:
There are three places in the code (marked with 'CODE TO BE FILLED IN') where you will need to add code to complete the program.


Complete the missing code segments:
In order to speed the process, we have made sure that the existing framework runs, so you incrementally build the assignment.

To test and debug your program, run the program with a few nodes. As described by the Tossim/Nido manual, which you should have read by now, the easiest way to start is to use a simplistic single-hop radio model (ie all nodes are within earshot of each other and packetloss is zero). This case is achieved when no command-line parameters are given. eg: './build/pc/main.exe 5' simulates 5 nodes in one broadcast domain.

In this step, look at the count that is obtained at the sink, i.e. how many different flooded replies does the sink receive. It is alright if the number does not correspond to the actual number of nodes in the network. In fact, if you are not seeing losses, there is something wrong. This is something we will fix in the later steps.


Helpful Tips:
Submit your final source code (including the changes that you make in steps 2, 3 and extra credit) as part of your solution.

Plot or otherwise make a table of Number Of Nodes (y-axis) VS Network Count Received At Sink (x-axis) for the lossless radio model, in which you use 5,10,20 and 40 nodes.

Similarly, plot or provide the table of LossyModelName (y-axis) vs Network Count received At Sink (x-axis) for the lossy models, where you use the three given files.



There are two issues that result in counting errors in Step 1.

The first is the possibility that the FloodM module is busy when a packet was attempted to be sent, i.e. if the Flood.sendFlood command returns a FAIL status. Since TinyOS uses non-blocking interfaces and no queuing is done within the Flood module, it is very likely that a status FAIL response is received.

The second problem is the possibility that nodes are responding in a synchronized manner, with the result that their packets are colliding with each other.This happens because of the choices that we made in our algorithm in Step 1. The sink broadcast would have been simultaneously received at all nodes in the network. Each node would have set a timer for the same amount of time (RESPONSE_PERIOD), at the end of which it would have attempted to flood. Thus, it is likely that many nodes try to simultaneously access the channel, with the result that some of them collide.

We will address these two issues in Steps 2 and 3.

Step 2:

We will now see what happens when the Flood interface returns status flag FAIL in CountResponseTimer.fired(). Clearly, when the status is fail, a backoff policy is needed i.e. the flood should be re-attempted after a time period. This procedure is similar to a MAC-layer backoff policy when the channel is sensed to be busy, except, at the application level. Clearly, tight-looping till the Flood module becomes available is not the best way to do this since this will waste system resources. Instead, you will re-start the timer with a different time-period, BACKOFF_PERIOD (defined in Node.h). Do this a maximum of MAX_RETRANSMISSIONS (defined in Node.h) times before giving up on the flood module. Such a policy makes your module robust to failures in the Flood module.

Also, vary the MAX_RETRANSMISSIONS parameter (set to two by default) defined in Node.h till you seem to achieve better results.

How does this improve the count seen by the sink? Provide the same table as for Step 1 as result.


Step 3:

The second problem that we identified was synchronized channel access, in other words, the lack of randomization in transmission times. In Step 2, you were asked to start CountResponseTimer after a fixed time, RESPONSE_PERIOD. Since the broadcast from the sink would have reached all nodes at the same time, and each node would have set a timer for exactly the same time period, the likelihood of many nodes trying to simultaneously access the channel is high. This dramatically increases the likelihood of collisions, and hence packet-loss.

You will now add application-level randomization to the code to add jitter i.e. use a random number instead of RESPONSE_PERIOD. You are already provided hooks to the Random_LFSR (Random Linear Feedback Shift Register) component, which can be used to provide random numbers. Note that it has already been initialized in StdControl.init(). You can call Random.rand() function to get a new 16 bit random number. This random number can be suitably shortened to suit your needs by using only some of its digits (eg: Random.rand() & 0xff). Note that this is not as good of a pseudo-random number generator that you are likely to get on a PC but a very crude one for the Mote platform. So, you might see some synchronization even after randomization.

Your task in this step is to add randomization and try to improve the count that the sink obtains by following the procedure in Step 1.

How much randomization is required for the sink to obtain the total network count within 10% error?



As with Assignment 1, give an estimate of the latency, i.e. the amount of time that the sink will have to wait before it gets the responses from all nodes. Provide this number only for the '5x5-10.nss' topology.

Extra credit:

Make the sink timer periodic i.e. instead of sending out a single count request, the sink now sends out periodic requests. This change can be easily accomplished by modifying the first field of a Timer.start(..) command to TIMER_REPEAT instead of TIMER_ONE_SHOT, which results in the sink sends a new Count request packet every FLOOD_PERIOD seconds. In this case, the sink will have an estimate of the network count at the end of each FLOOD_PERIOD.

First, determine a choice of randomization and MAX_RETRANSMISSIONS that lets the sink get results within 10% of the actual network count for every period.

Give a list of at least 3 parameters that influence the choice of the above parameters and how they do so. Hint: think about network scaling, MAC-level channel access etc.