⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tep108.txt

📁 tinyos-2.x.rar
💻 TXT
📖 第 1 页 / 共 4 页
字号:
inside a generic configuration. Wrapping the component in this way ensures that
each Resource client is given a unique client ID, with the added
benefit of properly coupling multiple components that all need to
refer to the same client ID.

Appendix B also provides a complete example of how an I2C resource might be 
abstracted according to this pattern.  For further examples see the various 
chip implementations in the tinyos-2.x source tree under tinyos-2.x/chips/

3.2 ArbiterInfo
-------------------------------

Arbiters MUST provide an instance of the ArbiterInfo interface.
The ArbiterInfo interface allows a component to query the current 
status of an arbiter::

  interface ArbiterInfo {
    async command bool inUse();
    async command uint8_t clientId();
  }
  
In contrast to the parameterized Resource interface provided by an arbiter, 
only a single ArbiterInfo interface is provided.  Its purpose is 
to allow one to find out:

- Whether the resource for which it is arbitrating use is currently in use or not
- Which client is using it.

One can view ArbiterInfo as an interface for obtaining global information about  
the use of a resource, while Resource can be viewed as an interface for obtaining 
local access to that resource.

The primary use of the ArbiterInfo interface is to allow a shared resource to reject 
any calls made through its data interface by clients that do not currently have access to 
it.  For an example of how this interface is used in this fashion refer to Appendix B.::

           /|\                        /|\
            |                          |
            | Data Interface           | Resource
            |                          |  
  -----------------------------------------------------------
  |                     Shared Resource                     |
  -----------------------------------------------------------
           /|\                    /|\         /|\
            |                      |           |
            | Data Interface       | Resource  | ArbiterInfo
            |                      |           |
  ----------------------      -------------------------------
  | Dedicated Resource |      |           Arbiter           |
  ----------------------      -------------------------------

3.3 ResourceRequested
-------------------------------

Sometimes it is useful for a client to be able to hold onto a resource until 
someone else needs it and only at that time decide to release it.  Using the
ResourceRequested interface, this information is made available to the current
owner of a resource:: 

  interface ResourceRequested {
    async event void requested();
    async event void immediateRequested();
  }
  
A requested event is signaled to the current owner of the resource if another
client makes a request for the resource through the request() command of
its Resource interface.  If a request is made through the immediateRequest()
command, then the immediateRequested() event is signaled.
  
An arbiter SHOULD provide a parameterized ResourceRequested interface to its 
clients, but is not required to.  The client id of the parameterized 
ResourceRequested interface should be coupled with the client id of the Resource 
interface to ensure that all events are signaled to the proper clients.  Please 
refer to Appendix B for an example of how this interface might be used.::

           /|\                        /|\                   /|\
            |                          |                     |
            | Data Interface           | Resource            | ResourceRequested
            |                          |                     |
  --------------------------------------------------------------------------------
  |                              Shared Resource                                 |
  --------------------------------------------------------------------------------
           /|\                    /|\         /|\            /|\
            |                      |           |              |
            | Data Interface       | Resource  | ArbiterInfo  | ResourceRequested
            |                      |           |              |
  ----------------------      ----------------------------------------------------
  | Dedicated Resource |      |                     Arbiter                      |
  ----------------------      ----------------------------------------------------

3.4 ResourceConfigure
-------------------------------

The existence of the ResourceConfigure interface allows a resource to be 
automatically configured just before a client is granted access to it.
Components providing the ResourceConfigure interface use the interfaces
provided by an underlying dedicated resource to configure it into one
of its desired modes of operation.  A cleint then wires its shared resource 
abstraction to the component implementing the desired configuration.  The 
configure command is called immediataely before the client is granted access 
to the resource, and the unconfigure command is called just before fully 
releasing it.::

  interface ResourceConfigure {
    async command void configure();
    async command void unconfigure();
  }
  
:: 

    ResourceConfigure       ResourceConfigure      ResourceConfigure
           |                       |                     /|\
           |                       |                      |
          \|/                     \|/                     |                
  -------------------     -------------------    ------------------- 
  | Configuration 1 |     | Configuration 2 |    | Shared Resource |
  -------------------     -------------------    -------------------
           |                       |                     /|\
           |   Control Interface   |                      | ResourceConfigure
          \|/                     \|/                     |
        ------------------------------               -----------                 
        |     Dedicated Resource     |               | Arbiter |
        ------------------------------               -----------

The arbiter SHOULD use a parameterized ResourceConfigure interface, with 
its client ID parameter coupled with the client id of its parameterized
Resource interface.  If an arbiter uses the ResourceConfigure interface, 
it MUST call ResourceConfigure.configure() on the granted client ID 
before it signals the Resource.granted() event. Similarly, after a valid
call to Resource.release(), it MUST call ResourceConfigure.unconfigure() 
on the releasing client ID.  By calling ResourceConfigure.configure() just
before granting a client access to a resource and calling 
ResourceConfigure.unconfigure() just before fully releasing it, it is guaranteed
that a resource is always unconfigured before an attempt to configure it can be 
made again.

The commands included in this interface could have been made part of the standard
Resource interface (and changed into callback events), but at a higher cost than 
keeping them separate. Introducing these new commands into the Resource interface 
would have lead to a large number of clients all including redundant configuration 
code, while using the call out approach to a separate component ensures that we 
only have a single instance of the code. 

For an example of how configurations for the three different modes of the 
Msp430 Usart component can take advantage of the ResourceConfigure 
interface refer to Appendix B as well as section 4 on the use of 
cross-component reservation.

