TestRoundRobinArbiter

This Insense program is an example of an access control mechanism where three resource users request access from a central controller, which grants access to each in turn.

/**
 * Resource access control with Insense components
 *
 * This application is used to test the use of Shared Resources.
 * Three Resource users are created and all three request
 * control of the resource before any one of them is granted it.
 * Once the first user is granted control of the resource, it performs
 * some operation on it.  Once this operation has completed, a timer
 * is set to allow this user to have control of it for a specific
 * amount of time.  Once this timer expires, the resource is released
 * and then immediately requested again.  Upon releasing the resource
 * control will be granted to the next user that has requested it in
 * round robin order.  Initial requests are made by the three resource
 * users in the following order.
 * -- Resource 0
 * -- Resource 2
 * -- Resource 1
 * It is expected then that using a round robin policy, control of the
 * resource will be granted in the order of 0,1,2 and the Leds
 * corresponding to each resource will flash whenever this occurs.
 *   -- Led 0 -> Resource 0
 *   -- Led 1 -> Resource 1
 *   -- Led 2 -> Resource 2
 *
 */


type ledType is enum (red, green, blue, other)
/*
 * Resource access component
 */

type controlI is interface(in bool reqChan ; in bool releaseChan ; out bool accessChan)

component control presents controlI {

    constructor() {

    }

    behaviour {
	
		//receive requests from the components
        receive request from reqChan
		
		/*
		* Grant access to a component.
		* Components block until the send is complete, therfore, only the component which completed the send will receive this meesage on the accessChan
		*/
        send true on accessChan

		//Component relinquished control
        receive release from releaseChan
    }
}

/*----------------------------------------------------------------------------*/
type nodeI is interface(out bool request ; in bool access ; in bool timerChan ; out bool release)

component node presents nodeI {

    state = true
    led = other


    constructor(ledType l) {

        led := l

    }

    behaviour {

		//request access, block untill message is received
        send true on request
		
		//access is granted
        receive result from access

		//set duration that we may have the lock
        setTimer(timerChan , 0.25 , true)

        if (led == red) then{
                setRedLedPower(state)
        }

        if (led == green) then{
                setGreenLedPower(state)
        }

        if (led == blue) then{
                setBlueLedPower(state)
        }

        state := !state

        receive timeOut from timerChan
		
		//release the lock
        send true on release
    }
}

/******************************************************************************/
c = new control()
        
/*----------------------------------------------------------------------------*/
r = new node(red)

connect r.request to c.reqChan
connect r.access  to c.accessChan
connect r.release to c.releaseChan
/*----------------------------------------------------------------------------*/
g = new node(green)

connect g.request to c.reqChan
connect g.access  to c.accessChan
connect g.release to c.releaseChan
/*----------------------------------------------------------------------------*/
b = new node(blue)

connect b.request to c.reqChan
connect b.access  to c.accessChan
connect b.release to c.releaseChan

The corresponding nesC program for TinyOS is shown below.


#define TEST_ARBITER_RESOURCE   "Test.Arbiter.Resource"
configuration TestRoundRobinArbiterAppC{
}
implementation {
  components MainC, TestRoundRobinArbiterC as App,LedsC,
  new TimerMilliC() as Timer0,
  new TimerMilliC() as Timer1,
  new TimerMilliC() as Timer2,
  new RoundRobinArbiterC(TEST_ARBITER_RESOURCE) as Arbiter;

     enum {
       RESOURCE0_ID = unique(TEST_ARBITER_RESOURCE),
       RESOURCE1_ID = unique(TEST_ARBITER_RESOURCE),
       RESOURCE2_ID = unique(TEST_ARBITER_RESOURCE),
     };

  App -> MainC.Boot;
  
  App.Resource0 -> Arbiter.Resource[RESOURCE0_ID];
  App.Resource1 -> Arbiter.Resource[RESOURCE1_ID];
  App.Resource2 -> Arbiter.Resource[RESOURCE2_ID];
  App.Timer0 -> Timer0;
  App.Timer1 -> Timer1;
  App.Timer2 -> Timer2;
  
  App.Leds -> LedsC;
}

/****************************************/

#include "Timer.h"

module TestRoundRobinArbiterC {
  uses {
    interface Boot;  
    interface Leds;
    interface Resource as Resource0;
    interface Resource as Resource1;
    interface Resource as Resource2;
    interface Timer as Timer0;
    interface Timer as Timer1;
    interface Timer as Timer2;
  }
}
implementation {

  #define HOLD_PERIOD 250
  
  //All resources try to gain access
  event void Boot.booted() {
    call Resource0.request();
    call Resource2.request();
    call Resource1.request();
  }
  
  //If granted the resource, turn on an LED  
  event void Resource0.granted() {
    call Timer0.startOneShot(HOLD_PERIOD);
    call Leds.led0Toggle();      
  }  
  event void Resource1.granted() {
    call Timer1.startOneShot(HOLD_PERIOD);
    call Leds.led1Toggle();     
  }  
  event void Resource2.granted() {
    call Timer2.startOneShot(HOLD_PERIOD);
    call Leds.led2Toggle();  
  }  
  
  //After the hold period release the resource
  event void Timer0.fired() {
    call Resource0.release();
    call Resource0.request();
  }
  event void Timer1.fired() {
    call Resource1.release();
    call Resource1.request();
  }
  event void Timer2.fired() {
    call Resource2.release();
    call Resource2.request();
  }
}