Monday, March 21, 2011

How to use GNU make

    When we are writing programs that has large number of source files, the commands that we have to use on the terminal will be very long since we have to put all the source files' names there. Therefore compiling again and again for testing and debugging purposes is difficult with the long list of source files's names. In addition to that there are certain other things that we have to consider when compiling source codes of a program. As an example if our program uses some libraries located in different directories in the system, we have to check wheather they exists. And also we may have to check whether the versions of different libraries and tools are compatible to compile our program.
    To ease the overhead of doing all those stuff we have GNU make which is a great utility available in Linux environment. In this article I note down the very basics of GNU make which can be used in our programming works. I use a simple examples to describe the most fundamental facilities we have in GNU make. Suppose we have a program with 4 source files given below.

1:  main.c file  
2:  ===========  
3:  #include "head1.h"  
4:  #include "head1.h"  
5:  #include "head1.h"  
6:  main() {  
7:    func_1();  
8:    func_2();  
9:    func_3();  
10:  }  
11:  head1.c  
12:  =======  
13:  #include "head1.h"  
14:  #include <stdio.h>  
15:  void func_1() {  
16:    printf("head-1\n");  
17:  }  
18:  head2.c  
19:  =======  
20:  #include "head2.h"  
21:  #include <stdio.h>  
22:  void func_2() {  
23:    printf("head-2\n");  
24:  }  
25:  head3.c  
26:  =======  
27:  #include "head3.h"  
28:  #include <stdio.h>  
29:  void func_3() {  
30:    printf("head-3\n");  
31:  }  

We need to compile these programs and create an executable program name "program". If we are not using GNU make, here what we will issue on the terminal to compile the program.
    gcc -o program main.c head1.c head2.c head3.c
Instead of it, we write a file with the contents below and save with the name "Makefile" in the same directory as the source files resides.

1:  Makefile  
2:  ========  
3:  program : main.o head1.o head2.o head3.o  
4:    gcc -o program main.o head1.o head2.o head3.o  
5:  main.o : main.c head1.h head2.h head3.h  
6:    gcc -c main.c  
7:  head1.o : head1.c head1.h  
8:    gcc -c head1.c  
9:  head2.o : head2.c head2.h  
10:    gcc -c head2.c  
11:  head3.o : head3.c head3.h  
12:    gcc -c head3.c  
13:  clean :  
14:    rm program main.o head1.o head2.o head3.o  

To compile the program what we have to do is just goto the directory from the Linux shell and issue the command 'make'. Then the 'Makefile' that we have created will get executed. Before closely analying the content in the make file it's better to look at the general syntax of a GNU make rule.

targets : prerequisites
             recipe
             ...

The targets is the file name that will be generated by executing this rule. Prerequisites are a list of file names separated by spaces that are required to execute this rule successfully. If the prerequisites are there, the recipe lines will be executed. In the recipe lines contains the instructions to do whatever to the prerequisites files and generate the target file. Lets take a look at the make file. There our first rule says that it should generate a file called program if the object files listed exists. If so, it execute the recipe and link the object files to create the target program. Likewise all the first five rules will specify that they are depend on and what they will produce.
    GNU make utility will consider all the dependencies of the source files to each other and do the compilation and linking. The last rule in the make file is something special. It doesn't talking about a target file called 'clean'. The clean target is used to specify what should be done if we enter the command in the shell as,
    make clean
In our make file we have specified to delete all the files that have generated by executing the make file. There's no prerequisites for the clean target. We can use variables in make files to reduce rewriting long lists of file names or other stuff. In our make file, let's use a variable to represent the object file names.

1:  Makefile  
2:  ========  
3:  objects = main.o head1.o head2.o head3.o  
4:  program : $(objects)  
5:    gcc -o program $(objects)  
6:  main.o : main.c head1.h head2.h head3.h  
7:    gcc -c main.c  
8:  head1.o : head1.c head1.h  
9:    gcc -c head1.c  
10:  head2.o : head2.c head2.h  
11:    gcc -c head2.c  
12:  head3.o : head3.c head3.h  
13:    gcc -c head3.c  
14:  clean :  
15:    rm program $(objects)  

We may have multiple make files in our program source directory. In such situations we may need to execute other make file by running a one make file. To do this we can inclue other make files' names in a make file by using the below way. 'Makefile.one' and 'Makefile.two' are two make files that we have in addition to the default make file.

    include Makefile.one
    include Makefile.two

