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();
}
}