:TEP: 106
:Group: Core Working Group
:Type: Documentary
-:Status: Draft
+:Status: Final
:TinyOS-Version: 2.x
:Author: Philip Levis and Cory Sharp
-:Draft-Created: 10-Dec-2004
-:Draft-Version: $Revision$
-:Draft-Modified: $Date$
-:Draft-Discuss: TinyOS Developer List <tinyos-devel at mail.millennium.berkeley.edu>
-
.. Note::
This memo documents a part of TinyOS for the TinyOS Community, and
Using this task interface, a component could post a task with a
``uint16_t`` parameter. When the scheduler runs the task, it will
signal the ``runTask`` event with the passed parameter, which contains
-the task's logic. Note, however, that this does not save any RAM: if
-anything, it will cost RAM as space must be allocated in the scheduler
-and may then also be allocated in the component. Furthermore, as
+the task's logic. Note, however, that this does not save any RAM:
+the scheduler must have RAM allocated for the parameter. Furthermore, as
there can only be one copy of a task outstanding at any time, it
is just as simple to store the variable in the component. E.g.,
rather than::
the scheduler to enter an infinite task-running loop, putting the MCU
into a low power state when the processor is idle: it never returns.
+The scheduler is repsonsible for putting the processor to sleep
+predominantly for efficiency reasons. Including the sleep call
+within the scheduler improves the efficiency of the task loop,
+in terms of the assembly generated by the TinyOS toolchain.
+
This is the TaskBasic interface::
interface TaskBasic {
next identifier off the queue and uses it to dispatch on the
parameterized TaskBasic interface.
+While the default TinyOS scheduler uses a FIFO policy, TinyOS
+components MUST NOT assume a FIFO policy. If two tasks must run
+in a particular temporal order, this order should be enforced by
+the earlier task posting the later task.
5. Replacing the Scheduler
====================================================================
TaskEdf interface. Its configuration SHOULD wire it to TinySchedulerC.
The key used for task unique identifiers MUST be "TinySchedulerC.TaskInterface",
where *TaskInterface* is the name of the new task interface as presented
-by the scheduler. For example, the module SomethingP requires two EDF
-tasks::
+by the scheduler. A common way to make sure a consistent string is used
+is to #define it. For example, TaskEdf.nc might include::
+#define UQ_TASK_EDF "TinySchedulerC.TaskEdf"
+
+In this example, the module SomethingP requires two EDF
+tasks::
+
configuration SomethingC {
...
}
implementation {
components SomethingP, TinySchedulerC;
- SomethingP.SendTask -> TinySchedulerC.TaskEdf["TinySchedulerC.TaskEdf"];
- SomethingP.SenseTask -> TinySchedulerC.TaskEdf["TinySchedulerC.TaskEdf"];
+ SomethingP.SendTask -> TinySchedulerC.TaskEdf[unique(UQ_TASK_EDF)];
+ SomethingP.SenseTask -> TinySchedulerC.TaskEdf[unique(UQ_TASK_EDF)];
}
The module SomethingP also has a basic task. The nesC compiler
The requirement that basic tasks not be subject to starvation
requires that a scheduler supporting EDF tasks must ensure that
basic tasks run eventually even if there is an unending stream of
-short deadline tasks to run.
+short deadline tasks to run. Quantifying "eventually" is difficult,
+but a 1% share of the MCU cycles (or invocations) is a reasonable
+approximation.
If the scheduler provides two instances of the same task interface,
their unique keys are based on the name of the interface as the