Depending on the context we may have to follow different approaches to compile a program. Therefore conditionals can be used to specify different ways.
The syntax of a simple conditional with no else is as follows:

     conditional-directive
     text-if-true
     endif

The syntax of a complex conditional is as follows:

     conditional-directive
     text-if-true
     else
     text-if-false
     endif
or:

     conditional-directive
     text-if-one-is-true
     else conditional-directive
     text-if-true
     else
     text-if-false
     endif

Let's assume we have a program that should be linked to different libraries depending on the environment we are working on. Below code describes the part of the make file that do this.

     libs_for_gcc = -lgnu
     normal_libs =
    
     foo: $(objects)
     ifeq ($(CC),gcc)
             $(CC) -o foo $(objects) $(libs_for_gcc)
     else
             $(CC) -o foo $(objects) $(normal_libs)
     endif

The ifeq directive begins the conditional, and specifies the condition. It contains two arguments, separated by a comma and surrounded by parentheses. Variable substitution is performed on both arguments and then they are compared. The lines of the makefile following the ifeq are obeyed if the two arguments match; otherwise they are ignored.
    There's another conditional directive that is ifdef. It checks whether a variable has defined and perform tasks according to it. Below is an example for ifdef directive.

    bar = true
        foo = bar
        ifdef $(foo)
        frobozz = yes
    else
        frobozz = no
        endif
The information I have showed here are just a small part of what we can do with GNU make. Yet there are lot of things we have to explore in GNU make utility. It's up to you to learn it and make use of it in your day to day programming works.

MSB430 Sensor Mote



When we are working on wireless sensor networks we find different hardware platforms developed by different vendors. Even though in each sensor mote hardware we find lot of differences, there are basic components or modules that exist in each and every wireless sensor node. Any mote requires a processing unit which is the central brain of the mote. Usually thay use microcontrollers(MCU) for this purpose rather than ordinary PC microprocessors becase MCUs operate with very little energy consumptions. Most of the MCUs we have out there in the market are targetted for environments where we have to rely on batteries.
    Usually these MCUs carry internal memory modules that can store program instructions and data within the MCU. But depending on the requirements of the sensor network developers, extra storage space may be necessary. Therefore usually a sensor mote contains a way to extend it's memory capacity by integrating with external units. These memory units can be EEPROMs or SD-/MM cards.The next important thing on a wirelless mote is the communication module. A mote should be capable of transmitting and receiving signals from other similar motes and devices in the sensor network. The transmission medium can be redio frequency, optical communication or infrared. The most common way of communicating between motes is radio frequencies since thay are very reliable. Unlike optical and infrared signals, the radio signals don't get interfered by environmental events and energy sources.
    At last sensor motes contains different sensors to gather data which is their ultimate task. The ability to plugin additional sensors is an added advantage in sensor motes rather than just using what the manufacturer of mote has shiped it with. Usually sensors are available to sense temparature, humidity, acceleration, vibrations, light, and so on.
    Now if we talk about our main topic the MSB430 sensor mote, it's a one which is specifically designed to use on research and academic purposes rather than industrial usages. MSB430 is a product of ScatterWeb which is a German vendor. It has an MCU called MSP430 developed by Texas Instruments, USA. This MCU offers 60KB of memory divided into 5KB of RAM and 55KB of flash-ROM. In addition to that it contains a SD-/MM card slot which supports upto 4GB storage.
    The radio transceiver of the sensor mote is a Chipcon CC1020 transceiver which operates on ISM band and has the ability to select the communication frequencies by software. Therefore selecting multiple channels for advanced routing schemes is supported with this tranceiver. For analog data in and out, the mote contains 2 A to D converters. To program the wireless mote we can use JTAG inerface. In addition to that we can connect the mote to a PC by the USB port with the help of a FTDI converter cable. When we connect it to the PC with USB port, we can put the mote to the USB mode by using it's switch on the main board. At this mode, it doesn't require the usual power supply with 3 AAA batteries since it can get the power though USB cable from the PC.
    When we are going to program the mote for our purposes we have differet software options. The hard way is programming it from scratch. If we're looking for some easier way, we have operating systems that can be installed on the mote. If so, we have to just write applications on top of the operating system. The manufacturer of the mote ScatterWeb itself provide an operating system called ScatterWeb operating system. And the Contiki operating system is also ported to MSB430 platform. If we're going to develope applications on Linux PCs for the Contiki operating system to run on MSB430 motes, we need some development tools installed in our Linux machine.
    GNU community provides compiler tool chains for the GCC compiler to support development for Contiki on MSB430. To install the tools and libraries we have to first add the below software source to the /etc/apt/sources.list file. 
    deb http://wyper.ca/debian i686/