3.5 ResourceDefaultOwner
-------------------------------

The normal Resource interface is for use by clients that all share the resource 
in an equal fashion. The ResourceDefaultOwner interface is for use by a single 
client that needs to be given control of the resource whenever no one else is 
using it. An arbiter MAY provide a single instance of the ResourceDefaultOwner 
interface. It MUST NOT provide more than one.::

  interface ResourceDefaultOwner {
    async event void granted();
    async command error_t release();
    async command bool isOwner();
    async event void requested();
    async event void immediateRequested();
  }
  
The Arbiter MUST guarantee that the client of the ResourceDefaulrClient interface is
made the owner of the resource before the boot initialization sequence is 
completed.  When a normal resource client makes a request for the resource, the 
ResourceDefaultOwner will receive either a requested() or an immediateRequested() 
event depending on how the request was made.  It must then decide if and when to 
release it.  Once released, all clients that have pending requests will be 
granted access to the resource in the order determined by the queuing policy of 
the arbiter in use.  Once all pending requests have been granted (including 
those that came in while other clients had access to the resource), the 
ResourceDefaultOwner is automatically given control of the resource, receiving its 
granted() event in the process.  The ResourceDefaultOwner interface also contains 
the same isOwner() command as the normal Resource interface, and the semantics 
of its use are exactly the same.

Although the ResourceDefaultOwner interface looks similar to a combination of the 
normal Resource interface and the ResourceRequested interface, its intended use 
is quite different.  The ResourceDefaultOwner interface should only be used by 
clients that wish to have access to a resource only when no other clients are 
using it.  They do not actively seek access to the resource, but rather use 
it to perform operations when it would otherwise simply be idle.  
  
The primary motivation behind the definition of the ResourceDefaultOwner 
interface is to allow for an easy integration of power management
for a resource with its arbitration policy.  Arbiters that want to allow 
a resource to be controlled by a particular power management policy can 
provide the ResourceDefaultOwner interface for use by a component that 
implements that policy. The power management component will receive the 
granted() event whenever the resource has gone idle, and will proceed in
powering it down.  When another client requests the resource, the power 
manager will be notified through either the requested() or 
immediateRequested() events as appropriate.  It can then power up the resource 
and release it once the power up has completed.  Note that if power up is 
a split-phase operation (takes a while), then calls by clients to 
immediateRequest() when in the powered down state will return 
FAIL. Please see the TEP on the Power Management of Non-Virtualized devices
([4]_) for more details.

4. Cross-Component Reservation
====================================================================

In some cases, it is desirable to share the reservation of a
single resource across multiple components. For example, on the TI
MSP430, a single USART component can be used as an I2C bus, a UART,
or an SPI connection. Clearly, on this chip, a reservation of the I2C
bus implicitly restricts the corresponding UART and SPI
services from gaining access to the resource. Enforcing such a policy
can be accomplished in the framework described above by:

 1) Creating a set of unique ids for each service using the shared
    resource.

 2) Mapping these ids onto the ids of the underlying resource

Clients connecting to these services do not know that that this
mapping is taking place.  As far as they are concerned, the only
arbitration taking place is between other clients using the same
service.  In the MSP430 example, a single client of the I2C bus could
be contending with a single client of the SPI connection, but they
would probably have the same service level client ID.  These two
service level client ids would be mapped onto 2 unique resource ids
for use by the shared USART component. The proper way to achieve this
mapping is through the use of generic components.  The example given
below shows how to perform this mapping for the SPI component on the
MSP430.  It is done similarly for the UART and I2C bus::

  #include "Msp430Usart.h"
  generic configuration Msp430Spi0C() {
    provides interface Resource;
    provides interface SpiByte;
    provides interface SpiPacket;
  }
  implementation {
    enum { CLIENT_ID = unique(MSP430_SPIO_BUS) };

    components Msp430Spi0P as SpiP;
    Resource = SpiP.Resource[ CLIENT_ID ];
    SpiByte = SpiP.SpiByte;
    SpiPacket = SpiP.SpiPacket[ CLIENT_ID ];

    components new Msp430Usart0C() as UsartC;
    SpiP.UsartResource[ CLIENT_ID ] -> UsartC.Resource;
    SpiP.UsartInterrupts -> UsartC.HplMsp430UsartInterrupts;
  }

The definition of the MSP430_SPIO_BUS string is defined in
Msp430Usart.h. A unique id is created from this string every time a
new Msp430Spi0C component is instantiated.  This id is used as a
parameter to the parameterized Resource interface provided by the
Msp430Spi0P component.  This is where the mapping of the two
different ids begins.  As well as *providing* a parameterized
Resource interface (Msp430Spi0P.Resource), the Msp430Spi0P component 
also *uses* a parameterized Resource interface (Msp430Spi0P.UsartResource). 
Whenever a client makes a call through the provided Resource interface 
with id CLIENT_ID, an underlying call to the Msp430Spi0P.Resource interface 
with the same id is implicitly made.  By then wiring the Msp430Spi0P.UsartResource 
interface with id CLIENT_ID to an instance of the Resource interface 
provided by the instantiation of the Msp430Usart0C component, the mapping 
is complete. Any calls to the Resource interface provided by a new 
instantiation of the Msp430Spi0C component will now be made through a 
unique Resource interface on the underlying  Msp430Usart0C component.

This level of indirection is necessary because it may not always be
desirable to directly wire the service level Resource interface to
the underlying shared Resource interface.  Sometimes we may want to
perform some operations between a service level command being

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -