+.. [4] TEP 115: Power Management of Non-Virtualized Devices.
+.. [5] TinyOS Programming. http://csl.stanford.edu/~pal/pubs/tinyos-programming-1-0.pdf
+
+Appendix A: Resource Class Examples
+====================================================================
+
+Dedicated Resource
+--------------------------------------------------------------------
+Timer 2 on the Atmega128 microprocessor is a dedicated resource
+represented by the HplAtm128Timer2C component::
+
+ module HplAtm128Timer2C {
+ provides {
+ interface HplTimer<uint8_t> as Timer2 @exactlyonce();
+ interface HplTimerCtrl8 as Timer2Ctrl @exactlyonce();
+ interface HplCompare<uint8_t> as Compare2 @exactlyonce();
+ }
+ }
+
+Only a single client can wire to any of these interfaces as enforced through
+the nesC @exactlyonce attribute. Keep in mind that although the interfaces of
+this component are only allowed to be wired to once, nothing prevents the
+component wiring to them from virtualizing the services they provide at some
+higher level. If you are unfamiliar with how @exactlyonce and other nesC
+attributes are used to by the nesC compiler, please refer to section 9.1 of the
+TinyOS Programming Manual [5]_.
+
+Virtualized Resource
+--------------------------------------------------------------------
+
+The TimerMilliC component provides a virtual abstraction of millisecond
+precision timers to application components [2]_. It encapsulates the required
+parameterized Timer interface through the use of a generic configuration.
+Clients wishing to use a millisecond timer need only instantiate a single
+instance of the TimerMilliC generic, leaving the fact that it is virtualized
+underneath transparent.::
+
+ generic configuration TimerMilliC {
+ provides interface Timer<TMilli>;
+ }
+ implementation {
+ components TimerMilliP;
+ Timer = TimerMilliP.TimerMilli[unique(UQ_TIMER_MILLI)];
+ }
+
+The actual parameterized Timer interface is provided by the chip specific
+HilTimerMilliC component. This interface is exposed through
+the TimerMilliP component which wires HilTimerMilliC to the boot
+initialization sequence::
+
+ configuration TimerMilliP {
+ provides interface Timer<TMilli> as TimerMilli[uint8_t num];
+ }
+ implementation {
+ components HilTimerMilliC, MainC;
+ MainC.SoftwareInit -> HilTimerMilliC;
+ TimerMilli = HilTimerMilliC;
+ }
+
+Appendix B: Arbiter Interface Examples
+====================================================================
+
+.. Note:
+ Most of the examples provided in this section use complex nesC syntax that may
+ be unfamiliar to the novice nesC programmer. Please refer to the TinyOS
+ programming Manual [5]_ for clarification as necessary.
+
+Resource
+--------------------------------------------------------------------
+Examples of how to use the Resource interface for arbitrating
+between multiple clients can be found in the tinyos-2.x
+source tree under tinyos-2.x/apps/tests/TestArbiter.
+
+A specific example of where the Resource.isOwner() is used
+can be seen in the HplTda5250DataP component of the Infineon
+Tda5250 radio implementation::
+
+ async command error_t HplTda5250Data.tx(uint8_t data) {
+ if(call UartResource.isOwner() == FALSE)
+ return FAIL;
+ call Usart.tx(data);
+ return SUCCESS;
+ }
+
+A call to the HplTda5250Data.tx command will fail if the radio does
+not currently have control of the underlying Usart resource. If it
+does, then the Usart.tx(data) command is called as requested.
+
+A component using the Resource interface to implement an I2C
+service might look like this::
+
+ #include I2CPacket.h
+ configuration I2CPacketP {
+ provides interface Resource[uint8_t client];
+ provides interface I2CPacket<I2CAddrSize>[uint8_t client];
+ }
+ implementation {
+ components new FcfsArbiterC(I2CPACKET_RESOURCE) as Arbiter;
+ components I2CPacketImplP() as I2C;
+ ...
+
+ Resource = Arbiter;
+ I2CPacket = I2C;
+ ...
+ }
+
+where I2CPacketImplP contains the actual implementation of the
+I2C service, and I2CPacket.h contains the #define for the
+name of the resource required by the arbiter::
+
+ #ifndef I2CPACKETC_H
+ #define I2CPACKETC_H
+ #define I2CPACKET_RESOURCE "I2CPacket.Resource"
+ #endif
+
+This service would then be made available to a user through
+the generic configuration seen below::
+
+ #include I2CPacket.h
+ generic configuration I2CPacketC {
+ provides interface Resource;
+ provides interface I2CPacket<I2CAddrSize>;
+ }
+ implementation {
+ enum { CLIENT_ID = unique(I2CPACKET_RESOURCE) };
+
+ components I2CPacketP as I2C;
+ Resource = I2C.Resource[CLIENT_ID];
+ I2CPacket = I2C.I2CPacket[CLIENT_ID];
+ }
+
+In this example, an instance of the I2CPacket interface is coupled with
+an instance of the Resource interface on every new instantiation of
+the I2CPacketC component. In this way, a single Resource and a
+single I2CPacket interface can be exported by this component together
+for use by a client.
+
+Clients of the I2C service would use it as follows::
+
+ module I2CClientP {
+ uses interface Resource as I2CResource;
+ uses interface I2CPacket<I2CAddrSize>;
+ } ...
+
+ configuration I2CClientC { }
+ implementation {
+ components I2CClientP, new I2CPacketC();
+
+ I2CClientP.I2CResource -> I2CPacketC.Resource;
+ I2CUserM.I2CPacket -> I2CPacket.I2CPacket;
+ }
+
+ArbiterInfo
+--------------------------------------------------------------------
+In the implementation of the ADC component on the Msp430 microcontroller,
+a simple arbiter is used to provide a round robin sharing policy
+between clients of the ADC::
+
+ configuration Msp430Adc12C {
+ provides interface Resource[uint8_t id];
+ provides interface Msp430Adc12SingleChannel[uint8_t id];
+ provides interface Msp430Adc12FastSingleChannel[uint8_t id];
+ }
+ implementation {
+ components Msp430Adc12P,MainC,
+ new SimpleRoundRobinArbiterC(MSP430ADC12_RESOURCE) as Arbiter,
+ ...
+
+ Resource = Arbiter;
+ SingleChannel = Msp430Adc12P.SingleChannel;
+ FastSingleChannel = Msp430Adc12P.FastSingleChannel;
+
+ Msp430Adc12P.Init <- MainC;
+ Msp430Adc12P.ADCArbiterInfo -> Arbiter;
+ ...
+ }
+
+In this configuration we see that the Resource interface provided by
+Msp430Adc12C is wired directly to the instance of the SimpleRoundRobinArbiterC
+component that is created. The ArbiterInfo interface provided by
+SimpleRoundRobinArbiterC is then wired to Msp430Adc12P. The Msp430Adc12P
+component then uses this interface to perform run time checks to ensure that
+only the client that currently has access to the ADC resource is able to
+use it::
+
+ async command error_t Msp430Adc12SingleChannel.getSingleData[uint8_t id]() {
+ if (call ADCArbiterInfo.userId() == id){
+ configureChannel()
+ // Start getting data
+ }
+ else return ERESERVE;
+ }
+
+ async command error_t Msp430Adc12FastSingleChannel.configure[uint8_t id]() {
+ if (call ADCArbiterInfo.userId() == id){
+ clientID = id
+ configureChannel()
+ }
+ else return ERESERVE;
+ }
+
+ async command error_t Msp430Adc12FastSingleChannel.getSingleData[uint8_t id]()
+ {
+ if (clientID = id)
+ // Start getting data
+ else return ERESERVE;
+ }
+
+In order for these runtime checks to succeed, users of the
+Msp430Adc12SingleChannel and Msp430Adc12FastSingleChannel interfaces will have
+to match their client id's with the client id of a corresponding Resource
+interface. This can be done in the following way::
+
+ generic configuration Msp430Adc12ClientC() {
+ provides interface Resource;
+ provides interface Msp430Adc12SingleChannel;
+ }
+ implementation {
+ components Msp430Adc12C;
+ enum { ID = unique(MSP430ADC12_RESOURCE) };
+
+ Resource = Msp430Adc12C.Resource[ID];
+ Msp430Adc12SingleChannel = Msp430Adc12C.SingleChannel[ID];
+ }
+
+::
+
+ generic configuration Msp430Adc12FastClientC() {
+ provides interface Resource;
+ provides interface Msp430Adc12FastSingleChannel;
+ }
+ implementation {
+ components Msp430Adc12C;
+ enum { ID = unique(MSP430ADC12_RESOURCE) };
+
+ Resource = Msp430Adc12C.Resource[ID];
+ Msp430Adc12FastSingleChannel = Msp430Adc12C.SingleChannel[ID];
+ }
+
+Since these are generic components, users simply need to instantiate them
+in order to get access to a single Resource interface that is already
+properly coupled with a Msp430Adc12SingleChannel or Msp430Adc12FastSingleChannel
+interface.
+
+Take a look in the tinyos-2.x source tree under tinyos-2.x/tos/chips/adc12
+to see the full implementation of these components in their original context.
+
+ResourceRequested
+--------------------------------------------------------------------
+On the eyesIFXv2 platform, both the radio and the flash need access to the bus
+provided by the Usart0 component on the Msp430 microcontroller. Using
+a simple cooperative arbitration policy, these two components should able to
+share the Usart resource by only holding on to it as long as they need it and
+then releasing it for use by the other component. In the case of the MAC
+implementation of the Tda5250 radio component, however, the Msp430 Usart
+resource needs be held onto indefinitely. It only ever considers releasing the
+resource if a request from the flash component comes in through its
+ResourceRequested interface. If it cannot release it right away (i.e. it is in
+the middle of receiving a packet), it defers the release until some later point
+in time. Once it is ready to release the resource, it releases it, but then
+immediately requests it again. The flash is then able to do what it wants with
+the Usart, with the radio regaining control soon thereafter.
+
+In the CsmaMacP implementation of the Tda5250 radio we see the ResourceRequested
+event being implemented::
+
+ async event void ResourceRequested.requested() {
+ atomic {
+ /* This gives other devices the chance to get the Resource
+ because RxMode implies a new arbitration round. */
+ if (macState == RX) call Tda5250Control.RxMode()();
+ }
+ }
+
+Through several levels of wiring, the Tda5250 interface is provided to this
+component by the Tda5250RadioP component::
+
+ module Tda5250RadioP {
+ provides interface Tda5250Control;
+ uses interface Resource as UsartResource;
+ ...
+ }
+ implementation {
+ async command error_t Tda5250Control.RxMode() {
+ if(radioBusy() == FALSE)
+ call UsartResource.release();
+ call UsartResource.request();
+ }
+ event void UsartResource.granted() {
+ // Finish setting to RX Mode
+ }
+ ...
+ }
+
+Although the full implementation of these components is not provided, the
+functionality they exhibit should be clear. The CsmaMacP component receives the
+ResourceRequested.requested() event when the flash requests the use of the
+Msp430 Usart0 resource. If it is already in the receive state, it tries to
+reset the receive state through a call to a lower level component. This
+component checks to see if the radio is in the middle of doing anything (i.e.
+the radioBusy() == FALSE check), and if not, releases the resource and then
+requests it again.
+
+To see the full implementations of these components and their wirings to one
+another, please refer to the tinyos-2.x source tree under
+tinyos-2.x/tos/chips/tda5250, tinyos-2.x/tos/chips/tda5250/mac,
+tinyos-2.x/tos/platforms/eyesIFX/chips/tda5250, and
+tinyos-2.x/tos/platforms/eyesIFX/chips/msp430.
+
+Resource Configure
+--------------------------------------------------------------------
+The Msp430 Usart0 bus can operate in three modes: SPI, I2C,
+and UART. Using all three concurrently is problematic: only one should
+be enabled at any given time. However, different clients of the bus might
+require the bus to be configured for different protocols. On Telos, for example
+many of the available sensors use an I2C bus, while the radio and flash chip use
+SPI.
+
+A component providing the SPI service on top of the shared Usart component looks
+like this::
+
+ generic configuration Msp430Spi0C() {
+ provides interface Resource;
+ provides interface SpiByte;
+ provides interface SpiPacket;
+ ...
+ }
+ implementation {
+ enum { CLIENT_ID = unique( MSP430_SPIO_BUS ) };
+
+ components Msp430SpiNoDma0P as SpiP;
+ components new Msp430Usart0C() as UsartC;
+ SpiP.ResourceConfigure[ CLIENT_ID ] <- UsartC.ResourceConfigure;
+ SpiP.UsartResource[ CLIENT_ID ] -> UsartC.Resource;
+ SpiP.UsartInterrupts -> UsartC.HplMsp430UsartInterrupts;
+ ...
+ }
+
+And one providing the I2C service looks like this::
+
+ generic configuration Msp430I2CC() {
+ provides interface Resource;
+ provides interface I2CPacket<TI2CBasicAddr> as I2CBasicAddr;
+ ...
+ }
+ implementation {
+ enum { CLIENT_ID = unique( MSP430_I2CO_BUS ) };
+
+ components Msp430I2C0P as I2CP;
+ components new Msp430Usart0C() as UsartC;
+ I2CP.ResourceConfigure[ CLIENT_ID ] <- UsartC.ResourceConfigure;
+ I2CP.UsartResource[ CLIENT_ID ] -> UsartC.Resource;
+ I2CP.I2CInterrupts -> UsartC.HplMsp430UsartInterrupts;
+ ...
+ }
+
+The implementation of the ResourceConfigure interface is
+provided by both the Msp430SpiNoDma0P and the Msp430I2C0P. In the
+two different components, the same Msp430Usart0C component is used,
+but wired to the proper implementation of the ResourceConfigure
+interface. In this way, different instances of the Msp430Usart0C
+can each have different configurations associated with them, but
+still provide the same functionality.
+
+Take a look in the tinyos-2.x source tree under
+tinyos-2.x/tos/chips/msp430/usart to see the full implementation of
+these components along with the corresponding Uart implementation.