dd {
margin-bottom: 0.5em }
-/* Uncomment (& remove this text!) to get bold-faced definition list terms
-dt {
- font-weight: bold }
-*/
-
div.abstract {
margin: 2em 5em }
<tr class="field"><th class="docinfo-name">Type:</th><td class="field-body">Documentary</td>
</tr>
<tr><th class="docinfo-name">Status:</th>
-<td>Draft</td></tr>
+<td>Final</td></tr>
<tr class="field"><th class="docinfo-name">TinyOS-Version:</th><td class="field-body">2.x</td>
</tr>
<tr><th class="docinfo-name">Author:</th>
<td>Philip Levis</td></tr>
-<tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">10-Dec-2004</td>
-</tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1.2.11</td>
-</tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2006-06-13</td>
-</tr>
-<tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List <tinyos-devel at mail.millennium.berkeley.edu></td>
-</tr>
</tbody>
</table>
<div class="note">
with a spin loop), MUST NOT return until complete. Otherwise the system
may start before initialization is complete.</p>
<p>The Scheduler interface is for initializing and controlling task
-execution. It is detailed in TEP 106 <a class="footnote-reference" href="#id5" id="id1" name="id1">[1]</a>.</p>
+execution. It is detailed in TEP 106 <a class="footnote-reference" href="#id7" id="id1" name="id1">[1]</a>.</p>
<p>The Boot interface has a single event, booted(), which the boot
sequence signals when it has completed:</p>
<pre class="literal-block">
implementation {
int main() __attribute__ ((C, spontaneous)) {
atomic {
+ platform_bootstrap();
call Scheduler.init();
call PlatformInit.init();
while (call Scheduler.runNextTask());
<p>The first step in the boot sequence is initializing the system:</p>
<pre class="literal-block">
atomic {
+ platform_bootstrap();
call Scheduler.init();
call PlatformInit.init();
while (call Scheduler.runNextTask());
while (call Scheduler.runNextTask());
}
</pre>
+<p>The first call, platform_bootstrap(), is a minimalist function that
+places the system into an executable state. This function MUST NOT include
+operations besides those which are absolutely necessary for further code,
+such as scheduler initialization, to execute.
+Examples of platform_bootstrap() operations are configuring the memory
+system and setting the processor mode. Generally, platform_bootstrap()
+is an empty function. TinyOS's top-level include file, <tt class="docutils literal"><span class="pre">tos.h</span></tt>, includes
+a default implementation of this function which does nothing. If a platform
+needs to replace the default, it SHOULD put it in a platform's
+<tt class="docutils literal"><span class="pre">platform.h</span></tt> file as a #define. The implementation of <tt class="docutils literal"><span class="pre">tos.h</span></tt>
+supports this:</p>
+<pre class="literal-block">
+/* This platform_bootstrap macro exists in accordance with TEP
+ 107. A platform may override this through a platform.h file. */
+#include <platform.h>
+#ifndef platform_bootstrap
+#define platform_bootstrap() {}
+#endif
+</pre>
<p>The boot sequence has three separate initializations: Scheduler,
PlatformInit, and SoftwareInit. The boot configuration (MainC) wires
the first two automatically, to TinySchedulerC (discussed in TEP 106)
hardware, the sequence is platform-specific. A port of TinyOS to a
new plaform MUST include a component PlatformC which provides
one and only one instance of the Init interface.</p>
+<p>Initializations invoked
+through PlatformC meet some or all of the following criteria:</p>
+<ol class="arabic simple">
+<li>The initialization requires configuring hardware resources. This implies that the code is platform-specific.</li>
+<li>The initialization should always be performed.</li>
+<li>The initialization is a prerequisite for common services in the system.</li>
+</ol>
+<p>Three example operations that often belong in PlatformInit are I/O pin
+configuration, clock calibration, and LED configuration. I/O pin
+configuration meets the first two criteria. It should always be performed
+(regardless of what components the OS uses) for low-power reasons:
+incorrectly configured pins can draw current and prevent the MCU from
+entering its lowest power sleep state <a class="footnote-reference" href="#id8" id="id3" name="id3">[2]</a>. Clock calibration meets
+all three criteria. LED configuration is a special case: while it
+nominally meets all three criteria, the most important one is the third:
+as LEDs are often needed during SoftwareInit initialization, they must
+be set up before it is invoked.</p>
+<p>Note that not all code which meets some of these criteria is wired through
+PlatformC. In particular, criterion 1 is typically necessary but not
+sufficient to require PlatformC. For example, a timer system that
+configures overflow and capture settings or a UART stack that sets the
+baud rate and transmission options can often be wired to SoftwareInit.
+They are encapsulated abstractions which will not be invoked or
+started until the boot event, and only need to be configured if the
+system includes their functionality.</p>
<p>Components whose initialization does not directly depend on hardware
resources SHOULD wire to MainC.SoftwareInit. If a component requires a
specific initialization ordering, then it is responsible for
dependencies unless they are required.</p>
<p>One common approach is for a configuration to "auto-wire" the
initialization routines of its internal components. The configuration
-does not provide an Init interface. Virtualized services (TEP 108)
+does not provide an Init interface. Virtualized services
often take this approach, as the service, rather than the clients, is
what needs to be initialized. For example, the standard Timer
-virtualization (TEP 102), TimerMilliC, wires to TimerMilliP, which is
+virtualization <a class="footnote-reference" href="#id9" id="id4" name="id4">[3]</a>, TimerMilliC, wires to TimerMilliP, which is
a very simple configuration that takes the underlying implementation
(HilTimerMilliC) and wires it to MainC:</p>
<pre class="literal-block">
configuration TimerMilliP {
- provides interface Timer<TMilli> as TimerMilli[uint8_t id];
+ provides interface Timer<TMilli> as Timinitialization in ordererMilli[uint8_t id];
}
implementation {
components HilTimerMilliC, MainC;
if the MCU supports doing so. Whichever mechanism is chosen, extreme
care needs to be used in order to not disrupt the operation of other
components.</p>
-<p>Unless part of a hardware abstraction architecture (HAA) <a class="footnote-reference" href="#id6" id="id3" name="id3">[2]</a>, the
+<p>Unless part of a hardware abstraction architecture (HAA) <a class="footnote-reference" href="#id10" id="id5" name="id5">[4]</a>, the
Init.init() command MUST NOT assume that other components have been
initialized unless it has initialized them, and MUST NOT call any
-functional interfaces on any components that might be shared. An HAA
+functional interfaces on any components that might be shared or
+interact with shared resources. Components MAY call functions
+on other components that are completely internal to the subsystem.
+For example, a networking layer can call queue operations to
+initialize its queue, but a link layer must not send commands
+over an SPI bus. An HAA
component MAY make other calls to initialize hardware state. A
component that is not part of an HAA SHOULD NOT call Init.init() on
other components unless it needs to enforce a temporal ordering on
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">RealMainP.nc</span></tt> is the module containing the function <tt class="docutils literal"><span class="pre">main</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">MainC.nc</span></tt> is the configuration that wires RealMainP to
-PlatformC and TinySchedulerC <a class="footnote-reference" href="#id5" id="id4" name="id4">[1]</a>.</li>
+PlatformC and TinySchedulerC <a class="footnote-reference" href="#id7" id="id6" name="id6">[1]</a>.</li>
</ul>
</blockquote>
</div>
</div>
<div class="section">
<h1><a id="citations" name="citations">7. Citations</a></h1>
-<table class="docutils footnote" frame="void" id="id5" rules="none">
+<table class="docutils footnote" frame="void" id="id7" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a name="id7">[1]</a></td><td><em>(<a class="fn-backref" href="#id1">1</a>, <a class="fn-backref" href="#id6">2</a>)</em> TEP 106: Schedulers and Tasks.</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="id8" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id3" name="id8">[2]</a></td><td>TEP 112: Microcontroller Power Management.</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="id9" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
-<tr><td class="label"><a name="id5">[1]</a></td><td><em>(<a class="fn-backref" href="#id1">1</a>, <a class="fn-backref" href="#id4">2</a>)</em> TEP 106: Schedulers and Tasks.</td></tr>
+<tr><td class="label"><a class="fn-backref" href="#id4" name="id9">[3]</a></td><td>TEP 102: Timers.</td></tr>
</tbody>
</table>
-<table class="docutils footnote" frame="void" id="id6" rules="none">
+<table class="docutils footnote" frame="void" id="id10" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id3" name="id6">[2]</a></td><td>TEP 2: Hardware Abstraction Architecture.</td></tr>
+<tr><td class="label"><a class="fn-backref" href="#id5" name="id10">[4]</a></td><td>TEP 2: Hardware Abstraction Architecture.</td></tr>
</tbody>
</table>
</div>