This lesson describes the details of the TinyOS toolchain, including the build system, how to create your own Makefile, and how to find out more information on the various tools included with TinyOS.
apps/Blink
directory,
$ make mica2compiles Blink for the mica2 platform,
$ make mica2 installcompiles and installs (using the default parallel port programmer) Blink for the mica2, and
$ make mica2 reinstall mib510,/dev/ttyS0installs the previously compiled mica2 version of Blink using the MIB510 serial port programmer connected to serial port /dev/ttyS0.
As these examples show, the TinyOS build system is controlled by passing arguments to make that specify the target platform, the desired action, and various options. These arguments can be categorised as follows:
$ make micaz sim
$ make debug verbose telosb
Additionally, you can pass additional compilation options by
setting the CFLAGS environment variable when you invoke make. For instance,
to compile apps/RadioCountoToLeds
for a mica2 with
a 900MHz radio set to ~916.5MHz, you would do:
$ env CFLAGS="-DCC1K_DEF_FREQ=916534800" make mica2Note that this will not work with applications whose Makefile defines CFLAGS (but this practice is discouraged, see the section on writing Makefiles below).
Arguments to the programmer are specified with a comma after the programmer name, e.g.,
$ make mica2dot reinstall mib510,/dev/ttyUSB1
$ make telosb reinstall bsl,/dev/ttyUSB1to specify that the programmer is connected to serial port /dev/ttyUSB1.
More details on the programmers and their options can be found in your mote documentation.
MIB510 ?= /dev/ttyS1 PFLAGS = -DCC2420_DEF_CHANNEL=12in a file called
Makelocal
in the support/make
directory. If you now compile in apps/RadioCountToLeds
, you
will see:
$ make micaz install mib510 compiling RadioCountToLedsAppC to a micaz binary ncc -o build/micaz/main.exe -Os -DCC2420_DEF_CHANNEL=12 ... RadioCountToLedsAppC.nc -lm compiled RadioCountToLedsAppC to build/micaz/main.exe ... installing micaz binary using mib510 uisp -dprog=mib510 -dserial=/dev/ttyS1 ...The definition of
PFLAGS
passes an option to the nesC
compiler telling it to define the C preprocessor symbol
CC2420_DEF_CHANNEL
to 12. The CC2420 radio stack checks
the value of this symbol when setting its default channel.
The definition of MIB510
sets the value of the
argument to the mib510 installation option, i.e.,
$ make micaz install mib510is now equivalent to
$ make micaz install mib510,/dev/ttyS1Note that the assignment to MIB510 was written using the
?=
operator. If you just use regular assignment (=
), then the
value in Makelocal
will override any value you specify
on the command line (which is probably not what you want...).
Makelocal
can contain definitions for any make
variables used by the build system. Unless you understand the details of
how this works, we recommend you restrict yourselves to defining:
PFLAGS
: extra options to pass to the nesC compiler. Most
often used to define preprocessor symbols as seen above.
X
: set the argument for make argument
x, e.g., MIB510
as seen above. You can, e.g., set the
default mote id to 12 by adding INSTALL ?= 12
and
REINSTALL ?= 12
to Makelocal
.
Some useful preprocessor symbols that you can define with
PFLAGS
include:
Application Makefiles
To use the build system with your application, you must create a makefile
(a file called Makefile
) which contains at the minimum:
COMPONENT=TopLevelComponent include $(MAKERULES)where TopLevelComponent is the name of the top-level component of your application.
TinyOS applications commonly also need to specify some options to the
nesC compiler, and build some extra files alongside the TinyOS
application. We will see examples of both, by looking at, and making a
small change to, the apps/RadioCountToLeds
application.
The RadioCountToLeds Makefile uses mig
(see Lesson 4) to build files describing the layout
of its messages, for use with python and Java tools:
COMPONENT=RadioCountToLedsAppC BUILD_EXTRA_DEPS = RadioCountMsg.py RadioCountMsg.class RadioCountMsg.py: RadioCountToLeds.h mig python -target=$(PLATFORM) $(CFLAGS) -python-classname=RadioCountMsg RadioCountToLeds.h RadioCountMsg -o $@ RadioCountMsg.class: RadioCountMsg.java javac RadioCountMsg.java RadioCountMsg.java: RadioCountToLeds.h mig java -target=$(PLATFORM) $(CFLAGS) -java-classname=RadioCountMsg RadioCountToLeds.h RadioCountMsg -o $@ include $(MAKERULES)The first and last line of this Makefile are the basic lines present in all TinyOS Makefiles; the line in bold defining BUILD_EXTRA_DEPS specifies some additional make targets to build alongside the main TinyOS application (if you are not familiar with make, this may be a good time to read a make tutorial, e.g., this one).
When you compile RadioCountToLeds for the first time, you will see that
the two extra targets, RadioCountMsg.py
and
RadioCountMsg.class
, are automatically created:
$ make mica2 mkdir -p build/mica2 mig python -target=mica2 -python-classname=RadioCountMsg RadioCountToLeds.h RadioCountMsg -o RadioCountMsg.py mig java -target=mica2 -java-classname=RadioCountMsg RadioCountToLeds.h RadioCountMsg -o RadioCountMsg.java javac RadioCountMsg.java compiling RadioCountToLedsAppC to a mica2 binary ...As this Makefile is written, these generated files are not deleted when you execute
make clean
. Fix this by adding the following line:
CLEAN_EXTRA = $(BUILD_EXTRA_DEPS) RadioCountMsg.javato
apps/RadioCountToLeds/Makefile
. This defines the CLEAN_EXTRA
make variable to be the same as BUILD_EXTRA_DEPS, with RadioCountMsg.java
added to the end. The build system's clean target deletes all files
in CLEAN_EXTRA:
$ make clean rm -rf build RadioCountMsg.py RadioCountMsg.class RadioCountMsg.java rm -rf _TOSSIMmodule.so TOSSIM.pyc TOSSIM.pyFinally, to see how to pass options to the nesC compiler, we will change RadioCountToLeds's source code to set the message sending period based on the preprocessor symbol
SEND_PERIOD
. Change the line in
RadioCountToLedsC.nc
that reads
call MilliTimer.startPeriodic(1000);to
call MilliTimer.startPeriodic(SEND_PERIOD);and add the following line to RadioCountToLeds's Makefile:
CFLAGS += -DSEND_PERIOD=2000Note the use of
+=
when defining CFLAGS: this allows the user
to also pass options to nesC when invoking make as we saw above (env CFLAGS=x make ...
).
Now compiling RadioCountToLeds gives:
$ make mica2 ... compiling RadioCountToLedsAppC to a mica2 binary ncc -o build/mica2/main.exe ... -DSEND_PERIOD=2000 ... RadioCountToLedsAppC.nc -lm compiled RadioCountToLedsAppC to build/mica2/main.exe ...
First, we compile RadioCountToLedsAppC.nc (the main component of the application) using the nesC compiler, ncc:
$ ncc -target=micaz -o rcl.exe -Os -finline-limit=100000 -Wnesc-all -Wall RadioCountToLedsAppC.ncThis generates an executable file,
rcl.exe
. Next, we want
to install this program on a mote with mote id 15. First, we create a
new executable, rcl.exe-15
, where the variables storing the
mote's identity are changed to 15, using the
tos-set-symbols
command:
$ tos-set-symbols rcl.exe rcl.exe-15 TOS_NODE_ID=15 ActiveMessageAddressC\$addr=15Finally, we install this executable on the micaz using
uisp
,
to a mib510 programmer connected to port /dev/ttyUSB1:
$ uisp -dpart=ATmega128 -dprog=mib510 -dserial=/dev/ttyUSB1 --erase --upload if=rcl.exe-15 Firmware Version: 2.1 Atmel AVR ATmega128 is found. Uploading: flashIf you wish to follow this route, note two things: first, you can find out what commands the build system is executing by passing the
-n
option to make, which tells it to print rather than execute commands:
$ make -n micaz install.15 mib510 mkdir -p build/micaz echo " compiling RadioCountToLedsAppC to a micaz binary" ncc -o build/micaz/main.exe -Os -finline-limit=100000 -Wall -Wshadow -Wnesc-all -target=micaz -fnesc-cfile=build/micaz/app.c -board=micasb -fnesc-dump=wiring -fnesc-dump='interfaces(!abstract())' -fnesc-dump='referenced(interfacedefs, components)' -fnesc-dumpfile=build/micaz/wiring-check.xml RadioCountToLedsAppC.nc -lm nescc-wiring build/micaz/wiring-check.xml ...Second, all the commands invoked by the build system should have man pages describing their behaviour and options. For instance, try the following commands:
$ man tos-set-symbols $ man ncc $ man nescc
< Previous Lesson | Top >