Executive library for Arduino
Public Member Functions | Public Attributes | List of all members
Executive Class Reference

#include <Executive.h>

Public Member Functions

 Executive (int maxTasks=DEFAULT_MAX_TASKS)
 
 ~Executive ()
 
int addTask (unsigned long interval_ms, void(*doTask)(void), unsigned long timeToNext_ms=0)
 
int addOneShotTask (void(*doTask)(void), unsigned long timeToNext_ms=0)
 
int enableTask (int taskNo)
 
int disableTask (int taskNo)
 
int modifyTaskInterval (int taskNo, unsigned long interval_ms)
 
int modifyTaskNextRun (int taskNo, unsigned long timeToNext_ms)
 
int removeTask (int taskNo)
 
void yield (void)
 
void delay (unsigned long delay_ms)
 
void loop (void)
 

Public Attributes

const unsigned long DELAY_FOREVER = -1L
 

Constructor & Destructor Documentation

◆ Executive()

Executive::Executive ( int  maxTasks = DEFAULT_MAX_TASKS)

Construct the Exec object with a specified size of task table

Parameters
maxTasksThe maximum number of tasks (enabled+disabled) in the task list.

◆ ~Executive()

Executive::~Executive ( )

Default destructor

Member Function Documentation

◆ addOneShotTask()

int Executive::addOneShotTask ( void(*)(void)  doTask,
unsigned long  timeToNext_ms = 0 
)

Add a new task to be performed just once

Parameters
timeToNext_msNumber of ms until first run of the task to do.
doTaskThe routine called to do the task
Returns
An index to the task or -1 if task could not be added (no room left in task table)

◆ addTask()

int Executive::addTask ( unsigned long  interval_ms,
void(*)(void)  doTask,
unsigned long  timeToNext_ms = 0 
)

Add a new task to be performed at a regular interval

Parameters
timeToNext_msNumber of ms until first run of the task to do. Must be less than interval_ms otherwise taken as interval_ms
interval_msInterval between successive runs of the task
doTaskThe routine called to do the task
Returns
An index to the task or -1 if task could not be added (no room left in task table)

◆ delay()

void Executive::delay ( unsigned long  delay_ms)

Run tasks in the schedule that need to be run in the next delay_ms milliseconds. Return after at least delay_ms. I.e. the function will call the standard delay() function to use up any 'spare' time after any relevant tasks have been run.

Tasks are not run in parallel, so if a task become due to be run during the execution of another task it will have to wait until the current task completes before it can be started.

When considering which task to run, the task with the earliest desired start time will always take priority. Where two tasks have the same desired start time, the one earliest in the list will take precedence. You should aim to place the tasks with shortest intervals near the top of the list as they stand the best chance of running to their desired interval.

Immediately before running a task, the time at it is started is recorded. The desired time of the next execution will be based on the actual time at which the task is started and the task interval. There is no account taken of whether the task was late in starting. This effectively means that the task interval is a minimum setting for the amount of time between successive calls to the task function. In the best case, where the delay() function has control for most of the time and other scheduled functions don't interfere, the interval time will be honoured and the task will operate at the requested interval. If the sketch spends a lot of its time outside the delay() function or if there are other tasks that individually or in combination might take longer then the interval, then Executive won't be able to keep to the schedule and will work on a 'best endeavours' basis.

One-shot tasks are treated equally to the interval tasks, except that they are removed from the table immediately before this scheduler runs their doTask() function.

If a task is started and runs beyond the delay_ms window then this Executive::delay() function will itself return as soon as that task completes. In this case no further tasks will be started (even if they were due to run in that delay_ms window).

If, when delay() is called, there is a backlog of tasks that are due to be run, then the tasks get run in the order of their desired run time. Again, if the end of the delay_ms is reached, then the delay() function will return as soon as the current task finishes, even if there are other back-logged or due to run tasks. This behaviour does ensure that if there is a backlog of tasks then at least one of these will get run for any call to delay().

If there are no tasks due to run in the requested delay_ms window then the Executive:delay() function just behaves like a standard delay() function.

Parameters
delay_msThe minimum amount of time to remain in this scheduling function. Return after this time has passed and a soon as any currently executing task returns. If the special value DELAY_FOREVER is used then the control is passed entirely to Executive and is never returned back to the calling sketch.
See also
Executive::loop()

◆ disableTask()

int Executive::disableTask ( int  taskNo)

Disable the specified task from being scheduled (run)

Task can be one-shot or continuous but must have been set up previously. If the task is one-shot then it must be disabled before it first runs or this routine will return -1. One-shot tasks are deleted from the table immediately before they are run.

Parameters
taskNoNumber of the task that is to be disabled. The task number is returned from addTask() and addOnShotTask().
Returns
The task no or -1 if the taskNo was not a valid task

◆ enableTask()

int Executive::enableTask ( int  taskNo)

Enable the specified task and make eligible to run immediately

Task can be one-shot or continuous but must have been set up previously.

Parameters
taskNoNumber of the task that is to be enabled. The task number is returned from addTask() and addOnShotTask().
Returns
The task no or -1 if the taskNo was not a valid task

◆ loop()

void Executive::loop ( void  )

Hand over control to the Executive. Run tasks to the schedule but never return.

◆ modifyTaskInterval()

int Executive::modifyTaskInterval ( int  taskNo,
unsigned long  interval_ms 
)

Modify the interval at which a task runs or the time until a one-shot is executed

For continuously running tasks, only the interval is changed, so if it is shortened, the task may immediately become eligible to run (during the next yield() or delay()).

For one-shot tasks, the 'timer' is reset so it will become eligible after the new interval_ms period.

Parameters
taskNo
interval_ms
Returns
The task no or -1 if the taskNo was not a valid task

◆ modifyTaskNextRun()

int Executive::modifyTaskNextRun ( int  taskNo,
unsigned long  timeToNext_ms 
)

Change the time at which the task will next run

Note that for one-shot tasks, this behaves the same as modifyTaskInterval() and the internal 'timer' is effectively reset.

For continuously running tasks, the timeToNext_ms should be less than or equal to the interval_ms for the task. If greater, then interval_ms is used.

Parameters
taskNo
timeToNext_ms
Returns
The task no or -1 if the taskNo was not a valid task

◆ removeTask()

int Executive::removeTask ( int  taskNo)

Immediately removes a task from the task schedule

Note that this doesn't stop a running task, it will just prevent the task from being run again.

After removing a task, its taskNo is not longer valid and should be discarded as the taskNo may get re-used on a subsequent call to addTask().

Parameters
taskNo
Returns
The task no of the removed task (which is no longer useful) or -1 if the taskNo was not a valid task.

◆ yield()

void Executive::yield ( void  )

Run the task that is most overdue to run.

Only the most overdue task is run. If there are no overdue tasks this routine returns after a short delay (MIN_YIELD_TIME_MS).

Member Data Documentation

◆ DELAY_FOREVER

const unsigned long Executive::DELAY_FOREVER = -1L

Use in a call to Exec.delay() this will cause an infinite delay.


The documentation for this class was generated from the following files: