-
Notifications
You must be signed in to change notification settings - Fork 243
API Task
- Task()
- Task(unsigned long aInterval, long aIterations, void (aCallback)(), Scheduler aScheduler, bool aEnable, bool (*aOnEnable)(), void (*aOnDisable)())
- Task(unsigned long aInterval, long aIterations, TaskCallback aCallback, Scheduler* aScheduler, bool aEnable, TaskOnEnable aOnEnable, TaskOnDisable aOnDisable)
- Task(void (aCallback)(), Scheduler aScheduler, bool (*aOnEnable)(), void (*aOnDisable)())
- bool isEnabled()
- bool canceled()
- unsigned long getInterval()
- long getIterations()
- long getStartDelay()
- long getOverrun()
- unsigned long getRunCounter()
- bool isFirstIteration()
- bool isLastIteration()
- Task* getPreviousTask()
- Task* getNextTask()
- bool enable()
- bool enableIfNot()
- void delay()
- void forceNextIteration()
- bool enableDelayed()
- bool enableDelayed (unsigned long aDelay)
- bool restart()
- bool restartDelayed (unsigned long aDelay)
- bool disable()
- void cancel()
- void abort()
- void set(unsigned long aInterval, long aIterations, void (*aCallback)(), bool (*aOnEnable)(), void (*aOnDisable)())
- void setSelfDestruct(bool aSelfDestruct=true)
- bool getSelfDestruct()
- void setInterval (unsigned long aInterval)
- void setIterations (long aIterations)
- void setCallback (void (*aCallback)())
- void setOnEnable (bool (*aCallback)())
- void setOnDisable (void (*aCallback)())
- void yield(void (*aCallback)())
- void yieldOnce(void (*aCallback)())
- void setTimeout(unsigned long aTimeout, bool aReset=false)
- void resetTimeout()
- unsigned long getTimeout()
- long untilTimeout()
- bool timedOut()
- bool waitFor(StatusRequest* aStatusRequest, unsigned long aInterval = 0, long aIterations = 1)
- bool waitForDelayed(StatusRequest* aStatusRequest, unsigned long aInterval = 0, long aIterations = 1)
- StatusRequest* getStatusRequest()
- StatusRequest* getInternalStatusRequest()
- void setId(unsigned int aID)
- unsigned int getId()
- void setControlPoint (unsigned int aPoint)
- unsigned int getControlPoint()
Task();
Default constructor.
Takes no parameters and creates a task that needs to be scheduled to run explicitly. There is no callback method defined, and the number of iterations is set to zero by default, so no code execution will take place.
All tasks are created disabled
by default.
Task(unsigned long aInterval, long aIterations, void (*aCallback)(), Scheduler* aScheduler, bool aEnable, bool (*aOnEnable)(), void (*aOnDisable)(), bool aSelfdestruct);
// OR
Task(unsigned long aInterval, long aIterations, TaskCallback aCallback, Scheduler* aScheduler, bool aEnable, TaskOnEnable aOnEnable, TaskOnDisable aOnDisable, bool aSelfdestruct);
Constructor with parameters.
Creates a task that is scheduled to run every <aInterval
> milliseconds, <aIterations
> times, executing <aCallback
> method on every pass.
-
aInterval
is inmilliseconds
(ormicroseconds
) (default = 0 or TASK_IMMEDIATE
) -
aIteration
in number of times,-1 or TASK_FOREVER
for indefinite execution (default = 0
)
Note: Tasks remember the number of iteration set initially, and could be restarted. After the iterations are done, the internal iteration counter is0
. If you need to perform a different set of iterations, you need to set the number of iterations explicitly.
Note: Tasks which performed all their iterations will be disabled during next scheduling run. -
aCallback
is a pointer to a void callback method without parameters (default = NULL
) -
aScheduler
– optional reference to existing scheduler. If supplied (notNULL
) this task will be appended to the task chain of the current scheduler). (default = NULL
) -
aEnable
– optional. Value of true will create task enabled. (default = false
) -
aOnEnable
is a pointer to a bool callback method without parameters, invoked when task isenabled
. IfOnEnable
method returnstrue
, task isenabled
. IfOnEnable
method returnfalse
, task remainsdisabled
(default = NULL
) -
aOnDisable
is a pointer to a void callback method without parameters, invoked when task isdisabled
(default = NULL
)
All tasks are created disabled by default (unlessaEnable = true
). You have to explicitlyenable
the task for execution. - Enables/disables self-destruct on disable event. (
default = false
). Only if compiled with_TASK_SELF_DESTRUCT
option.
NOTE: OnEnable
callback method is called immediately when task is enabled
, which could be well ahead of the scheduled execution time of the task. Please bear that in mind – other tasks, hardware, serial interface may not even be initialized yet. It is always advisable to explicitly enable
tasks with OnEnable
methods after all initialization methods completed (e.g., at the end of setup()
method)
Enabled task is scheduled for execution as soon as the Scheduler's execute()
methods gets control. In order to delay first run of the task, use enableDelayed
or delay method (for enabled tasks) method.
Task(void (*aCallback)(), Scheduler* aScheduler, bool (*aOnEnable)(), void (*aOnDisable)());
If compiled with support for Status Request objects, this constructor creates a Task for activation on event (since such tasks must run waitFor()
method, their interval, iteration and enabled status will be set by that method (to 0
, 1
and false
respectively).
The following 4 “getter” methods return task status (enabled/disabled), cancled flag (in case Task execution was canceled or aborted), execution interval in milliseconds, number of remaining iterations.
bool isEnabled();
bool canceled();
unsigned long getInterval();
long getIterations();
long getStartDelay();
If library is compiled with _TASK_TIMECRITICAL
enabled, you can assess how much later the callback method was invoked against when it was scheduled to be invoked. The return value of getStartDelay()
method provides this information in milliseconds (or microseconds).
long getOverrun();
If library is compiled with _TASK_TIMECRITICAL
enabled, tasks are monitored for “long running” scenario. A “long running” task is a task that does not finish processing its callback methods quickly, and thus creates a situation for itself and other tasks where they don't run on a scheduled interval, but rather “catch up” and are behind. When task scheduler sets the next execution target time, it adds Task's execution interval to the previously scheduled execution time:
next execution time = current execution scheduled time + task execution interval
If next execution time
happens to be already in the past (next execution time < millis()
), then task is considered overrun
. GetOverrun
method returns number of milliseconds between next execution time and current time. If the value is negative, the task has overrun (cut into the) next execution interval by that many milliseconds.
Positive value indicate number of milliseconds (or microseconds) of slack this task has for execution purposes.
unsigned long getRunCounter();
Returns the number of the current run. “Current run” is the number of times a callback method has been invoked since the last time a task was enabled.
NOTE: The runCounter
value is incremented before callback method is invoked. If a task is checking the runCounter
value within its callback method, then the first run value is 1
. If task T1
is checking the runCounter value of another task (T2
) , then value = 0
indicates that T2
has not been invoked yet, and value = 1
indicates that T2
has run once.
bool isFirstIteration();
Indicates whether current pass is (or will be) a first iteration of the task.
bool isLastIteration();
For tasks with a limited number of iterations only, indicates whether current pass is the last iteration.
Task* getPreviousTask();
If compiled with _TASK_EXPOSE_CHAIN
option returns pointer to the Task previous to this one in the scheduler execution chain.
Task* getNextTask();
If compiled with _TASK_EXPOSE_CHAIN
option returns a pointer to the Task next after this one in the scheduler execution chain. This does not mean that the Task will be invoked next however, it only means that it will be evaluated for invocation next by the scheduler.
bool enable();
Enables the task, and schedules it for immediate execution (without delay
) at this or next scheduling pass depending on when the task was enabled. Scheduler will execute the next pass without any delay
because there is a task that was enabled and requires execution.
Returns: true if task was enabled, and false otherwise
NOTE: if task being enabled is not assigned to a scheduler and is not part of execution chain, then task will not be enabled.
NOTE: enable()
invokes task’s OnEnable
method (if not NULL
) immediately, which can prepare task for execution. OnEnable
must return a value of true
for task to be enabled. If OnEnable
returns false
, task remains disabled
. OnEnable
is invoked every time enable
is called, regardless if task is already enabled or not. Alignment to current millis()
is performed after OnEnable
exits, so any changes to the interval inside OnEnable
is taken into consideration.
TaskScheduler
allows tasks to be added to a Scheduler and enabled at the time of creation. Be very careful with such tasks – the OnEnable
method will be executed immediately, while certain objects (i.e., other Tasks, libraries) are not yet ready (e.g., Wire.begin()
was not yet called), or hardware not yet activated (pins not set to INPUT
or OUTPUT
).
It is very much recommended to enable all tasks at the end of setup()
method after all initializations are done.
If you require immediate execution of the already enabled task, use forceNextIteration()
method instead of enable()
: it achieves the result, but does not call OnEnable
method.
NOTE: in the event enable()
method is called inside the OnEnable
callback method (thus basically creating an infinite loop), TaskScheduler
will only call OnEnable
once (thus protecting the Task against OnEnable
infinite loop).
NOTE: internal StatusRequest
object will be set waiting for an event when Task is enabled (if TaskScheduler
is compiled with support for StatusRequests
). StatusRequest
object is set waiting after the call to onEnable()
method of the Task (if defined). Consequently, any Task#2
that is expected to wait on this Task’s internal StatusRequest
should do it only after this task is enabled.
bool enableIfNot();
Enables the task only if it was previously disabled.
Returns previous enable state: true
if task was already enabled, and false
if task was disabled.
Since enable()
schedules Task for execution immediately, this method provides a way to activate tasks and schedule them for immediate execution only if they are not active already.
All NOTES from the enable()
method apply.
void delay();
Schedules the task for execution after a delay (aInterval), but does not change the enabled/disabled status of the task.
NOTE: a delay of 0 (zero) will delay task for current execution interval. Use **forceNextIteration()**
method to force execution of the task’s callback during immediate next scheduling pass.
void forceNextIteration();
Schedules the task for execution during immediate next scheduling pass.
The Task must be already enabled prior to this method.
Note: Task’s schedule is adjusted to run from this moment in time. For instance: if a task was running every 10 seconds: 10, 20, 30, .., calling forceNextIteration
at 44th second of task execution will make subsequent schedule look like: 44, 54, 64, 74,...
bool enableDelayed();
Enables the task, and schedules it for execution after task's current scheduling interval (aInterval
).
Returns: true if task was enabled, and false otherwise
bool enableDelayed (unsigned long aDelay);
Enables the task, and schedules it for execution after a specific delay (aDelay
, which may be different from aInterval
).
Returns: true if task was enabled, and false otherwise
bool restart();
For tasks with limited number of iterations only, restart
method will re-enable the task, set the number of iterations back to last set value, and schedule task for execution as soon as possible.
Returns: true if task was enabled, and false otherwise
bool restartDelayed (unsigned long aDelay);
Same as restart()
method, with the only difference being that Task is scheduled to run first iteration after a delay = aDelay
milliseconds (or microseconds).
Returns: true if task was enabled, and false otherwise
bool disable();
Disables the task. Scheduler will not execute this task any longer, even if it remains in the chain. Task can be later re-enabled for execution.
Return previous enabled state: true
if task was enabled prior to calling disable, and false
otherwise.
If not NULL
, task’s OnDisable
method is invoked immediately. OnDisable
is invoked only if task was in enabled state. Calling disable 3 times for instance will invoke OnDisable
only once.
NOTE: internal StatusRequest
object will signal completion of an event when Task is disabled (if TaskScheduler
is compiled with support for StatusRequests
). StatusRequest
object is set complete after the call to onDisable()
method of the Task (if defined). Consequently, the task which has to signal its completion to other Tasks could not restart itself. Do so will not ever set the internal StatusRequest
object to a complete status, since the Task is never really disabled.
void cancel();
Disables the task and sets canceled
flag. Similarly to disable()
method cancel()
will call OnDisable()
method (if provided), where the canceled
flag could be examined and appropriate action taken.
void abort();
Similar to the cancel()
- aborts task execution, however without calling OnDisable()
method. The Task is just not scheduled for execution anymore. StatusRequest objects are not triggered.
void set(unsigned long aInterval, long aIterations, void (*aCallback)() , bool (*aOnEnable)() , void (*aOnDisable)());
Allows dynamic control of task execution parameters in one method call.
NOTE: OnEnable
and OnDisable
parameters can be omitted. In that case they will be assigned to NULL and respective methods will no longer be called. Therefore it is advisable to use either all five parameters explicitly, or employ individual “setter” methods below instead.
void void setSelfDestruct(bool aSelfDestruct=true);
If compiled with _TASK_SELF_DESTRUCT
option, requests Task to be deleted after disable()
method is invoked (if aSelfDestruct == true) or not to be deleted (if aSelfDestruct == false)
void bool getSelfDestruct();
If compiled with _TASK_SELF_DESTRUCT
option, returns current state of the self-destruct request (true: self-destruct on disable()
, false: keep task after disable()
)
NOTE Default behavior is not to delete task after disable()
is invoked.
Next five “setter” methods allow changes of individual task execution control parameters.
void setInterval (unsigned long aInterval);
void setIterations (long aIterations);
void setCallback (void (*aCallback)());
void setOnEnable (bool (*aCallback)());
void setOnDisable (void (*aCallback)());
NOTE: Next execution time calculation takes place after the callback method is called, so new interval will be used immediately by the scheduler. For the situations when one task is changing the interval parameter for the other, setInterval
method calls delay
explicitly to guarantee schedule change, however it does not enable the task if task is disabled.
NOTE: Tasks that ran through all their allocated iterations are disabled. SetIterations()
method DOES NOT enable the task. Either enable
explicitly, or use restart
methods.
Please note that as a result execution of the tasks is delayed by the provided interval. If immediate invocation is required, call forceNextIteration()
method after setting a new interval.
void yield(void (*aCallback)());
This method could be used to break up long callback methods. A long callback method should be broken up into several shorter methods. Yield
method just gives control back to scheduler, while ensuring that next iteration of the Task is executed immediately with the next callback method. Basically yield(&callBack2)
is equivalent to setting new callback method, and forcing next iteration to be immediate. Please note that original interval and number of iterations are preserved. Even the runcounter
of the callback2
after yielding will remain the same. Typically a call to yield()
method is the last line of the method yielding.
void yieldOnce(void (*aCallback)());
This method is equivalent to yield()
, only execution of the target aСallback
method is set to happen only once, after which the Task will be disabled.
NOTE ON TIMEOUT: Timeout conditions are evaluated first. Which means that a task that is ready to be disabled due to last iteration and a timeout, will be disabled with a timeout flag set. This is by design. To make timeout a secondary choice, you need to use a separate “timeout” task and place it after this task in the execution chain.
Once set, a timeout value remains with the task, i.e., when a disabled task is restarted or reenabled, the timeout will restart as well. To disable timeout, use setTimeout(TASK_NOTIMEOUT);
method call.
void setTimeout(unsigned long aTimeout, bool aReset=false)
Sets the task’s timeout to the aTimeout
milliseconds (microseconds) value.
Setting timeout to TASK_NOTIMEOUT
value will disable the timeout. If aReset
is false or not supplied, the timeout counter is not activated for the task If aReset
is true, the current value of millis()
[or micros()
] is set as a starting point in time.
NOTE: Tasks’ timeout starting points are reset automatically by enable(), enableDelayed(), enableIfNot(), restart() and restartDelayed()
methods.
void resetTimeout();
Resets Task’s timeout start value to current time. Effectively the timeout countdown restarts
from the beginning.
NOTE: enable(), enableDelayed(), enableIfNot(), restart() and restartDelayed()
methods call resetTimeout()
explicitly. There is no need to reset timeouts for the tasks that have been just enabled or restarted.
unsigned long getTimeout();
Returns Task’s initial timeout value.
A value of TASK_NOTIMEOUT
(0) indicates that this task has not timeout set.
long untilTimeout();
Returns amount of time remaining until this task will time out.
NOTE: Take care using this method: it returns a **signed **integer, with a negative value meaning
the task has already or is about to timeout:
-1
= the task has already timed outstanding
value < -1
= the task is still active but will time out at next iteration.
bool timedOut();
Returns true
if the task was disabled due to a timeout.
Returns false
if a timeout has not occurred (either not yet, or the task deactivated under normal conditions – ran out of iterations).
NOTE: Best place to use this method is in the OnDisable
method of a task to determine how termination has occurred. Please see example 17 for details.
bool waitFor(StatusRequest* aStatusRequest, unsigned long aInterval = 0, long aIterations = 1);
bool waitForDelayed(StatusRequest* aStatusRequest, unsigned long aInterval = 0, long aIterations = 1);
If compiled with support for Status Requests, these methods make task wait for the completion of aStatusRequest
event. By default waitFor()
sets tasks interval to 0
(zero) for immediate execution when event happens, and also sets the number of iterations to 1
. However, you can specify different interval and number of iterations.
By default waitForDelayed()
sets tasks interval to a supplied value or (if omitted or zero) keeps the current interval, so delayed execution will take place when the event happens. It also sets the number of iterations to 1
by default if not supplied.
When Status Request object completes, all tasks waiting on it are executed during next scheduling pass. Tasks waiting via waitFor()
method are executed immediately. Tasks waiting via waitForDelayed()
method are activated, but executed after current or supplied interval delay.
NOTE: aStatusRequest
should be “activated” by calling setWaiting()
method before making a task wait on it. Otherwise, the task will execute immediately.
The sequence of events to use Status Request object is as follows:
- Create a status request object
- Activate status request object (calling its
setWaiting()
method) - Set up tasks to wait of the event completion
- Signal completion of event(s)
Returns: true if task was enabled, false otherwise.
StatusRequest* getStatusRequest();
Returns a pointer to StatusReqeust
object this Task was waiting on.
StatusRequest* getInternalStatusRequest();
Returns a pointer to an internal StatusReqeust
object associated with this Task. Internal StatusRequest
object is:
- Always waits on 1 event – completion of this task
- Is activated (set to “waiting” status) after Task is enabled
- Is completed after Task is disabled (either explicitly, or by running out of iterations)
NOTE: Please remember that a task is deactivated at the next scheduling pass after the last iteration, which means that other Tasks in the chain will have a chance to run before Task StatusRequest
signaling completion of the internal StatusRequest
. However, there is no further delay – deactivation will take place at the next scheduling pass.
void setId(unsigned int aID);
If compiled with support for Task IDs, this method will set the task ID explicitly. Calling this method is not necessary as task IDs are assigned automatically during task creation: 1, 2, 3,…
unsigned int getId();
If compiled with support for Task IDs
, this method return current task’s ID.
void setControlPoint (unsigned int aPoint);
If compiled with support for Task IDs
, this method will set a control point in the task’s code.
Control points are similar to “try…catch” blocks, with control point ID specifying where in the code the “try” part started, and a mechanism like watchdog timer providing the “catch” functionality.
unsigned int getControlPoint();
If compiled with support for Task IDs
, this method will return currently set control point for this task.
void setLtsPointer(void *aPtr);
If compiled with support for LTS, this method will set the task's local storage pointer.
void *getLtsPointer();
If compiled with support for LTS, this method will return reference to the task's local storage.
NOTE: the value returned has type (void *
), and needs to be re-cast into appropriate pointer type. Please refer to example sketches for implementation options.