[Tinyos-2-commits] CVS: tinyos-2.x/doc/txt tep106.txt, 1.1.2.3,
1.1.2.4
Phil Levis
scipio at users.sourceforge.net
Wed May 3 11:18:37 PDT 2006
Update of /cvsroot/tinyos/tinyos-2.x/doc/txt
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3867
Modified Files:
Tag: tinyos-2_0_devel-BRANCH
tep106.txt
Log Message:
David Gay's input.
Index: tep106.txt
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/doc/txt/Attic/tep106.txt,v
retrieving revision 1.1.2.3
retrieving revision 1.1.2.4
diff -C2 -d -r1.1.2.3 -r1.1.2.4
*** tep106.txt 23 Apr 2006 22:00:49 -0000 1.1.2.3
--- tep106.txt 3 May 2006 18:18:35 -0000 1.1.2.4
***************
*** 86,90 ****
1) Some components do not have a reasonable response to a failed ``post``
2) As a given task can be posted multiple times, it can consume more than one element in the buffer
! 3) All tasks from all components share a single resource: one misbehaving component cause other's posts to fail
--- 86,90 ----
1) Some components do not have a reasonable response to a failed ``post``
2) As a given task can be posted multiple times, it can consume more than one element in the buffer
! 3) All tasks from all components share a single resource: one misbehaving component can cause other's posts to fail
***************
*** 171,176 ****
}
! One can do this::
param = 34;
--- 171,186 ----
}
+ The semantics of tasks in TinyOS 2.x are different than those in 1.x.
+ This change is based on experiences with the limitations and run time
+ errors that the 1.x model introduces. **In TinyOS 2.x, a basic post will
+ only fail if the task has already been posted and has not started
+ execution.** A task can always run, but can only have one outstanding
+ post at any time. 2.x achieves these semantics by allocating a single
+ byte of state per task. While a very large number of tasks could make
+ this overhead noticable, it is not significant in practice.
+ If a component needs to post a task several times, then the end of
+ the task logic can repost itself as need be.
! For example, one can do this::
param = 34;
***************
*** 181,186 ****
}
-
-
4. The Scheduler in TinyOS 2.x
====================================================================
--- 191,194 ----
***************
*** 194,199 ****
The basic task in TinyOS 2.x is parameterless and FIFO. Tasks continue
to follow the nesC semantics of task and post, which are linguistic
! shortcuts for declaring a TaskBasic interface and wiring it to the
! Scheduler component. Appendix A describes how these shortcuts can be
configured. A scheduler provides a task interface as a parameterized
interface. Every task that wires to the interface uses the unique()
--- 202,207 ----
The basic task in TinyOS 2.x is parameterless and FIFO. Tasks continue
to follow the nesC semantics of task and post, which are linguistic
! shortcuts for declaring an interface and wiring it to the
! scheduler component. Appendix A describes how these shortcuts can be
configured. A scheduler provides a task interface as a parameterized
interface. Every task that wires to the interface uses the unique()
***************
*** 201,209 ****
dispatch tasks.
! For example, the standard TinyOS Scheduler has this signature:
! | ``module SchedulerBasic {``
| ``provides interface Scheduler;``
| ``provides interface TaskBasic[uint8_t taskID];``
| ``}``
--- 209,218 ----
dispatch tasks.
! For example, the standard TinyOS scheduler has this signature:
! | ``module SchedulerBasicP {``
| ``provides interface Scheduler;``
| ``provides interface TaskBasic[uint8_t taskID];``
+ | ``uses interface McuSleep;``
| ``}``
***************
*** 212,216 ****
eventually. The scheduler MUST return SUCCESS to a TaskBasic.postTask()
operation unless it is not the first call to TaskBasic.postTask() since
! that task's TaskBasic.runTask() event has been signaled.
A scheduler MUST provide the Scheduler interface.
--- 221,227 ----
eventually. The scheduler MUST return SUCCESS to a TaskBasic.postTask()
operation unless it is not the first call to TaskBasic.postTask() since
! that task's TaskBasic.runTask() event has been signaled. The
! McuSleep interface is used for microcontroller power management;
! its workings are explained in TEP 112[3]_.
A scheduler MUST provide the Scheduler interface.
***************
*** 218,224 ****
tasks, and is used by TinyOS to execute tasks.
! | ``interface SchedulerRun {``
| ``command void init();``
| ``command bool runNextTask(bool sleep);``
| ``}``
--- 229,236 ----
tasks, and is used by TinyOS to execute tasks.
! | ``interface Scheduler {``
| ``command void init();``
| ``command bool runNextTask(bool sleep);``
+ | ``command void taskLoop();``
| ``}``
***************
*** 232,236 ****
is executed, and SHOULD put the CPU to sleep until a new task arrives.
Calls of runNextTask(FALSE) may return TRUE or FALSE; calls of
! runNextTask(TRUE) always return TRUE.
This is the TaskBasic interface:
--- 244,250 ----
is executed, and SHOULD put the CPU to sleep until a new task arrives.
Calls of runNextTask(FALSE) may return TRUE or FALSE; calls of
! runNextTask(TRUE) always return TRUE. The taskLoop() command tells
! 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.
This is the TaskBasic interface:
***************
*** 243,256 ****
When a component declares a task with the ``task`` keyword in nesC, it
is implicitly declaring that it uses an instance of the TaskBasic
! interface: the task body is the run event. When a component uses the
! ``post`` keyword, it calls the post command. Each TaskBasic MUST be
! wired to the Scheduler with a unique identifier as its parameter.
The parameter MUST be obtained with the ``unique`` function in nesC,
! with a key of ``"BasicScheduler.TaskBasic"``. The nesC compiler
automatically does this wiring when the ``task`` and ``post``
keywords are used.
! The SchedulerBasic implementation uses these identifiers as its queue
! entries. When TinyOS tells the Scheduler to run a task, it pulls the
next identifier off the queue and uses it to dispatch on the
parameterized TaskBasic interface.
--- 257,270 ----
When a component declares a task with the ``task`` keyword in nesC, it
is implicitly declaring that it uses an instance of the TaskBasic
! interface: the task body is the runTask event. When a component uses the
! ``post`` keyword, it calls the postTask command. Each TaskBasic MUST be
! wired to the scheduler with a unique identifier as its parameter.
The parameter MUST be obtained with the ``unique`` function in nesC,
! with a key of ``"TinySchedulerC.TaskBasic"``. The nesC compiler
automatically does this wiring when the ``task`` and ``post``
keywords are used.
! The SchedulerBasicP implementation uses these identifiers as its queue
! entries. When TinyOS tells the scheduler to run a task, it pulls the
next identifier off the queue and uses it to dispatch on the
parameterized TaskBasic interface.
***************
*** 260,316 ****
====================================================================
! The TinyOS scheduler is presented as a component named TinyScheduler.
The default TinyOS scheduler implementation is a module named
! SchedulerBasic; the default Scheduler component is a configuration
! that provides wire-through of SchedulerBasic.
To replace the scheduler for a particular application, a developer
! SHOULD put a configuration named Scheduler in the application
! directory: this will replace the default. The Scheduler component
provides a wire-through of the desired scheduler implementation. All
scheduler implementations SHOULD provide a parameterize TaskBasic
! interface, as SchedulerBasic does; this supports nesC post statements
! and task declarations. All scheduler implementations MUST provide
! the Scheduler interface.
For example, imagine a hypothetical scheduler that provides earliest
! deadline first tasks, which are provided through the TaskEDF
interface:
! | ``interface TaskEDF {``
| ``async command error_t postTask(uint16_t deadlineMs);``
| ``event void runTask();``
| ``}``
! The scheduler implementation is named SchedulerEDF, and provides both
! TaskBasic and TaskEDF interfaces:
! | ``module SchedulerEDF {``
| ``provides interface Scheduler;``
| ``provides interface TaskBasic[uint8_t taskID];``
! | ``provides interface TaskEDF[uint8_t taskID];``
| ``}``
! An application that wants to use SchedulerEDF instead of
! SchedulerBasic includes a configuration named TinyScheduler, which
! exports all of SchedulerEDF's interfaces:
! | ``configuration TinyScheduler {``
| ``provides interface Scheduler;``
| ``provides interface TaskBasic[uint8_t taskID];``
! | ``provides interface TaskEDF[uint8_t taskID];``
| ``}``
| ``implementation {``
! | ``components SchedulerEDF;``
! | ``Scheduler = SchedulerEDF;``
! | ``TaskBasic = SchedulerEDF;``
! | ``TaskEDF = SchedulerEDF;``
| ``}``
For a module to have an earliest deadline first task, it uses the
! TaskEDF interface. Its configuration SHOULD wire it to TinyScheduler.
! The key used for task unique identifiers MUST be "TinyScheduler.TaskInterface",
where *TaskInterface* is the name of the new task interface as presented
! by the scheduler. For example, the module SomethingM requires two EDF
tasks:
--- 274,332 ----
====================================================================
! The TinyOS scheduler is presented as a component named TinySchedulerC.
The default TinyOS scheduler implementation is a module named
! SchedulerBasicP; the default scheduler component is a configuration
! that provides wire-through of SchedulerBasicP.
To replace the scheduler for a particular application, a developer
! SHOULD put a configuration named TinySchedulerC in the application
! directory: this will replace the default. The scheduler component
provides a wire-through of the desired scheduler implementation. All
scheduler implementations SHOULD provide a parameterize TaskBasic
! interface, as SchedulerBasicP does; this supports nesC post statements
! and task declarations. If a scheduler does not provide the TaskBasic
! interface, compiling applications requires modifying the standard
! ncc scheduler parameters (as described in Appendix A). All scheduler
! implementations MUST provide the Scheduler interface.
For example, imagine a hypothetical scheduler that provides earliest
! deadline first tasks, which are provided through the TaskEdf
interface:
! | ``interface TaskEdf {``
| ``async command error_t postTask(uint16_t deadlineMs);``
| ``event void runTask();``
| ``}``
! The scheduler implementation is named SchedulerEdfP, and provides both
! TaskBasic and TaskEdf interfaces:
! | ``module SchedulerEdfP {``
| ``provides interface Scheduler;``
| ``provides interface TaskBasic[uint8_t taskID];``
! | ``provides interface TaskEdf[uint8_t taskID];``
| ``}``
! An application that wants to use SchedulerEdfP instead of
! SchedulerBasicP includes a configuration named TinySchedulerC, which
! exports all of SchedulerEdfP's interfaces:
! | ``configuration TinySchedulerC {``
| ``provides interface Scheduler;``
| ``provides interface TaskBasic[uint8_t taskID];``
! | ``provides interface TaskEdf[uint8_t taskID];``
| ``}``
| ``implementation {``
! | ``components SchedulerEdfP;``
! | ``Scheduler = SchedulerEdf;``
! | ``TaskBasic = SchedulerEdfP;``
! | ``TaskEDF = SchedulerEdfP;``
| ``}``
For a module to have an earliest deadline first task, it uses the
! 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:
***************
*** 319,328 ****
| ``}``
| ``implementation {``
! | ``components SomethingM, TinyScheduler;``
! | ``SomethingM.SendTask -> TinyScheduler.TaskEDF["TinyScheduler.TaskEDF"];``
! | ``SomethingM.SenseTask -> TinyScheduler.TaskEDF["TinyScheduler.TaskEDF"];``
| ``}``
! The module SomethingM also has a basic task. The nesC compiler
automatically transforms task keywords into BasicTask interfaces and
wires them appropriately. Therefore, for basic tasks, a component
--- 335,344 ----
| ``}``
| ``implementation {``
! | ``components SomethingP, TinySchedulerC;``
! | ``SomethingP.SendTask -> TinySchedulerC.TaskEdf["TinySchedulerC.TaskEdf"];``
! | ``SomethingP.SenseTask -> TinySchedulerC.TaskEdf["TinySchedulerC.TaskEdf"];``
| ``}``
! The module SomethingP also has a basic task. The nesC compiler
automatically transforms task keywords into BasicTask interfaces and
wires them appropriately. Therefore, for basic tasks, a component
***************
*** 330,338 ****
interface. A component SHOULD use the keywords whenever possible, and it
MUST NOT mix the two syntaxes for a given task. This is an example
! implementation of SomethingM that uses keywords for basic tasks:
! | ``module SomethingM {``
! | ``uses interface TaskEDF as SendTask``
! | ``uses interface TaskEDF as SenseTask``
| ``}``
| ``implementation {``
--- 346,354 ----
interface. A component SHOULD use the keywords whenever possible, and it
MUST NOT mix the two syntaxes for a given task. This is an example
! implementation of SomethingP that uses keywords for basic tasks:
! | ``module SomethingP {``
! | ``uses interface TaskEdf as SendTask``
! | ``uses interface TaskEdf as SenseTask``
| ``}``
| ``implementation {``
***************
*** 356,360 ****
for the high priority queue before the standard queue:
! | ``configuration TinyScheduler {``
| ``provides interface Scheduler;``
| ``provides interface TaskBasic[uint8_t taskID];``
--- 372,376 ----
for the high priority queue before the standard queue:
! | ``configuration TinySchedulerC {``
| ``provides interface Scheduler;``
| ``provides interface TaskBasic[uint8_t taskID];``
***************
*** 363,373 ****
A component that uses a high priority task would then wire to
! TaskHighPriority with the key "TinyScheduler.TaskHighPriority":
| ``configuration SomethingElseC {``
| ``}``
| ``implementation {``
! | ``components TinyScheduler, SomethingElseM;``
! | ``SomethingElseM.RetransmitTask -> TinyScheduler.TaskHighPriority[unique("TinyScheduler.TaskHighPriority")];``
| ``}``
--- 379,389 ----
A component that uses a high priority task would then wire to
! TaskHighPriority with the key "TinySchedulerC.TaskHighPriority":
| ``configuration SomethingElseC {``
| ``}``
| ``implementation {``
! | ``components TinySchedulerC as Sched, SomethingElseP;``
! | ``SomethingElseP.RetransmitTask -> Sched.TaskHighPriority[unique("TinySchedulerC.TaskHighPriority")];``
| ``}``
***************
*** 406,409 ****
--- 422,426 ----
Programming Language Design and Implementation (PLDI).*
+ .. [3] TEP 112: Microcontroller Power Management.
More information about the Tinyos-2-commits
mailing list