# Alarm (Overview)

## Introduction

An alarm uses one of the four hardware timers to generate an interrupt at a time specified by the application. The reference unit for time is the `tick` used by the tick system, so that system must be operating for alarms to work properly. Since the tick system also uses a hardware timer, there are two hardware timers remaining and available to the user.

### Initialization

To use the alarm system, begin by making sure that the tick system is initialized. If it has not been, do so by calling `OS_InitTick()`. Once you're certain that the tick system is initialized and operating, initialize the alarm system by calling `OS_InitAlarm()`.

To determine whether or not an alarm is available, call `OS_IsAlarmAvailable()`.

To free the hardware timer that was allocated to the alarm system and quit the alarm system, call `OS_EndAlarm()`.

### Setting Alarms

To set an alarm, first prepare an `OSAlarm` structure object. One alarm can be set for each prepared structure object. Initialize the object using `OS_CreateAlarm()`.

Now use the `OS_SetAlarm()` function to specify when the alarm is to be triggered (when to call the specified handler). The function specifies how many ticks should elapse after being called before tripping the alarm.

To call the alarm handler on a set cycle, use `OS_SetPeriodicAlarm()` to set the period.

If an alarm cannot generate an interrupt at its specified time because of another interrupt process or because the alarm handler is already active, the alarm handler will be called as soon as it becomes possible. If there are a number of alarms in this state, they will all be called in turn and none will escape from the alarm system's handler.

We recommend that your processes generally end the interrupt handler quickly.

### Canceling Alarms

To cancel a single alarm, call `OS_CancelAlarm()`. This function cancels one specified alarm.

To cancel all alarms, call `OS_CancelAllAlarm()`.

Another method (described below) uses tag values to cancel groups of alarms.

### About Alarm Tags

Alarms can be assigned tag values of 1 to 255. These tag values can be used to cancel all alarms with a given tag.

Tag values are set to existing alarms using `OS_SetAlarmTag()`.

To cancel all alarms with a given tag value, use `OS_CancelAlarms()`. (Note that the function name is plural.)

### Internal Data Structure

The OSAlarm alarm structures are inter-connected in a list according to the temporal order of the alarms.

If a given alarm structure is still connected to the list, that means its alarm has not yet gone off. Do not use this structure to set another alarm, because that will corrupt the list. If a list corruption is detected, `OS_Panic` will stop the library, regardless of the build.

Using `OS_CreateAlarm()` to initialize an alarm structure that is still connected to the list is also prohibited, since this can corrupt the list structure and cause unstable behavior.

### Handling Multiple Alarms

Even though the alarm system only uses one timer, the application can set multiple alarms at the simultaneously. This works because the alarm system maintains an internal list of alarms, arranged in order starting with the alarm that is set to go off the soonest. The alarm system follows this list to conduct the alarm process, using the hardware timer on only one alarm at a time. Once the process for one alarm ends, the system repeats the process on the next alarm in the list. In this way, it appears as if multiple alarms have been set at the same time.

In the example below, four alarms have been set. The current time (the present tick value) is 70, and the alarm that is set to go off the soonest is `Alarm1`. The alarm system is set to generate a timer interrupt for `Alarm1` after another 30 ticks elapse.

When the time reaches 100, the timer interrupt for `Alarm1` is triggered and the alarm handler is called.

When this process ends the next alarm is set. The alarm process for `Alarm1` ends at tick 105, and the list says `Alarm2` should go off at tick 150, so the alarm system is set to generate a timer interrupt for `Alarm2` after another 45 ticks elapse.

The process is repeated for the other alarms in the list in turn.

### Canceling and Resetting Alarms Inside the Alarm Handler

Below are explanations of the circumstances surrounding the process of alarms canceling and resetting themselves inside the alarm handler.

1. A one-time alarm cancels its own alarm in alarm handler
   Since an alarm is generated at the time the alarm handler is called, there is no need for self-canceling and this action has no meaning.
2. A one-time alarm uses own alarm to rest itself in alarm handler
   The alarm structure `OSAlarm` for that alarm has already been removed from the list, so the alarm can be reset. Cancellation is not necessary.
3. A periodic alarm cancels its own alarm in alarm handler
   It does not matter if this is done or not.
4. A periodic alarm uses own alarm to reset itself in alarm handler
   As long as the alarm has been cancelled, there are no restrictions on using that alarm object to set a new alarm.

### Use of Hardware Timers

The timer that used by the alarm system cannot be used by the application. The OS timer functions are checked at the time of the DEBUG build by `SDK_ASSERT`.

The timer being used is defined by `OSi_ALARM_TIMER` in `NitroSDK/build/libraries/common/src/os_alarm.c`. The default is `timer 1`.

## See Also

List of OS Functions (Alarm)

## Revision History

11/05/2004 Initial version