📄 tep131.txt
字号:
|
V
Target
platform
The core TinyOS platforms are centered around GCC, this includes the
telos family, mica family and intelmote2. The nesC compiler expects
code resembling GCC C-dialect and also outputs code in GCC
C-dialect. The current TinyOS platforms are supported by GCC, but for
some processor architectures GCC is not available (e.g. Motorola HCS08,
Intel MCS51).
Porting to platforms that are GCC supported can benefit from the
existing tool flow, while porting to other platforms requires some
effort. A straight forward solution adopted for these platforms is to
post-process the C files produced by nesC to fit the needs of a
specific compiler, see TEP121 for an example of such a solution.
3.2 The Make System
--------------------------------------------------------------------
TinyOS controls the build process using make. The global make file
searches certain locations to find make definitions for all available
platforms. In order to make a new platform available to the TinyOS
make system, a few files must be created in particular locations. These
files will be read by the global make system and exposed to the users
by make targets. Often the required rules are tied to a particular MCU
that is shared among several platforms and TinyOS leverages this fact
by creating a light-weight *.target* file pointing to the appropriate
rules in a *.rules* file. The make system is documented in
``support/make/README`` and in TinyOS 2 Tutorial Lesson 10[TUT10_].
The make system looks for *.target* files in ``support/make`` and the
directories listed in the environment variable ``TOSMAKE_PATH``. Each
of the files found contain make targets for one TinyOS platform. The
target files usually do not contain the rules to build the binary
files, but include the appropriate rules from a *.rules* file, located
in a sub directory for the appropriate MCU architecture (e.g. avr for
the ATMega128 used by Mica). In this way many platforms share the
build rules, but have different *.target* files. In addition *.extra*
targets can be used to define helper targets such as install or clean.
Setting up the make system, requires two steps (Section 3.2.1 gives an
example):
1. Creating a *platformX.target* file that allows the make system to
discover the new platform. This file must contain a make rule with
the name of the platform. Further this target must depend on the
targets given in the variable ``BUILD_DEPS`` - this variable
contains the remainder of targets to be build during the build
process.
2. Creating a *.rules* file in a sub diretory of
``support/make``. Each file contain the actual target for
producing the binaries, hex files, etc. for one platform. They are
assembled in the ``BUILD_DEPS`` variable.
We will cover these two files next.
3.2.1 The .target file
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
As mentioned above TinyOS searches for targets in the ``support/make``
directory of the TinyOS source code and in the directories listed in
the environment variable ``TOSMAKE_PATH``. A *.target* file for the
platform must exist in one of these locations. The *.target* usually
only sets up variables related to this platform and provide a target
named after the platform, this target depend on other rules to build
the binaries. These rules are included by calling
*TOSMake_include_platform*. As an example the ``mica2.target`` is
listed below:
::
PLATFORM = mica2
SENSORBOARD ?= micasb
PROGRAMMER_PART ?= -dpart=ATmega128 --wr_fuse_e=ff
PFLAGS += -finline-limit=100000
AVR_FUSE_H ?= 0xd9
$(call TOSMake_include_platform,avr)
mica2: $(BUILD_DEPS)
@:
Pay attention to the call to *TOSMake_include_platform,avr* this call
includes ``.rules`` files in ``support/make`` or any sub directory of
``TOSHMAKE_PATH`` named *avr*.
3.2.2 The .rules file
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The *.rules* file contain the make rules for building the target
binary. If a MCU implementation already exists for a new platform,
simply pointing to this *.rules* from the corresponding *.target* is
sufficient. If not the *.rules* file must be built for a new MCU
architecture.
``TOSMake_include_platform`` expects a sub directory with a rule file
of the form ``avr/avr.rules``. The call also includes additional
*.rules* and *.extra* files present in that sub directory. See
``support/make/README`` for details.
For example a simplified .rules file could look like this (from
*avr/avr.rules*):
::
...
BUILD_DEPS = srec tosimage
srec: exe FORCE
$(OBJCOPY) --output-target=srec $(MAIN_EXE) $(MAIN_SREC)
tosimage: ihex build_tosimage FORCE
@:
exe: builddir $(BUILD_EXTRA_DEPS) FORCE
@echo " compiling $(COMPONENT) to a $(PLATFORM) binary"
$(NCC) -o $(MAIN_EXE) $(OPTFLAGS) $(PFLAGS) $(CFLAGS)
$(COMPONENT).nc $(LIBS) $(LDFLAGS)
...
4. The Platform
====================================================================
A TinyOS platform is a collection of components corresponding to a
physical devices (a collection of drivers). A platform is constructed
by defining which components make up the platform and by providing any
additional platform specific components. The content of a platform is
not covered by a TEP at the time of writing and the following is based
on the available tutorials, *READMEs* and the current consensus.
The platform definitions for a *PlatformX* are located in
``tos/platforms/platformX`` and contain 3 major elements:
1. The *.platform* file containing include paths and other arguments
for nesC
2. Platform boot procedure: PlatformP/PlatformC
3. Platform specific code, including a header for hardware specific
funtions (hardware.h) and code that is specific to the combination
of chip and platform (e.g. pin assignments, modifications, etc.).
In the following we will describe each of these in more detail, below
is a depiction of a fictuous platform and the required definitions.
::
Platform: .platform
include MCU driver
+-------------------------+ include Radio driver
| | include Sensors driver
| Chips: |
| +-------+ | PlatformP
| | Radio | | Initialize MCU
| +--+----+ | Initialize Sensor
| +-----+ | | Initialize Radio
| | MCU +------+ |
| +-----+ | | hardware.h
| +--+----+ | Include MCU HW macros
| | Leds | |
| +-------+ | HIL interfaces, eg:
| | PlatformLeds
+-------------------------+
All the files we describe here must be found in a common directory
named after the platform; we call this a platform directory. This
directory must be found in the TinyOS tool chain search path for
example ``tos/platforms`` (or found in ``TOSHMAKE_PATH`` see Section
3.2.1). For example a platform named PlatformX could be placed in the
directory ``tos/platforms/platformX``.
4.1 .platform file
--------------------------------------------------------------------
All platform directories must carry a ``.platform`` file, this file
defines what makes up the platform. This file carries instructions for
the make system on where to locate the drivers for each of the
components of the platform. The definitions are read in a two step
process: the file is read by the ncc script that passes the
appropriate arguments to the nesC pre-processor[nescman_]. The
.platform file is written as a Perl script interpreted by ncc.
The file is documented in form of the README file in the platforms
directory (*tos/platforms*), and the source code of the ncc script
found in the TinyOS distribution. Valuable information can also be
found in [TEP106_], [TEP109_], TinyOS 2 Tutorial Lesson 10[TUT10_].
In addition to setting up include paths for nesC other arguments can
be passed on. In particular the components to be used for the
scheduler are selected with the '-fnesc-scheduler' command line
argument (see [TEP106_]). The include paths are passed on using the
'-I' command line argument covered in [TEP109_].
As an example, an abbreviated *.platform* file for the mica2 platform
looks like this:
::
push( @includes, qw(
%T/platforms/mica
%T/platforms/mica2/chips/cc1000
%T/chips/cc1000
%T/chips/atm128
%T/chips/atm128/adc
%T/chips/atm128/pins
%T/chips/atm128/spi
%T/chips/atm128/timer
%T/lib/timer
%T/lib/serial
%T/lib/power
) );
@opts = qw(
-gcc=avr-gcc
-mmcu=atmega128
-fnesc-target=avr
-fnesc-no-debug
-fnesc-scheduler=TinySchedulerC,TinySchedulerC.TaskBasic,TaskBasic,TaskBasic,runTask,postTask
);
4.2 PlatformP and PlatformC
--------------------------------------------------------------------
The PlatformP and PlatformC components are responsible for booting
this platform to a usable state. In general this usually means things
like calibrating clock and initializing I/O pins. If this platform
requires that some devices are initialized in a particular order this
can be implemented in a platform dependent way here. The boot process
covered in [TEP107_].
Most hardware peripherals require an initialization procedure of some
sort. For most peripheral devices this procedure is only required when
the device is in use and can be left out if the device is
unused. TinyOS accomplishes this by providing a few initialization
call backs interfaces. When a given component is included it wires an
initialization procedure to one of these interfaces. In this way the
procedure will only be included when the component is included, this
process is known as auto wiring[TOSPRG_].
The boot sequence calls two initialization interfaces in the following
order: ``PlatformC.Init`` and ``MainC.SoftwareInit``.
``PlatformC.Init`` must take care of initializing the hardware to an
operable state and initialization that has hidden dependencies must
occur here. Other components are initialized as part of
``SoftwareInit`` and the orderign is determined at compile
time.
Common tasks in ``PlatformC.Init`` include clock calibration and IO
pins. However this component can be used to provide greater control of
the boot process if required. Consider for example that some component
which is initialized in SoftwareInit requires that some other
component has been initialized previously - lets say that the radio
must be initialized prior to the radio stack or that a component
prints a message to the UART during boot. How can this order be
ensured? One solution is to provide an additional initialization
handle prior to SoftwareInit and wire such procedures to this
handle. Below is an example from the Mica mote family using the
``MoteInit`` interface. Components that must be initialized early in
the boot process is wired to this interface. If greater level of
control is required this strategy can be trivially be expanded to
further levels of interfaces for example MoteInit1 being initialized
prior to MoteInit2, this strategy is chosen by the MSP430
implementation.
4.2.1 PlatformC
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Below is depicted the PlatformC component from the Mica family of platforms.
::
#include "hardware.h"
configuration PlatformC {
provides {
interface Init;
/**
* Provides calibration information for other components.
*/
interface Atm128Calibrate;
}
uses interface Init as SubInit;
} implementation {
components PlatformP, MotePlatformC, MeasureClockC;
Init = PlatformP;
Atm128Calibrate = MeasureClockC;
PlatformP.MeasureClock -> MeasureClockC;
PlatformP.MoteInit -> MotePlatformC;
MotePlatformC.SubInit = SubInit;
}
4.2.1 PlatformP
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Below is depicted the PlatformP component from the Mica family of platforms.
::
module PlatformP
{
provides interface Init;
uses interface Init as MoteInit;
uses interface Init as MeasureClock;
}
implementation
{
void power_init() {
...
}
command error_t Init.init()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -