Resource Reservations

Reservations are an enforcement mechanism that allow the OS to monitor resource
usage and deny tasks access to a resource if they overdraw their budget. For example if
sending an ultrasonic pulse is expensive, a task may have an upper limit of five allowed
transmits over a period of five seconds. This parameter is set at build time and enforces
an average energy usage of that device. By setting reservations for all significant energy
consuming devices one can implement a system-wide virtual energy reservations.
CPU reservations are created statically by populating the corresponding task’s TCB
structure with reservation information. When the CPU time for a task exceeds the reservation size
the application is immediately suspended and its reservation is replenished during the next period. We allow an application to query the status and usage of its own reservation so that it
can adapt its behavior accordingly. Reservations are strongly recommended for
power-sensitive applications.

Network and peripheral reservations are handled in a similar manner. Network
reservations keep track of the number of bytes and packets transmitted by a particular
task and the node as a whole. The sensors and actuator reservations count how many
times a particular resource is used over the reservation period and then weights that by
a factor that accounts for variable energy consumption between devices. Virtual energy
reservations can be implemented by judiciously choosing values of (CPU, Network,
Peripheral) reservation values. These reserves are used primarily for energy encapsulation.
This means that one task in your system could potentially
deprive other tasks of a resource, but will not be allowed to deplete overall node lifetime.

NRK_MAX_RESERVES is defined in nrk_cfg.h and defines how many counting reserves are available
to all running tasks. This defines the pool used when calling nrk_reserve_create().
CPU reserves are built into each task's TCB and do not need to be included
in this number. Counting reserves can provide reservation support for application code or custom
drivers. For more information on using counting reserves see the basic_reserves project.

[[TaskOne]].task = Task1;
[[TaskOne]].Ptos = (void *) &Stack1[NRK_APP_STACKSIZE-1];
[[TaskOne]].Pbos = (void *) &Stack1r0;
[[TaskOne]].prio = 2;
[[TaskOne]].FirstActivation = TRUE;
[[TaskOne]].Type = BASIC_TASK;
[[TaskOne]].SchType = PREEMPTIVE;
[[TaskOne]].period.secs = 1;
[[TaskOne]].period.nano_secs = 0;
[[TaskOne]].cpu_reserve.secs = 0;
[[TaskOne]].cpu_reserve.nano_secs = 100*NANOS_PER_MS;
[[TaskOne]].offset.secs = 0;
[[TaskOne]].offset.nano_secs= 0;
nrk_activate_task (&TaskOne);

Sample of the CPU reserve being configured when a task is created. Setting a task's reserve to 0 time disables the
reserve on that task.

int8_t nrk_check_cpu_reserve(nrk_time_t *reserve)

This function returns the time remaining for a particular task’s CPU reserve. NRK_OK is returned upon success and NRK_ERROR upon failure.

int8_t nrk_reserve_create()

This function returns the ID of a free counting resource up to NRK_MAX_RESERVES reservations. Upon error this function returns NRK_ERROR.

int8_t nrk_reserve_delete(uint8_t reserve_id)

This function frees an already created resource. reserve_id is the reservation handler returned by nrk_reserce_create(). NRK_OK is returned on success and NRK_ERROR is returned upon error.

int8_t nrk_reserve_set(uint8_t reserve_id, nrk_time_t *period,int16_t access_count,void *errhandler)

This function sets the number of counts, the period and the error handler function for the reserve reserve_id. period is the time before the reserve is replenished. access_count is the number of consume calls that can be made during this period. errhandler is a function pointer for an error handling task that gets called if the reserve fails. Any computation time used by the error handling task is taken from the task calling nrk_reserve_consume(). If not error callback function is required set errhandler to NULL. NRK_OK is returned upon success and NRK_ERROR is returned upon failure.

uint8_t nrk_reserve_get(uint8_t reserve_id)

This function returns the number of counts for reserve reserve_id left during the current period. If the reserve is empty, 0 is returned.

int8_t nrk_reserve_consume(uint8_t reserve_id)

This function should be used to allow access to resources that have a reserve associated with them. reserve_id denotes the reserve that is being accessed. If the reserve still has counts remaining, NRK_OK is returned and a single resource unit is consumed. If the resource is depleted, NRK_ERROR is called and the error handle callback function is called.

Prev: LEDs and GPIO Next: Power Control Top