Then run these commands on the shell.
    apt-get update
    apt-get install binutils-msp430 gcc-msp430 msp430-libc msp430-jtag
Now our development environment is ready. So, it's time to write some apps, install and run on our MSB430 motes.

Compiling and running tikiridb-0.2 for Cooja Simulator

Cooja is a network simulator that comes with the Contiki operating system. When we're working on sensor network applications that runs with Contiki operating system we always have to compile, run and check whether it works. For this purpose it's not a good idea to burn the application and OS to real hardware motes over and over again because the re-writability of the memory modules of the hardware may be limited. Therefore it's a good idea to use Cooja simulator as a pre-testing tool of our application programs. Here I write down the way to compile tikiridb to run on cooja simulator.


    We begin from downloading tikiridb 0.2 version from http://score.ucsc.lk and the daily snapshot code of the contiki from http://www.sics.se/contiki/. We create a new directory somewhere in our Ubuntu machine and put the two downloaded source directories ("0.2" and "contiki-2.x") in that directory side by side. Now it's time to follow a sequence of instructions to reach our goal.

1) Open the file "0.2/node/platform-modified/cooja/packetizer-arch.c" and put this function to the end of it.

    void packetizer_arch_writeb(unsigned char c) {
        rs232_send(c);
    }

2) Copy the "serial_forwarder" directory in "0.2/cooja/plugins/" to the "contiki-2.x/tools/cooja/apps/" directory.

3) open file "contiki-2.x/tools/cooja/build.xml",
    1. As a child element of , add the following
          <ant antfile="build.xml" dir="apps/serial_forwarder" target="clean" inheritAll="false"/>  

    2. As a child element of add the following
 
         <ant antfile="build.xml" dir="apps/serial_forwarder" target="jar" inheritAll="false"/>

4) open file "contiki-2.x/tools/cooja/config/external_tools_linux.config" and  replace the variable "DEFAULT_PROJECTDIRS" with,
    DEFAULT_PROJECTDIRS = [CONTIKI_DIR]/tools/cooja/apps/mrm;[CONTIKI_DIR]/tools/cooja/apps/mspsim;[CONTIKI_DIR]/tools/cooja/apps/avrora;[CONTIKI_DIR]/tools/cooja/apps/serial_forwarder

5) Install additional packages that are needed to compile tikirisql(TikiriDB client).
   In the terminal type:
   # apt-get install flex bison

6) Compile tikirisql client
   In the terminal type:
   # cd 0.2/gateway/tikirisql
   # make

7) Open the file "0.2/test-apps/Makefile" with your favorite
   text editor and set the path to Contiki directory appropriately.

8) Go to "contiki-2.x/tools/cooja" directory and type,
    ant clean
    ant run
   This will open the cooja simulator. Close it.

9) Go to the directory "0.2/test-apps" and issue the command,
    make test-app.cooja TARGET=cooja

10) Now our cooja simulator will start and get ready to run tikiridb. In the GUI of the opened cooja, we should follow the precedure as follows. In the dialog box for create new simulation, click "Create button". In the next create mote type window, click "Compile". when it's done click on "Create". Now in the add motes window enter 2 for number of motes and then click "Create and add" button.Now in the "simulation visualizer" window, right click on a mote and "open mote plugin for contiki" &gt;&gt; serial forwarder. Then in the serial forwarder window, keep the default port value it has and click "start". Then in the control panel, click "start". A simulation error window will come. Close it and goto the menu bar,
        file &gt;&gt; reload simulation &gt;&gt; keep random seeds. Now the serial forwader will be running. Start the control panel also.

11) Go to the directory "0.2/gateway/tikirisql" and issue the command,
    ./tikirisql -H localhost -P 25601
   when you issue an sql query in the prompt and if it hangs without printing the data, there should be something wrong. Check whether the motes in the simulation are in within each others radio range. If not, drag them to closer.

Wednesday, March 9, 2011

TikiriDB: Compiling, Running and Exploring !


TikiriDB, the database abstraction for wireless sensor networks is an ongoing research work in our SCoRe lab. It's an application program written to the Contiki operating system which is a very powerful operating system used in wireless sensor networks. Initially TikiriDB was written completely in C language. The latest release of it was version 0.2 and it's a considerable time ago. However with different modifications to its architecture, TikiriDB is changing its shape. Currently most of it's parts has rewritten in Java language and under further development.
When testing and working with TikiriDB system, we have two options. First one is to use real hardware while second one is to use sensor network simulators. On development stages it's better to use simulators since if we use real hardware, we will be burning their memory modules over and over again for testing and debugging. These sensor network hardware costs thousands of money and it's better to keep them safe until a well tested, working version of program is available.

TikiriDB High level Overview 



Compiling and Running TikiriDB
Here I write the way to compile and run TikiriDB on a real sensor hardware. This description is about the currently released TikiriDB 0.2 version. I use MSB430 sensor nodes which are supported by the Contiki operating system. The first thing to do is downloading the software. We need TikiriDB 0.2 source which can be obtained from here (http://score.ucsc.lk). We also have to download the daily snapshot of the Contiki 2.x operating system source from here (http://www.sics.se/contiki/).

Create a new directory in a linux machine and put the two downloaded directories inside it. Let's say we have the following set up.
 

TikiriDB is here--> /[path to my directory]/0.2
Contiki is here--> /[path to my directory]/contiki-2.x

Open the make file in test-apps directory of TikiriDB and check whether it's attribute CONTIKI contains the correct path to the Contiki operating systems source directory. In our case, it should be just like below.

CONTIKI = ../../contiki-2.x

Now open this header file in Contiki, located at the path,
/[path to my directory]/contiki-2.x/platform/MSB430/contiki-conf.h
There you have to edit it's content at line numbers 9 to 11 and make those lines similar to the given below.

1:  #define NETSTACK_CONF_RADIO cc1020_driver  
2:  #define NETSTACK_CONF_RDC nullrdc_driver  
3:  #define NETSTACK_CONF_MAC nullmac_driver  

   

It's time to compile and upload TikiriDB and Contiki to sensor mote. We need a special compiler to compile tikiriDB to the MSP430 MCU platform. To install the compiler tool chain, follow this procedure.
Add this line to the software sources list of you Ubuntu machine,

deb http://wyper.ca/debian i686/ 

Then give this command from the terminal,
apt-get update
apt-get install binutils-msp430 gcc-msp430 msp430-libc msp430-jtag
 
Now you have to plug a MSB430 mote to the serial port of the PC with the provided cable. Then from a linux terminal, goto the test-apps directory in TikiriDB and apply this command.

chmod o+rw /dev/parport0
make TARGET=msb430 test-app.u

If everything went fine, TikiriDB application and the Contiki operating system will be compiled and uploaded to the MSB430 sensor mote. When it's done, remove the mote and plug another mote to the serial port. Apply the command again. By this way we can prepare all the motes that we hope to use in the sensor network. It's very important to remember that the motes should be equipped with batteries while programming, which I always forget.

Now we should compile and start the serial forwarder. Therefore goto the following directory and issue a “make” command.

/[path to my directory]/0.2/gateway/serial-forwarder-cpp

Then serial forwarder will get compiled. Now plug in a mote which will be our gateway node to the PC with the USB cable provided and put it's switch into USB mode. That means the mote receives a power supply from the PC through the USB cable and batteries are not necessary. Put other motes to the Battery mode and keep near the gateway node.

From the terminal where we issued make command, issue the following command to start serial forwarder.

./sf -s /dev/ttyUSB1 -b 115200 -p 10000

If this command give some errors, try using a different serial device like ttyUSB0 or something.

Now we need our TikiriDB client program to issue queries. Therefore goto the following directory from a different terminal window and issue the following commands.

cd /[path to my directory]/0.2/gateway/tikirisql
make
./tikirisql -H localhost -P 10000

Now we can issue queries to this prompt and get the data from it. For a help and example queries, type “help” or “\h” (without quotes) on the prompt.