1. Platform Specific Code
In addition to PlatformP/PlatformC the platform directory contain additional code that is specific to this platform. First this could be code that ties platform independent resources to particular instances on this platform, second it could be code that is only relevant on this particular platform (e.g. the clock rate of this platform). For example the LEDs are a an example of the rst: most platform have a few LEDs, and the particular pin on this platform is tied to the platform independent implementation using PlatformLedsC.
TinyOS requires that the header hardware.h is present while other component can be named freely.
1.1 Platform Headers
TinyOS relies on a few C-header files being present for each platform. These headers are then automatically included from the respective parts of the TinyOS system. TinyOS expects that the following files are present and that certain properties are defined in them.


The hardware.h header file is included by tos/system/MainC.nc and usually in turn includes a MCU specific header file, with a few required macros (such as avr128hardware.h, see Section 5.1.1). The header is documented in TinyOS 2 Tutorial Lesson 10[TUT10]

In addition the hardware.h file can set flags that are not related to the hardware in general, but to this platform (e.g. clock rate). Below is a snippet from mica2/hardware.h
#ifndef MHZ
/* Clock rate is ~8MHz except if specified by user
    (this value must be a power of 2, see MicaTimer.h and Measure-
    ClockC.nc) */
#define MHZ 8
#include <atm128hardware.h>
enum {

As part of the TinyOS 2 message buffer abstraction[TEP111], TinyOS includes the header platform message.h
from the internal TinyOS header message.h. This header is only strictly required for platforms wishing to use the message_t abstraction – this is not described further in this TEP, but is used widely throughout TinyOS (See [TEP111] for details). The is expected to define the structures: message header_t, message footer_t, and message metadata_t which are used to ll out the generic message t structure.
Below is an example from the mica2 platform message.h

typedef union message_header {
    cc1000_header_t cc1k;
    serial_header_t serial;
} message_header_t;
typedef union message_footer {
    cc1000_footer_t cc1k;
} message_footer_t;
typedef union message_metadata {
    cc1000_metadata_t cc1k;
} message_metadata_t;

1.2 Platform Specfic Components
The code for platform dependent features also resides in the platform directory. If the code can be tied to a particular chip it can be placed in a separate directory below the chips directory. As an example the following section of micaz/chips/cc2420/HplCC2420PinsC.nc ties speci c pins to general names on the MicaZ platform.
configuration HplCC2420PinsC {
provides {
interface GeneralIO as CCA;
interface GeneralIO as CSN;
interface GeneralIO as FIFO;
interface GeneralIO as FIFOP;
interface GeneralIO as RSTN;
interface GeneralIO as SFD;
interface GeneralIO as VREN;
implementation {
components HplAtm128GeneralIOC as IO;
CCA = IO.PortD6;
CSN = IO.PortB0;
FIFO = IO.PortB7;
FIFOP = IO.PortE6;
RSTN = IO.PortA6;
SFD = IO.PortD4;
VREN = IO.PortA5;

2. The chips
The functionality of each chip is provided by a set of one or more interfaces and one or more components, in traditional terms this makes up a driver. Each chip is assigned a sub directory in the the tos/chips directory. All code that de ne the functionality of a chip is located here regardless of the type of chip (MCU, radio, etc.). In addition MCU’s group the code related to separate sub systems into further sub directories (e.g. tos/chips/atm128/timer).
In this section we will go trough some of the peripherals commonly built into MCUs, but we will not go trough other chips such as sensors or radio.
2.1 MCU Internals
Apart from the drivers for each of the peripheral units, a few additional de nitions are required for the
internals of the MCU. This includes i) atomic begin/end and ii) low power mode. The rst is de ned
in the header hardware.h and the latter component MCUSleepC.
5.1.1 mcuXardware.h
Each architecture de nes a set of required and useful macros in a header led named after the archi-
tecture (for example atm128hardware.h for ATMega128). This header is then in turn included from
hardware.h in the platform directory (See Section 4.3.1).
A few of the macros are required by nesC code generation. nesC will output code using these macros
and they must be de ned in advance, other useful macros such as interrupt handlers on this particular
platform can be de ned here as well. The required macros are:
nesc enable interrupt / nesc disable interrupt
nesc atomic start / nesc atomic end
Below is a few examples from atm128hardware.h
/* We need slightly different defs than SIGNAL, INTERRUPT */
#define AVR_ATOMIC_HANDLER(signame) \
void signame() __attribute__ ((signal)) @atomic_hwevent() @C()
#define AVR_NONATOMIC_HANDLER(signame) \
void signame() __attribute__ ((interrupt)) @hwevent() @C()

inline void __nesc_enable_interrupt() { sei(); }
inline void __nesc_disable_interrupt() { cli(); }

inline __nesc_atomic_t
__nesc_atomic_start(void) @spontaneous() {
__nesc_atomic_t result = SREG;
asm volatile("" : : : "memory");
return result;
/* Restores interrupt mask to original state. */
inline void
__nesc_atomic_end(__nesc_atomic_t original_SREG) @spontaneous() {
asm volatile("" : : : "memory");
SREG = original_SREG;