IppatsuMan - TinyOS installation
Installation on Linux from source code
Introduction
As part of my Ph.D. research I often write software based on TinyOS that will run on sensor nodes. Although there are easy means to have TinyOS up and running (like using the Xubuntu Live CD image, the RPM packets or the Stanford repository), I prefer to install everything from scratch, using only the source code. In this how-to I describe how to install the CVS version of TinyOS 2.x on Linux. My target is Ubuntu Linux 10.04 Lucid Lynx, but I tested this method on Ubuntu 9.10 Karmic Koala and on Debian 5 too. Anyway the specific Linux distribution is relevant only for the initial installation of needed software. I'll use apt-get to install software, for any non-Debian based distribution, please use its specific package manager.
Software components
To install TinyOS you need to install three/four main components:
- the TinyOS source files, i.e. the .nc files that will be compiled and uploaded on your motes;
- the nesC compiler, that compiles the .nc files in standard C;
- a cross compiler, i.e. a compiler that runs on your computer but has as output binary files targeting a different architecture.
The installation must be made in reverse order: first the cross compiler(s), then the nesC compiler, finally TinyOS.
Installation
Shopping list
To install TinyOS, nesC and the cross compilers, we need to install some additional software:
- cvs;
- gcc and g++;
- graphviz;
- Java JRE and JDK;
- libgmp3-dev, libgmp3c2, libmpfr-dev and libmpfr1ldbl;
- make and automake;
- tinfoil.
On Debian, enable the non-free repository and run as root
aptitude install automake cs g++ gcc graphviz libgmp3-dev libgmp3c2 libmpfr-dev libmpfr1ldbl make sun-java6-jdk texinfo
On Ubuntu, enable the multiverse repository ad run:
sudo aptitude install automake build-essential cvs graphviz libgmp3-dev libgmp3c2 libmpfr-dev libmpfr1ldbl make sun-java6-jdk texinfo
The downloading and installation may take a while, these packages sum up to several hundreds of MiB. Wait for the installation to finish before going to the next step.
On Debian and Ubuntu, to set Oracle's JDK as default Java installation, run as root:
update-java-alternatives -s java-6-sun
Installing GCC for MSP430
As first step, we'll install the GCC toolchain for the Texas Instruments MSP430 MCUs. This toolchain is needed to compile software for motes using the MSP430 microcontroller, for example the TelosB and shimmer motes. Create a directory for it and set it as current directory:
mkdir -p tinyossrc/gccmsp430 cd tinyossrc/gccmsp430
Then, download the vanilla binutils and GCC sources, that we'll patch in the following steps to make it support MSP430:
wget ftp://sources.redhat.com/pub/binutils/releases/binutils-2.19.tar.bz2 wget ftp://ftp.gnu.org/gnu/gcc/gcc-3.2.3/gcc-core-3.2.3.tar.bz2 wget ftp://ftp.gnu.org/gnu/gcc/gcc-3.2.3/gcc-g++-3.2.3.tar.bz2
Let's download the GCC MSP430 patches:
export CVSROOT=:pserver:anonymous@mspgcc.cvs.sourceforge.net:/cvsroot/mspgcc export CVS_RSH=ssh cvs login
When asked for password, just press enter. Then, checkout from cvs the files to patch GCC:
cvs checkout gcc cvs checkout msp430-libc cvs checkout packaging
We have all the files needed to compile GCC for MSP430. Let's compile binutils. The pattern is: extract the tarball, patch, compile, install. Create the directory where we'll compile binutils and then extract the tarball:
mkdir build-binutils tar xzvf binutils-2.19.tar.bz2 cd binutils-2.19
Second step: patch the source code, using the patches checked out from CVS:
patch -p1 < ../packaging/patches/binutils-2.19-patch
Third step: configure and compile:
cd ../build-binutils ../binutils-2.19/configure --target=msp430 --prefix=/usr/local/msp430 make
Depending on how fast your system is, the compilation of binutils may take any time between five minutes and an hour. Have a break. Then, run as root make install. If you are using on Ubuntu:
sudo -s make install exit
Back to the user sell, we need to add the newly installed MSP430 binutils to the PATH environment variable:
export PATH=$PATH:/usr/local/msp430/bin
Now go back to the gccmsp430 directory and extract the GCC and g++ tarballs:
cd .. tar xzvf gcc-core-3.2.3.tar.bz2 tar xzvf gcc-g++-3.2.3.tar.bz2
To patch GCC, we need to copy the files provided by the GCC MSP430 project:
cp -av gcc/gcc-3.3/* gcc-3.2.3
Now create the directory where we'll compile GCC:
mkdir build-gcc cd build-gcc
Compile GCC:
../gcc-3.2.3/configure --target=msp430 --prefix=/usr/local/msp430 make
Install GCC:
sudo -s export PATH=$PATH:/usr/local/msp430/bin make install exit
Last step: compilate and install the MSP430 libc library:
cd ../msp430-libc/src make sudo -s export PATH=$PATH:/usr/local/msp430/bin make install exit
Installing GCC for AVR32
Many motes use Atmel's MCU, for example MICAz, MICA2 and IRIS. To download Atmel's GNU Toolchain for AVR32 go to http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4118, click on AVR32 GNU Toolchain 2.4.2 - Linux Source Code and follow the procedure to download the file named avr32_gnu_toolchain_2.4.2_source.zip. Put it into the directory tinyossrc/avr32. Then, extract all the tarballs:
for f in *.tar.gz ; do tar xzvf "$f" ; done
Again, the first step is to compile binutils. Extract the tarball (again!):
cd avr32-binutils-2.19.atmel.1.2.0 tar xvf binutils-2.19.tar.bz2
To successfully compile binutils, we need to apply a patch not provided by atmel. Using your favourite text editor, create a file called 40-binutils-2.19-avr32-opcodes-sprintf.patch into the directory avr32-binutils-2.19.atmel.1.2.0 and write in it the following data:
--- opcodes/avr-dis.c 2010-05-14 16:37:44.965947901 +0200
+++ opcodes/avr-dis.c 2010-05-14 16:40:30.705945553 +0200
@@ -109,7 +109,7 @@ avr_operand (unsigned int insn, unsigned
case 0x100e: xyz = "-X"; break;
default: xyz = "??"; ok = 0;
}
- sprintf (buf, xyz);
+ sprintf (buf, "%s", xyz);
if (AVR_UNDEF_P (insn))
sprintf (comment, _("undefined"));
@@ -149,7 +149,7 @@ avr_operand (unsigned int insn, unsigned
value of the address only once, but this would mean recoding
objdump_print_address() which would affect many targets. */
sprintf (buf, "%#lx", (unsigned long) *sym_addr);
- sprintf (comment, comment_start);
+ sprintf (comment, "%s", comment_start);
break;
case 'L':
@@ -158,7 +158,7 @@ avr_operand (unsigned int insn, unsigned
sprintf (buf, ".%+-8d", rel_addr);
*sym = 1;
*sym_addr = pc + 2 + rel_addr;
- sprintf (comment, comment_start);
+ sprintf (comment, "%s", comment_start);
}
break;
@@ -169,7 +169,7 @@ avr_operand (unsigned int insn, unsigned
sprintf (buf, ".%+-8d", rel_addr);
*sym = 1;
*sym_addr = pc + 2 + rel_addr;
- sprintf (comment, comment_start);
+ sprintf (comment, "%s", comment_start);
}
break;
Now patch the binutils source code:
cd binutils-2.19 for p in ../*.patch ; do patch -p0 < "$p" ; done
Compile binutils:
cd ../.. mkdir build-binutils cd build-binutils ../avr32-binutils-2.19.atmel.1.2.0/binutils-2.19/configure --target=avr --prefix=/usr/local/avr make
This may take a while. Then, install binutils:
sudo -s make install exit
Back to the user sell, we need to add the newly installed AVR32 binutils to the PATH environment variable:
export PATH=$PATH:/usr/local/avr/bin
Now extract the GCC tarball, apply the AVR32 patches and create a directory for GCC's binaries:
cd .. cd avr32-gcc-4.3.2-atmel.1.2.0 tar xzvf gcc-4.3.2.tar.bz2 cd gcc-4.3.2 for p in ../*.patch ; do patch -p0 < "$p" ; done cd ../.. mkdir build-gcc
We'll compile GCC in three steps:
- first we'll compile the "first stage" or "bootstrap" compiler;
- then the newlib library, that is a C library optimized for embedded platforms;
- finally we'll finish the GCC compilation.
Configure and compile the first stage of GCC:
cd build-gcc ../avr32-gcc-4.3.2-atmel.1.2.0/gcc-4.3.2/configure --target=avr --prefix=/usr/local/avr --without-headers --with-newlib --with-gnu-as --with-gnu-ld make all-gcc
Then install it:
sudo -s export PATH=$PATH:/usr/local/avr/bin make install-gcc exit
Extract the newlib tarball, apply the AVR32 patches and create a directory for newlib's binaries:
cd .. cd avr-newlib-1.16.0.atmel.1.1.0 tar xvf newlib-1.16.0.tar.gz cd newlib-1.16.0 for p in ../*.patch ; do patch -p0 < "$p" ; done cd ../.. mkdir build-newlib
Configure and compile newlib:
cd build-newlib ../avr32-newlib-1.16.0.atmel.1.1.0/newlib-1.16.0/configure --target=avr --prefix=/usr/local/avr make all
Install newlib:
sudo -s export PATH=$PATH:/usr/local/avr/bin make install exit
Complete GCC's compilation:
cd ../build-gcc ../avr32-gcc-4.3.2-atmel.1.2.0/gcc-4.3.2/configure --target=avr --prefix=/usr/local/avr --with-newlib --with-gnu-as --with-gnu-ld --disable-shared --disable-libssp --enable-languages=c,c++ make all
Install GCC:
sudo -s export PATH=$PATH:/usr/local/avr/bin make install exit
And that's it! After few (?) easy (?) steps, GCC for MSP430 and AVR32 is installed!
nesC compiler
Compared to build a complete toolchain for another system, building nescc it's a snap. Set tinyossrc as current directory and download the latest source code from nescc SourceForge page.
mkdir nescc cd nescc wget http://ignum.dl.sourceforge.net/project/nescc/nescc/v1.3.1/nesc-1.3.1.tar.gz
Extract the tarball, configure the source code and compile it:
tar xzvf nesc-1.3.1.tar.gz cd nesc-1.3.1 ./configure --prefix=/usr/local make
Install nescc:
sudo -s make install exit
Easy, isn't it?
TinyOS
Now everything is in place to install TinyOS from CVS. We'll install it in /opt.
Using root rights, make the /opt directory world-writable:
sudo chmod o+w /opt
Checkout TinyOS' source files from CVS:
cvs -d:pserver:anonymous@tinyos.cvs.sourceforge.net:/cvsroot/tinyos login cvs -z3 -d:pserver:anonymous@tinyos.cvs.sourceforge.net:/cvsroot/tinyos co -P tinyos-2.x
Make the /opt directory writable only for root:
sudo chmod o-w /opt
TinyOS relies on environment variables to work:
export TOSROOT=/opt/tinyos-2.x export TOSDIR=$TOSROOT/tos export MAKERULES=$TOSROOT/support/make/Makerules export CLASSPATH=.:$TOSROOT/support/sdk/java/tinyos.jar
Now compile and install TinyOS' tools:
cd /opt/tinyos-2.x/tools ./Bootstrap ./configure --prefix=/usr/local/tinyos make
Install TinyOS' tools:
sudo -s make install exit
During the installation, you may get error messages like: "64-bit libgetenv.so NOT GENERATED - DO NOT USE THIS RUN TO BUILD AN RPM". They are safe to ignore, just press enter to skip them.
Add TinyOS' tools directory to PATH and, finally, install the JNI libraries:
sudo -s export PATH=$PATH:/usr/local/tinyos/bin tos-install-jni
tos-install-jni may give you an error like [: 31: =: unexpected operator. It is due to a syntax error in the tos-install-jni script, in can be safely ignored.
I had some problems with the tinyos.jar library checked out from the CVS. So, recompile it:
cd /opt/tinyos-2.x/support/sdk/java make
Finalize installation
Finally, it's desirable to permanently export all the environment variables used in this how-to. There are basically two options: you can modify the /etc/profile file to make TinyOS easily available to all users, or you can modify the ~/.bashrc if you are the only one that needs to use TinyOS. Whatever your choice is, open your target file (/etc/profile or ~/.bashrc) and append the following instructions to the end:
export PATH=$PATH:/usr/local/msp430/bin:/usr/local/avr/bin:/usr/local/nesc/bin:/usr/local/tinyos/bin export TOSROOT=/opt/tinyos-2.x export TOSDIR=$TOSROOT/tos export MAKERULES=$TOSROOT/support/make/Makerules export CLASSPATH=.:$TOSROOT/support/sdk/java/tinyos.jar
Make sure that everything works by running tos-check-env. Its output should be similar to this:
Path:
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/msp430/bin
/usr/local/avr/bin
/usr/local/nesc/bin
/usr/local/tinyos/bin
Classpath:
.
/opt/tinyos-2.x/support/sdk/java/tinyos.jar
rpms:
nesc:
/usr/local/nesc/bin/nescc
Version: nescc: 1.3.1
perl:
/usr/bin/perl
Version: v5.10.0 built for x86_64-linux-gnu-thread-multi
flex:
/usr/bin/flex
bison:
/usr/bin/bison
java:
/usr/bin/java
--> WARNING: The JAVA version found first by tos-check-env may not be version 1.4 or version 1.5one of which is required by TOS. Please ensure that the located Java version is 1.4 or 1.5
graphviz:
/usr/bin/dot
dot - Graphviz version 2.20.2 (Wed Sep 16 11:12:21 UTC 2009)
--> WARNING: The graphviz (dot) version found by tos-check-env is not 1.10. Please update your graphviz version if you'd like to use the nescdoc documentation generator.
tos-check-env completed with errors:
--> WARNING: The JAVA version found first by tos-check-env may not be version 1.4 or version 1.5one of which is required by TOS. Please ensure that the located Java version is 1.4 or 1.5
--> WARNING: The graphviz (dot) version found by tos-check-env is not 1.10. Please update your graphviz version if you'd like to use the nescdoc documentation generator.
tos-check-env reports some errors because it isn't able to recognize the recent versions of graphviz and Java. Those warnings can be safely ignored.
That's it, enjoy your fresh installed TinyOS!




