X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=doc%2Fhtml%2Ftutorial%2Flesson10.html;h=dd2b1dc06340da475f921d65a269920bdfb6a43a;hb=375431b9fbdd2459ffbb6b8db4729555b87ac063;hp=a159b9b22addb152f4f835cf884bd6262391e0bd;hpb=335b7ef46e2c205b98e96079e5f167369ea272da;p=tinyos-2.x.git diff --git a/doc/html/tutorial/lesson10.html b/doc/html/tutorial/lesson10.html index a159b9b2..dd2b1dc0 100644 --- a/doc/html/tutorial/lesson10.html +++ b/doc/html/tutorial/lesson10.html @@ -1,560 +1,14 @@ - - + + - TinyOS Tutorial Lesson 10: Platforms - +klueska.com - + + + <body> - -<div class="title">Lesson 10: Platforms</div> -<div class="subtitle">Last updated October 23 2006</div> - -<h1>Introduction</h1> - -<p>Many different hardware platforms (e.g micaZ, telos, eyesIFX) can be - used with TinyOS. This lesson shows you what a platform port consists - of, and how TinyOS reuses as much code as possible between different - platforms. - The lesson will proceed by showing how to do the port for an imaginary - mote called "yamp", which has a MSP430 microcontroller and a CC2420 - radio transceiver. - -<p> - The <b>target audience</b> of this lesson consists of those people that want - to better understand what the difference between e.g "make micaz" and "make - telosb" is, and how these differences concretely map into the underlying - files, definitions, etc. - -<p> Note that the material covered in this tutorial is <b>not</b> - strictly necessary for regular tinyos developpers, and you can safely skip - it if you have no intention of working down to the lowest level or - developping new platforms. - -</p> - -<h1>Chips vs Platforms</h1> - -<p> - Two key building blocks for any mote are the microcontroller and - radio transceiver. - Of course, both a microcontroller and a radio can be used on - more than one platform. This is indeed the case for the MSP430 and CC2420 - that our yamp mote uses (telos, eyes, and tinynode use the MSP430; telos - and micaz use the CC2420). -</p> - -<p> - Given this multiplicity of platforms, it would be vasly redundant if each - platform developper had to rewrite the software support for each chip - from scratch. While a chip may be physically wired in a different way on - different platforms (e.g., a radio is connected to a different digital - pins on the microcontroller), by far the largest part of the logic to - deal with a chip is platform-independent. -</p> - -<p> - Thus, platform-independent code to support a chip is placed in a - chip-specific directory. Writing a platform port for a platform is then - (essentially) a matter of <b>pulling in the code for each of the - platform's chips, and "gluing" things together</b>. - For example, the modules and components that support the CC2420 are in - tos/chips/cc2420. This radio is used on both the telos and micaZ motes; the - "gluing" is done by the modules in the tos/platforms/telosa/chips/cc2420 and - tos/platforms/micaz/chips/cc2420/ directories. -</p> - -<p> - Note that in general there may - be more to a platform port than pulling in existing code for different - chips, in particular when a new platform uses a chip that is not yet - supported. Developping drivers for a new chip can be a non-trivial - undertaking (especially for radios and microcontrollers); these aspects - are not covered here. -</p> - -<h1>Initial platform bring-up</h1> - -<p> - As a first step to bring up the platform, we will stick to the bare minimum in - order to compile and install the Null application on our yamp mote. -</p> - -<p> - All platform-specific code goes in tos/platforms/<platformname>. - For example, we have tos/platforms/micaz or tos/platforms/tinynode. - Our first step is to create a directory for the yamp platform: - <pre> - $ cd tinyos-2.x/tos/platforms - $ mkdir yamp - </pre> -</p> - -<h2>The .platform file</h2> - -Each platform directory (such as tos/platforms/yamp) should contain a -file named ".platform", that contains basic compiler parameters -information for each platform. So, create the file -"tos/platforms/yamp/.platform" (note the <b>.</b> in "<b>.</b>platform" !!!), that contains the following: - -<pre> - push( @includes, qw( - - %T/chips/cc2420 - %T/chips/msp430 - %T/chips/msp430/adc12 - %T/chips/msp430/dma - %T/chips/msp430/pins - %T/chips/msp430/timer - %T/chips/msp430/usart - %T/chips/msp430/sensors - %T/lib/timer - %T/lib/serial - %T/lib/power - ) ); - - @opts = qw( - - -gcc=msp430-gcc - -mmcu=msp430x1611 - -fnesc-target=msp430 - -fnesc-no-debug - -fnesc-scheduler=TinySchedulerC,TinySchedulerC.TaskBasic,TaskBasic,TaskBasic,runTask,postTask - - ); - -</pre> - -<p> - This file contains perl snippets that are intepreted by the ncc compiler. - The first statement simply adds some directories to the include path that - is used when compiling an application for the yamp platform (the %T gets - expanded to the full location of tinyos-2.x/tos, using the TOS2DIR - environment variable). Note that we have included the CC2420 and MSP430 - directories, as well as some libraries. -</p> - -<p> - The second statement defines the @opts list, that contains various parameters - passed to nesc. Please consult the nesc documentation for information on the - meaning of these parameters. -</p> - -<h2>The hardware.h file</h2> - -<p> - Each platform directory also has a file named "hardware.h" that is included by - default when compiling an application for that platform. This can define - platform-specific constants, pin names, or also include other "external" - header files (e.g. msp430hardware.h in our case, or atm128hardware.h for - platforms using the atm128 MCU).<br> - - So, create the file "tos/platforms/yamp/hardware.h" with the following contents: -</p> - -<pre> - #ifndef _H_hardware_h - #define _H_hardware_h - - #include "msp430hardware.h" - - // LEDs - TOSH_ASSIGN_PIN(RED_LED, 5, 4); - TOSH_ASSIGN_PIN(GREEN_LED, 5, 5); - TOSH_ASSIGN_PIN(YELLOW_LED, 5, 6); - - // UART pins - 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> - -<h1>Setting up the build environment and building the "null" app</h1> -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: - -<!-- <h2> Defining a make target</h3> --> - -<!-- At this point we have created all the necessary files in tos/platforms/yamp/ --> -<!-- in order to run the Null application. But how do we compile it and install it --> -<!-- on our yamp mote? --> - -<!-- We would like to enter "make yamp" in any application directory and have a --> -<!-- yamp binary be built, just as e.g. "make micaz" builds us a micaz --> -<!-- binary. But if we try it at this point we get an error message listing all the --> -<!-- valid targets and telling us that yamp is not a valid target: --> - -<pre> - $ cd tinyos-2.x/apps/Null - $ make yamp -/home/henridf/work/tinyos-2.x/support/make/Makerules:166: *** - -Usage: make <target> <extras> - make <target> 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 <target> 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> - -<h2> Defining a make target</h2> - -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: - -<pre> - -PLATFORM = yamp - -$(call TOSMake_include_platform,msp) - -yamp: $(BUILD_DEPS) - @: -</pre> - -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: - -<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> - -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: - -<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> - -, and create the file "tos/platforms/yamp/PlatformC.nc" as: - -<pre> -#include "hardware.h" - -configuration PlatformC -{ - provides interface Init; -} -implementation -{ - components PlatformP - , Msp430ClockC - ; - - Init = PlatformP; - PlatformP.Msp430ClockInit -> Msp430ClockC.Init; -} -</pre> - -Now, compilation of the Null application finally works for the yamp platform: - -<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> - - -<h1>Getting Blink to work</h1> - -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> -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> -As a first step, let's go to the Blink application directory and try to -compile the application: -<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> - -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> -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> -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> 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> 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> 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: - -<pre> -#include "hardware.h" - -configuration PlatformLedsC { - provides interface GeneralIO as Led0; - provides interface GeneralIO as Led1; - provides interface GeneralIO as Led2; - uses interface Init; -} -implementation -{ - components - HplMsp430GeneralIOC as GeneralIOC - , new Msp430GpioC() as Led0Impl - , new Msp430GpioC() as Led1Impl - , new Msp430GpioC() as Led2Impl - ; - components PlatformP; - - Init = PlatformP.LedsInit; - - Led0 = Led0Impl; - Led0Impl -> GeneralIOC.Port54; - - Led1 = Led1Impl; - Led1Impl -> GeneralIOC.Port55; - - Led2 = Led2Impl; - Led2Impl -> GeneralIOC.Port56; - -} -</pre> - -We refer the reader to the TinyOS Programming Guide cited below for more -explanations on how the above confiuration uses generics (ie with the "new" -keyword). For the purpose of this lesson, the key point is that we are wiring -to ports 5.4, 5.5, and 5.6 -- we shall suppose that these are the MSP430 -microcontroller pins to which the three Leds are connected on the yamp -platform. <p> - -With the above file in place, we can now compile Blink for the yamp platform. -How do we test that the application actually works? We have thus far presented -yamp as an imaginary platform, but it turns out that the above application -should work on any platform with the MSP430x1611 microcontroller and where the -Leds are connected to microcontroller ports 5.4-5.6. -Not entirely coincidentally, these are exactly the Led wirings used by the -telos/tmote platforms. So those readers that have a telos/tmote at hand can -test this application on it. (Testing on a tinynode or eyes mote is also easy and only -requires changing the pin wirings in PlatformLedsC to follow those of that -platform; running this application on mica-family motes will require more -changes since they use a different microcontroller). - -<p> -Now, enter the following command (where you have suitably replaced /dev/ttyXXX by the appropriate serial port), -<pre> - make yamp install bsl,/dev/ttyXXX -</pre> -and you will see the Leds of your impersonated (by a telos) yamp node Blinking! - -<h1>Conclusion</h1> - -<p>This lesson has introduced the notion of per-platform support in TinyOS - using as a guiding example the development of a platform port to an - imaginary "yamp" platform. We have seen how introducing support for a new - platform requires touching not only nesc code but also adding some rules to - the build system. This tutorial also touched upon the notions of Hardware - Abstraction Architecture (HAA) that is central to the clean and modular - support of different platforms and chips in TinyOS. -<p> - The steps outlined here did not cover what is the hardest part of - a platform port: developping the components to drive a radio transceiver or - MCU (which are necessary if the platform uses chips that are not currently - supported in TinyOS). Developping such drivers is an advanced topic that is - beyond the scope of the tutorials; for those curious to gain some insight we - recommend perusing the code for a chip (e.g the CC2420 radio in - tos/chips/cc2420 or the xe1205 radio in tos/chips/xe1205) armed with that - chips datasheet and the platform schematics. -<p> -<a name=#related_docs> -<h1>Related Documentation</h1> -</a> -<ul> -<li> <a href="https://sourceforge.net/projects/nescc">nesc at sourceforge</a> -<li> <a href="http://nescc.sourceforge.net/papers/nesc-ref.pdf">nesC reference manual</a> -<li> <a href="http://csl.stanford.edu/~pal/pubs/tinyos-programming-1-0.pdf">TinyOS Programming Guide</a> -<li> <a href="../tep102.html">TEP 2: Hardware Abstraction Architecture</a> -<li> <a href="../tep106.html">TEP 106: Schedulers and Tasks</a> -<li> <a href="../tep107.html">TEP 107: TinyOS 2.x Boot Sequence</a> -<li> <a href="../tep117.html">TEP 117: Low-level I/O</a> -</ul> - -<p> -<hr> - - -<!-- Begin footer --> -<br> -<hr> -<center> - <p>&lt;&nbsp;<b><a href="lesson8.html">Previous Lesson</a></b> |&nbsp; <b><a - href="index.html">Top</a></b> &nbsp;|&nbsp; <b><a href="lesson11.html">Next -Lesson </a>&nbsp;&gt;</b> -</p> - -&nbsp;</b> -</center> - +<p>Sorry, your browser does not support frames. Please <a href="http://docs.tinyos.net/index.php/Platforms" target="_top">go here</a>.</p> </body> -</html> + + + \ No newline at end of file