📄 platforms - tinyos documentation wiki.htm
字号:
TOSH_ASSIGN_PIN(SOMI0, 3, 2);
TOSH_ASSIGN_PIN(SIMO0, 3, 1);
TOSH_ASSIGN_PIN(UCLK0, 3, 3);
TOSH_ASSIGN_PIN(UTXD0, 3, 4);
TOSH_ASSIGN_PIN(URXD0, 3, 5);
TOSH_ASSIGN_PIN(UTXD1, 3, 6);
TOSH_ASSIGN_PIN(URXD1, 3, 7);
TOSH_ASSIGN_PIN(UCLK1, 5, 3);
TOSH_ASSIGN_PIN(SOMI1, 5, 2);
TOSH_ASSIGN_PIN(SIMO1, 5, 1);
#endif // _H_hardware_h
</PRE>
<P>This file simply pulls in msp430hardware.h from tos/chips/msp430 (the
compiler will find it because we have added this directory to our search path in
the .platform created previously) and defines some physical pins using macros
from msp430hardware.h. For example, on our yamp mote, the red led is physically
connected to the general purpose I/O (GPIO) pin 5.4. </P>
<P>Some other very important functions (that are defined in msp430hardware.h and
so pulled in indirectly via this hardware.h) concern the disabling of interrupts
for atomic sections (atomic blocks in nesc code essentially get converted into
__nesc_atomic_start() and __nesc_atomic_end()). How interrupts are disabled is
of course microcontroller specific; the same applies to putting the
microcontroller to sleep (as is done by the scheduler when there are no more
tasks to run, using the McuSleep interface). These functions must be somehow
defined for each platform, typically by means of an <TT>#include</TT>'d
MCU-specific file.<BR><I>As an exercise, try finding the definitions of</I>
__nesc_atomic_start() <I>and </I>__nesc_atomic_end()<I> for the micaZ and
intelmote2 platforms.</I> </P><A
name=Setting_up_the_build_environment_and_building_the_.22null.22_app></A>
<H1><SPAN class=mw-headline>Setting up the build environment and building the
"null" app</SPAN></H1>
<P>Before pulling in existing chip drivers or writing any code, we must set up
the build environment so that it is aware of and supports our platform. Once
this is done, we will define the basic TinyOS module for our platform, and use
the Null app (in tinyos-2.x/apps/null) in order to test that our platform is
properly configured. As per it's description in its README file, Null is an
empty skeleton application. It is useful to test that the build environment is
functional in its most minimal sense, i.e., you can correctly compile an
application. So, let's go ahead and try to compile Null for the yamp platform:
</P><PRE> $ cd tinyos-2.x/apps/Null
$ make yamp
/home/henridf/work/tinyos-2.x/support/make/Makerules:166: ***
Usage: make
make help
Valid targets: all btnode3 clean eyesIFX eyesIFXv1 eyesIFXv2 intelmote2 mica2 mica2dot micaz null telos telosa telosb tinynode tmote
Valid extras: docs ident_flags nescDecls nowiring rpc sim sim-cygwin sim-fast tos_image verbose wiring
Welcome to the TinyOS make system!
You must specify one of the valid targets and possibly some combination of
the extra options. Many targets have custom extras and extended help, so be
sure to try "make help" to learn of all the available features.
Global extras:
docs : compile additional nescdoc documentation
tinysec : compile with TinySec secure communication
ERROR, "yamp tos-ident-flags tos_image" does not specify a valid target. Stop.
</PRE>
<P>The problem is that we need to define the platform in the <I>TinyOS build
system</I>, so that the make invocation above recognizes the yamp platform. The
TinyOS build system is a Makefile-based set of rules and definitions that has a
very rich functionality. This includes invoking necessary compilation commands
as with any build system, but goes much further and includes support for other
important aspects such as device reprogramming or supporting multiple platforms
and targets. </P>
<P>A full description of the inner workings of the TinyOS build system is beyond
the scope of this tutorial. For now, we will simply see how to define the yamp
platform so that the "make yamp" command does what it should. (For those that
want to delve deeper, start with "tinyos-2.x/support/make/Makerules".) </P><A
name=Defining_a_make_target></A>
<H2><SPAN class=mw-headline>Defining a make target</SPAN></H2>
<P>The TinyOS build system resides in "tinyos-2.x/support/make". The strict
minimum for a platform to be recognized by the build system (i.e., for the build
system to understand that "yamp" is a legal platform when we enter "make yamp")
is the existence of a <I>platformname</I>.target file in the aforementioned make
directory.<BR>So, create the file "tinyos-2.x/support/make/yamp.target" with the
following contents: </P><PRE>PLATFORM = yamp
$(call TOSMake_include_platform,msp)
yamp: $(BUILD_DEPS)
@:
</PRE>
<P>This sets the PLATFORM variable to yamp, includes the msp platform
("make/msp/msp.rules") file, and provides in the last two lines a make rule for
building a yamp application using standard Makefile syntax. Now, let's go back
and try to compile the Null app as before. This time we get: </P><PRE>[18:23 henridf@tinyblue: ~/work/tinyos-2.x/apps/Null] make yamp
mkdir -p build/yamp
compiling NullAppC to a yamp binary
ncc -o build/yamp/main.exe -Os -Wall -Wshadow -DDEF_TOS_AM_GROUP=0x7d -Wnesc-all -target=yamp -fnesc-cfile=build/yamp/app.c -board= NullAppC.nc -lm
In file included from NullAppC.nc:42:
In component `MainC':
/home/henridf/work/tinyos-2.x/tos/system/MainC.nc:50: component PlatformC not found
/home/henridf/work/tinyos-2.x/tos/system/MainC.nc:53: no match
make: *** [exe0] Error 1
</PRE>
<P>So there's progress of sorts, since now we're getting a "real" compilation
error as opposed to not even making it past the build system. Let's take a
closer look at the output. The ncc compiler is unhappy about not finding a
"PlatformC" component. The "PlatformC" component must be defined for each
platform. Its role and placement in the system is described in more detail in
TEP107. For now, suffice to cite from that TEP that: <I>A port of TinyOS to a
new plaform MUST include a component PlatformC which provides one and only one
instance of the Init interface.</I>. Create the file
"tos/platforms/yamp/PlatformP.nc" with the following contents: </P><PRE> #include "hardware.h"
module PlatformP{
provides interface Init;
uses interface Init as Msp430ClockInit;
uses interface Init as LedsInit;
}
implementation {
command error_t Init.init() {
call Msp430ClockInit.init();
call LedsInit.init();
return SUCCESS;
}
default command error_t LedsInit.init() { return SUCCESS; }
}
</PRE>
<P>, and create the file "tos/platforms/yamp/PlatformC.nc" as: </P><PRE> #include "hardware.h"
configuration PlatformC
{
provides interface Init;
}
implementation
{
components PlatformP
, Msp430ClockC
;
Init = PlatformP;
PlatformP.Msp430ClockInit -> Msp430ClockC.Init;
}
</PRE>
<P>Now, compilation of the Null application finally works for the yamp platform:
</P><PRE>[19:47 henridf@tinyblue: ~/work/tinyos-2.x/apps/Null] make yamp
mkdir -p build/yamp
compiling NullAppC to a yamp binary
ncc -o build/yamp/main.exe -Os -Wall -Wshadow -DDEF_TOS_AM_GROUP=0x7d -Wnesc-all -target=yamp
-fnesc-cfile=build/yamp/app.c -board= NullAppC.nc -lm
compiled NullAppC to build/yamp/main.exe
1216 bytes in ROM
6 bytes in RAM
msp430-objcopy --output-target=ihex build/yamp/main.exe build/yamp/main.ihex
writing TOS image
</PRE><A name=Getting_Blink_to_work></A>
<H1><SPAN class=mw-headline>Getting Blink to work</SPAN></H1>
<P>With the previous steps, we now have the basic foundation to start working on
our yamp platform: the basic platform definitions are in place, and the build
system recognizes and correctly acts upon the "make yamp" target. We haven't yet
actually <I>programmed</I> our mote yet. </P>
<P>The next step in the bring-up of a platform, that we will cover in this part,
is to program a node with an application and verify that it actually works.
We'll do this with Blink, because it is simple, and easy to verify that it
works. As a bonus, we'll also have validated basic timer functionality once we
see those Leds turning on and off. </P>
<P>As a first step, let's go to the Blink application directory and try to
compile the application: </P><PRE>[19:06 henridf@tinyblue: ~/work/tinyos-2.x/apps/Blink] make yamp
mkdir -p build/yamp
compiling BlinkAppC to a yamp binary
ncc -o build/yamp/main.exe -Os -Wall -Wshadow -DDEF_TOS_AM_GROUP=0x7d -Wnesc-all -target=yamp
-fnesc-cfile=build/yamp/app.c -board= BlinkAppC.nc -lm
In file included from BlinkAppC.nc:45:
In component `LedsC':
/home/henridf/work/tinyos-2.x/tos/system/LedsC.nc:38: component PlatformLedsC not found
/home/henridf/work/tinyos-2.x/tos/system/LedsC.nc:42: cannot find `Init'
/home/henridf/work/tinyos-2.x/tos/system/LedsC.nc:43: cannot find `Led0'
/home/henridf/work/tinyos-2.x/tos/system/LedsC.nc:44: cannot find `Led1'
/home/henridf/work/tinyos-2.x/tos/system/LedsC.nc:45: cannot find `Led2'
make: *** [exe0] Error 1
</PRE>
<P>The compiler cannot find the component "PlatformLedsC" that is referred to in
the file tos/system/LedsC.nc. As the name indicates, "PlatformLedsC" is a
platform-specific component, and thus we will need to define this component for
the yamp platform. </P>
<P>Why should there be such a platform-specific component for accessing Leds?
This is because at the lowest level, i.e in hardware, Leds are implemented
differently on different platforms. Typically, a Led is connected to a
microcontroller I/O pin, and the Led is turned on/off by setting the appropriate
output 0/1 on that pin. This is in fact the model used on all current TinyOS
platforms. But even in this simple and uniform model, (and disregarding the fact
that future platforms may use different hardware implementations and not connect
each Led directly to an I/O pin), we have that the lowest-level to turn on/off a
Led must be defined on a per-platform basis. </P>
<P>Now, consider Leds from another perspective, namely that of the Leds.nc
interface (defined in tos/interfaces/Leds.nc). In this interface, we have
commands such as <TT>get();</TT> in principle such a command does not need to be
platform-dependent: the code that maintains the current state of a Led and
returns it via the get() call does not need to be re-written each time a Led is
connected to a different pin (of course re-writing get() for each platform would
not be much overhead given its simplicity; this argument clearly becomes far
stronger in more complex situations involving entire chips rather than
individual GPIOs). </P>
<P>The key notion that the above example is simply that there is a boundary
above which software components are platform-independent, and below which
components are specifically written with one hardware platform in mind. This is
at heart a very simple concept; its complete instantiation in TinyOS is of
course richer than the above example, and is the topic of TEP2 (Hardware
Abstraction Architecture). </P>
<P>Let's now return to the task at hand, which is to make Blink work on our
platform. If we take a closer look at the file "tos/system/LedsC.nc", we see
that it contains a configuration that wires the module LedsP with modules Init,
Leds0, Leds1, and Leds2, all of which are to be provided by the (still missing)
PlatformLedsC. Taking a closer look at "tos/system/LedsP.nc", we see that the
Leds0,1,2 modules used by LedsP are GeneralIO interfaces. The GeneralIO
interface (see "tos/interfaces/GeneralIO.nc" and TEP 117) simply encapsulates a
digital I/O pin and provides functions to control its direction and get/set its
input/output values. </P>
<P>So, we need to create a PlatformLedsC configuration that shall provide three
GeneralIO interfaces and an Init. This is done by creating the file
"tos/platforms/yamp/PlatformLedsC.nc" with the following contents: </P><PRE> #include "hardware.h"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -