Real time automation systems require time keeping functions
weAutSys offers all those possibilities. For the aspect of date and time see time keeping.
Timer functions relative to start or now can easily (and under some conditions better) be implemented by counting in the cyclic application threads provided the timing period is a small multiple of the task's or cycle's period.
For all (other) timer purposes weAutSys offers any number of timers. There are three types of system supported timers
All three timer types are quite efficiently and uniformly handled by the runtime. The permanent system load is not dependent on the number of running timers (it is O(1)).
The speciality of the third type (date / time oriented) is that any adjustments or corrections of the system's date & time will (effectively) change the current endTime of running timers of that type by the same amount. Hence, that a timer of that type started with a period aiming at "next week Monday 10:23:11" will lapse at that time even if clock corrections (by NTP, e.g.) or summertime shifts occurred in between.
The other two timer types will strictly adhere to their set period (or frequency).
Conditions and rules described anywhere in this documentation as mandatory are essential for the whole system's health.
Modifying variables described as "do not touch" or "read only", like timing values, timer states, linked list pointers etc., directly by application software almost certainly breaks essential system invariants.
Data Structures | |
struct | timer_t |
The timer data type resp. More... | |
Defines | |
#define | ms_TIMER_TYPE |
A milliseconds based timer. | |
#define | MSEC_DAY 86400000 |
Milliseconds per day. | |
#define | MSEC_HOUR 3600000 |
Milliseconds per hour. | |
#define | MSEC_MINUTE 60000 |
Milliseconds per minute. | |
#define | MSEC_WEEK |
Milliseconds per week. | |
#define | sec_dat_TIMER_TYPE |
A date / time oriented timer with seconds resolution. | |
#define | sec_dur_TIMER_TYPE |
A duration / period oriented timer with seconds resolution. | |
#define | SECONDS_IN_DAY 86400 |
Seconds in a day. | |
#define | SECONDS_IN_WEEK |
Seconds in a week. | |
#define | SECONDS_IN_YEAR |
Seconds in a (normal) year. | |
#define | TIMER_LAPSED 0x00 |
Timer lapsed. | |
#define | TIMER_RUNNING |
Timer running. | |
#define | TIMER_STATE_MASK |
upper 4 bits of timer.state (the state) | |
#define | TIMER_STOPPED |
Timer stopped. | |
#define | TIMER_TYPE_DEFAULT |
Set type to default or leave untouched. | |
#define | TIMER_TYPE_FREE |
Timer free. | |
#define | TIMER_TYPE_MASK |
lower 4 (2) bits of timer.state (the type) | |
#define | TIMER_UNUSED |
Timer unused. | |
#define | timerLapsed(timer) |
Is a timer lapsed. | |
#define | timerRunning(timer) |
Is a timer running. | |
Functions | |
void | freeTimer (struct timer_t *timer) |
Free a timer. | |
void | haltTimer (struct timer_t *timer) |
Halt a timer. | |
uint8_t | initTimer (struct timer_t *timer, uint32_t period, uint8_t type) |
Initialise a timer. | |
uint32_t | msClock (void) __attribute__((always_inline)) |
Milliseconds since power up. | |
void | pauseTimer (struct timer_t *timer) |
Stop / pause a timer. | |
struct timer_t * | removeTimerFromList (const struct timer_t *timer, struct timer_t *list) |
Remove a timer from a list. | |
void | restartTimer (struct timer_t *timer) |
Start a timer with its own interval from now. | |
void | startNextInterval (struct timer_t *timer) |
Start a timer's next interval. | |
void | startTimer (struct timer_t *timer, uint32_t period, uint8_t type) |
Start a timer with interval / type from now. | |
void | startTimerAbs (struct timer_t *timer, uint32_t endTime, uint8_t type) |
Start a timer (with absolute end time) | |
Variables | |
uint16_t | msAbsClockCount |
The system ms clock value for local time. | |
uint16_t | msSystClockCount |
The system ms counter / clock value for running / system up time. | |
struct timer_t | msTimers |
The system milliseconds time and timers. | |
struct timer_t | secDatTimers |
The system seconds resolution date / time oriented timers. | |
struct timer_t | secDurTimers |
The system seconds resolution duration oriented timers. | |
struct timer_t * | timerLists [] |
The list of timer lists. |
#define MSEC_MINUTE 60000 |
Milliseconds per minute.
#define MSEC_HOUR 3600000 |
Milliseconds per hour.
#define MSEC_DAY 86400000 |
Milliseconds per day.
This value can be used as milliseconds timer period for every day repetitive actions like closing or opening windows, shutters or doors.
#define MSEC_WEEK |
Milliseconds per week.
This value can be used as period for milliseconds timers of one week. Often unused aggregates, like pumps, are run for a short time every week to be kept movable.
#define SECONDS_IN_DAY 86400 |
Seconds in a day.
This is the divisor used to split second based absolute time into a) days since base date and b) seconds since midnight.
This value can be used as period for seconds based timers.
#define SECONDS_IN_WEEK |
Seconds in a week.
This value can be used as period for seconds based timers.
Often unused aggregates, like pumps, are run for a short time every week to be kept movable.
#define SECONDS_IN_YEAR |
Seconds in a (normal) year.
This value is the equvalent of 365 days.
#define ms_TIMER_TYPE |
#define sec_dur_TIMER_TYPE |
A duration / period oriented timer with seconds resolution.
This is a timer with seconds resolution that is duration / period oriented. Its endTime relates to secClock.
#define sec_dat_TIMER_TYPE |
A date / time oriented timer with seconds resolution.
This is a timer with seconds resolution that is date / time oriented.
Its endTime relates to secClock. In effect the endtimes of running timers of that type are adjusted by the the same amount if any date and time settings or adjustments should occur.
So, for example, a timer of this type started with SECONDS_IN_WEEK duration an Monday 7:15, will lapse next Monday 7:15 no matter what adjustments (by NTP client e.g.) or even summertime shifts were made during that week. On the other hand big adjustments (like setting date and time to totally different values) may bring a timer of this type far into future or let it lapse at once.
#define TIMER_TYPE_FREE |
Timer free.
This is the type of a timer that is neither used nor owned by any task. If used as type value for (re-) start, this acts as default.
If the user / application software chooses to have a pool of timers (en lieu de one static timer for every purpose) it will have to handle the transitions to / from this state.
#define TIMER_LAPSED 0x00 |
Timer lapsed.
This is the state value of a timer that has run to the end of its (actual) period, i.e. lapsed or expired.
#define TIMER_RUNNING |
Timer running.
This is the state value of a timer that is running and not yet lapsed nor stopped.
#define TIMER_STOPPED |
Timer stopped.
This is the state value of a timer that has been stopped. Its period value will be set to the remaining rest time; it will have to be restored to its original value before a timer restart.
This usually makes no sense for date time oriented timers
#define TIMER_UNUSED |
Timer unused.
This is the state value of a timer that is currently unused but still owned by a application or system task. This owner is responsible for re-using or freeing that timer.
#define timerLapsed | ( | timer | ) |
Is a timer lapsed.
This will evaluate to true if the timer was started and has run to its end.
timer | The timer to be asked (never NULL !) |
#define timerRunning | ( | timer | ) |
Is a timer running.
This will evaluate to true if the timer is still running; i.e. has not yet run to its end.
timer | The timer to be asked (never NULL !) |
uint32_t msClock | ( | void | ) |
Milliseconds since power up.
The value returned is the basis of all weAutSys (relative) timing in milliseconds resolution. It is the 32 bit unsigned number of milliseconds since system start or reset. The value will wrap around after a bit more than 49 days.
A modulo arithmetic compare function (geU32ModAr()) used for timers / time values of that type will give an correct >= answer even over that wrap around provided the the difference is less than half the above range.
Hence timers for about 24,8 days can be made with milliseconds resolution.
Monotony in the sense of modulo 2**32 (or geU32ModAr()) is guaranteed, but there may be gaps (little leaps).
struct timer_t* removeTimerFromList | ( | const struct timer_t * | timer, |
struct timer_t * | list | ||
) | [read] |
Remove a timer from a list.
This function removes the timer
from the list
and then sets timer->next
to NULL. The return value will point to the element that was timer's
predecessor in list
.
If timer
is not found in list
NULL is returned and neither timer
nor list
will be touched.
timer | the timer to be removed from list |
list | the list head, but may be any timer (in a linked list) the search for timer to be removed will start after |
void startTimer | ( | struct timer_t * | timer, |
uint32_t | period, | ||
uint8_t | type | ||
) |
Start a timer with interval / type from now.
If timer is NULL or it is free nothing will happen.
If the period
is set to 0 the state will be set to unused (n.b. not to lapsed) and nothing else will happen.
Otherwise this function will set the timer
with period
ms or s running from now, no matter what its before state has been.
timer | points to the timer to be started |
period | is the next interval duration in s or ms depending on type |
type | may be ms_TIMER_TYPE, sec_dur_TIMER_TYPE or sec_dat_TIMER_TYPE; the upper 6 state bits are ignored |
void restartTimer | ( | struct timer_t * | timer | ) |
Start a timer with its own interval from now.
If timer is NULL or it is free nothing will happen.
If its period
is 0 the state will be set to unused and nothing else will happen.
Otherwise this function will set the timer
with its own period
running from now, no matter what its before state has been.
timer | points to the timer to be (re-) started |
void startTimerAbs | ( | struct timer_t * | timer, |
uint32_t | endTime, | ||
uint8_t | type | ||
) |
Start a timer (with absolute end time)
If timer is NULL or it is free nothing will happen.
If the endTime
set is not in the future the state will be set to unused (n.b. not to lapsed) and nothing else will happen.
Otherwise this function will set the timer
running to the endTime
(of type
).
timer | points to the timer to be started |
endTime | is the next interval's end in s or ms depending on type |
type | may be ms_TIMER_TYPE, sec_dur_TIMER_TYPE or sec_dat_TIMER_TYPE; the upper 6 state bits are ignored |
void startNextInterval | ( | struct timer_t * | timer | ) |
Start a timer's next interval.
If timer is NULL or it is free nothing will happen.
If the period
is 0 nothing will happen, also.
Otherwise this function starts or restarts the timer
with its actually set internal period
from its actual end time.
This actual end time may be in future for a running timer. In this case the timer's next lapse will be postponed farther in the future.
The actual end time may be now or in the past for a lapsed timer. In this case it is a "frequency exact" restart, while startTimer() would be used for an "absolute time exact" restart.
Attention: If the the timers actual end time so far in the past that the prolonged end time is in the past too, the timer will not be re-started. It will be lapsed at once.
If the timer is in state halted/paused or unused it will start with its internal settings from now.
timer | points to the timer to be re-started |
Halt a timer.
If timer is NULL or it is free nothing will happen.
Just stop the timer. This will set the timer to state TIMER_UNUSED
.
timer | points to the timer to be halted |
Initialise a timer.
This will set the timer to state unused and to the given period
and type
non-regarding its current state.
This function should also be called by the owner of a (static!) timer for first time (reset) initialisation. If the user / application software chooses to have a pool of N timers (probably as static timer_t tPool[N]) this function should be called for every element.
If timer
is NULL nothing will be done; if its state is TIMER_RUNNING it will be removed from the system's list of running timers.
timer | points to the timer to be initialised |
period | the duration in s or ms dependinf on type |
type | may be ms_TIMER_TYPE, sec_dur_TIMER_TYPE or sec_dat_TIMER_TYPE; the upper 4 state bits are ignored |
timer
was not free, otherwise, as a signal to user software that chose to handle (a list of) free timers, true (!=0) void pauseTimer | ( | struct timer_t * | timer | ) |
Stop / pause a timer.
If timer is NULL, unused or free nothing will happen.
A bit like haltTimer(struct timer_t)
, but the internal period
will be reduced to the actual run duration not yet elapsed and the state will be TIMER_STOPPED.
timer | pointer to the timer to be freed |
Free a timer.
This function sets a timer in the type TIMER_TYPE_FREE.
If timer
is NULL nothing will be done; if it is running it will be removed from the system's list of running timers.
timer | pointer to the timer to be freed |
uint16_t msSystClockCount |
The system ms counter / clock value for running / system up time.
The value is in the range 0..999 and will be incremented respectively wrapped around modulo 1000 by system software (i.e. in the system 1ms thread). Wrapping means incrementing the secClock() (i.e. secDurTimers.end.v32).
Monotony (in modulo 1000 terms) is guaranteed, but there may be gaps.
This value is not affected by absolute (local) date / time settings or corrections.
Never to be modified elsewhere.
uint16_t msAbsClockCount |
The system ms clock value for local time.
The value is in the range 0..999 and will be incremented respectively wrapped around modulo 1000 by system software (i.e. in the system 1ms thread). Wrapping means incrementing all seconds resolution clock values, like secTime308Loc() etc., but not secClock().
Monotony (in modulo 1000 terms) is guaranteed except for time / date settings corrections.
Never to be modified elsewhere.
The system milliseconds time and timers.
This is (a pseudo timer) for system internal timing and list handling use only!
.next is the root of the system's internal ordered linked list of active / running ms based timers.
.end is the (one) system ms 32 bit counter.
.period is the time zone offset in seconds (0 for WET, 3600 for CET, 7200 for CEST [EU DST rules implied]; -5 for EST .. -8 PST [Northamerican DST rules]).
Application software must not modify any field.
struct timer_t secDatTimers |
The system seconds resolution date / time oriented timers.
This is (a pseudo timer) for system internal timing and list handling use only!
.next is the root of the system's internal ordered linked list of active / running seconds based timers.
secDatTimers.end
is the local time in seconds since March 1st 2008 UTC.
secDatTimers.period
is the (msTimers.end
stamp) value of the absolute date / time last adjustment or setting.
Application software must not modify any field.
struct timer_t secDurTimers |
The system seconds resolution duration oriented timers.
This is (a pseudo timer) for system internal timing and list handling use only!
.next is the root of the system's internal ordered linked list of active / running seconds based timers.
secDurTimers.end
is the (one) system seconds clock counting the seconds since last reset / re-start.
secDurTimers.period
is the system start time in seconds since March 1st 2008 UTC.
Application software must not modify any field.
struct timer_t* timerLists[] |
The list of timer lists.
Index is the type: ms_TIMER_TYPE sec_dat_TIMER_TYPE sec_dur_TIMER_TYPE ([0..2])