# Timer functions
[Cooperative scheduler]

The kernel contains a simple timer subsystem. More...

## Functions
int | BZ_TimerCancel (BZ_TIME *timer)
| Cancels a timer.
int | BZ_TimerStart (BZ_TIME *timer, unsigned initial, unsigned repeat, int pid, int event)
| Start a timer.
void | BZ_TimerTick (unsigned us)
| Timer tick function.
unsigned long long | BZ_TimerUptime (void)
| Return the uptime of the system.

## Detailed Description

The kernel contains a simple timer subsystem.

You do not have to use the subsystem. It is possible to set up an interrupt routine on a hardware timer and send a broadcast signel to every thread from the interrupt routine. Counting the number of signals you receive you can implement as many timers as you wish. That is a sensible approach if you have a system that is full of state machines and many timers. If you want, however, a more sophisticated approach, you can use the timer subsystem of the kernel. It is still based on signals, but instead of getting a single, regular event, you can set up independent timers, each of which delivers a different event.

To keep track of the passage of time, you have to call the BZ_TimerTick() function regularly and tell it how many microseconds have passed since its last call. Timers are represented by BZ_TIME structures that reside in your memory. You can start a timer by calling the BZ_TimerStart() function. When the timer expires it will deliver an event to a thread, both the thread and the event being specified by the BZ_TimerStart() function call. You can also cancel a running timer, have periodic timers and you can get the uptime of the system by further functions.

## Function Documentation

int BZ_TimerCancel | ( | BZ_TIME * | timer | ) |

Cancels a timer.

The function checks the active timer queue and removes the timer from it. If the timer is not found on the queue, then this function does nothing.

Parameters:

  | timer | The timer to remove

Return values:

  | 1 | The timer was removed from the queue
  | 0 | The timer was not found on the queue

int BZ_TimerStart | ( | BZ_TIME * | timer,
|  | unsigned | initial,
|  | unsigned | repeat,
|  | int | pid,
|  | int | event |
| ) |  |  |

Start a timer.

The timer is represented by a BZ_TIME structure, which you have to allocate. You can allocate it on the stack, as long as you guarantee that it does not go out of scope before it expires.

The timer will be started with an initial period defined by the first argument. If the second argument is not 0, then when the timer expires, it will be restarted by the period defined by the second argument. That way you can create a periodic source of events.

When a timer expires, it delivers an event specified by the fourth argument to the process defined by the third argument. It can be BZ_??? if you want the event delivered to all processes. Only one event is delivered, if you specify more than one bit in the event map, only the lowest numbered bit of that mask will be delivered. The event mask can not be empty.

Starting a timer that is already running might lead to system crash. If you want to re-use a timer structure, you must be sure that it is not in use.

Parameters:

  | timer | Pointer to a BZ_TIME structure, representing the timer
  | initial | The initial period of the timer, in microseconds.
  | repeat | The subsequent period of the timer, in microseconds. If this parameter is 0, then when the timer expires after the initial period, it stops. If this argument is not 0, then the timer will be restarted, using the time specified by this argument. Thus you get a periodic timer, which will stop only when you call BZ_TimerCancel() on it.
  | pid | The timer when expires delivers an event. This argument specifies the process to which the event will be delivered.
  | event | The event mask to be delivered. It must not be 0. It should not contain bits reserved for the system; if it does, then those bits will be deleted from the mask. Furthermore, it should have only one bit set. If there are more than one bits set in the mask, then only the lowest numbered bit will be delivered when the timer expires.

Return values:

  | @retval | 0 Success

void BZ_TimerTick | ( | unsigned | us | ) |

Timer tick function.

If you use timers, then calling this function informs the timer subsystem that a certain amount of time has elapsed. Please read the explanation Resolution and time units for the BX_TimerTick() function in the pre-emptive kernel, as the behaviour of this function is identical to that one, except for the details on the scheduling aspects of expired timers.

Parameters:

  | us | The time elapsed since the last call, in microsecs.

Attention:
  This call must either be called from an interrupt service routine or with interrupts disabled.

unsigned long long BZ_TimerUptime | ( | void |  | ) |

Return the uptime of the system.

The function returns the uptime of the system in microseconds. It relies on the calls to BZ_TimerTick(), basically summing the arguments of those calls.

Returns:
  The uptime. It is returned as an `unsigned long long` but it is actually two `unsigned int`s, one being the number of seconds and the other the microseconds. It is guaranteed that the microsecond count is never larger than 999999. The upper 32-bits of the word represent the seconds and the lower 32 are the microseconds. That is:

                      unsigned long long  temp;
                      unsigned int        sec, usec;

                          temp = BZ_TimerUptime();
                          usec = temp;
                          sec  = temp >> 32;