rtc(7)
NAME
rtc − real-time clock device
DESCRIPTION
The rtc is a real-time clock device that can be used for almost any timing/frequency control function. It provides several different resolutions (e.g., 1 microsecond resolution), which, when combined with a clock count value, provide many different timing intervals. This makes it ideal for running processes at a given frequency (e.g., 100Hz) or timing code segments.
Configuration
On Series 4000 HN4800 systems, the real-time clock controller is integral to the system and is always provided. Five real-time clocks are available.
On Series 4000 HN4400 systems, the real-time clocks are integral to the CPU boards; CPUs 0 and 1 each support two real-time clocks, thus providing a maximum of four rtcs per system.
On Series 5000 HN5800 systems, the real-time clocks are integral to the CPU boards. Both CPUs on a board may be interrupted by the clocks on that board. Five real-time clocks are available on the first board. On muliple CPU board systems, each of the (possible) next three CPU boards have three real-time clocks. This provides a maximum of 13 real-time clocks per system.
Disk Names, Special Files, Minor Device Numbers
The rtc special file names have the form /dev/rrtc/∗c#. The character ∗ is the controller number. The controller number is always 0 on Series 4000 systems. On Series 5000 systems it may be 0, 1, 2, or 3 and corresponds to the CPU board on which the clock resides. The character "#" is the minor number and refers to a given rtc. This is 0-3 on Model 4400 systems and 0-4 on Model 4800 systems. On Series 5000 systems it is 0-4 on the first board, and 0-2 on subsequent boards.
Interrupt Levels
Each rtc is associated with an interrupt level. Devices with higher interrupt levels will be serviced before devices of lower interrupt levels.
On Series 4000 systems each rtc’s interrupt level is fixed. This interrupt level ordering, from highest to lowest, is as follows: /dev/rrtc/0c0, /dev/rrtc/0c2, /dev/rrtc/0c1, /dev/rrtc/0c3, and on Model 4800 systems, /dev/rrtc/0c4.
On Series 5000 systems each rtc’s interrupt level is fixed. Note that a rtc may only interrupt a CPU on the same CPU board. The interrupt level ordering, from highest to lowest on the first CPU board is as follows: /dev/rrtc/0c0, /dev/rrtc/0c2, /dev/rrtc/0c1, /dev/rrtc/0c3, /dev/rrtc/0c4. The interrupt level ordering on the second CPU board is: /dev/rrtc/1c0, /dev/rrtc/1c2, /dev/rrtc/1c1. The interrupt level ordering on the third CPU board is: /dev/rrtc/2c0, /dev/rrtc/2c2, /dev/rrtc/2c1. The interrupt level ordering on the fourth CPU board is: /dev/rrtc/3c0, /dev/rrtc/3c2, /dev/rrtc/3c1.
Modes
An rtc is in one of two modes: default or direct. These modes provide different degrees of control over a real-time clock. Default mode enables a user to control the direction of the clock count (up or down), the clock count value (1 to 65535), the resolution per clock count value (1, 10, 100, 1000, or 10000 microseconds), and whether the clock automatically restarts counting when the clock count reaches zero. Although this mode does not take advantage of all features supported by the controller, it should satisfy most user needs.
Direct mode enables a user to take advantage of most of the rtc’s features by enabling the user to directly program the hardware registers. Direct mode should not be used without a complete understanding of the chip and its registers. The information needed can be obtained by special request. Note that direct mode does not support comparators, time-of-day mode, and concatenation of registers.
Resolution Restriction
Although rtcs can be loaded with different clock count values and count independently of each other, the resolution per clock count must be the same for all rtcs on Series 4000 systems. Series 5000 systems do not have this restriction.
High-Resolution Callout Queue
You can use a real-time clock for triggering events in the high-resolution callout queue. The hrtconfig(1M) command is provided for this purpose. Note that when you configure a real-time clock for use with the high-resolution callout queue, you cannot use it for any other purpose. See the CX/RT Reference Manual for additional information on the high-resolution callout queue and the hrtconfig(1M) command. Note that using a real-time clock with the high-resolution callout queue does not affect the resolution of other rtcs on the same controller.
User Interface
An rtc is controlled by open(2), close(2), and ioctl(2) system calls. The open(2) system call prohibits more than one process from opening the same rtc at the same time (in other words, rtcs are exclusive devices). The close(2) system service stops the rtc and clears its settings unless either the RTCIOCFBS ioctl(2) command is issued to the rtc before the close(2) or the rtc is configured for use with the high-resolution callout queue. The parameters passed through ioctl(2) control the modes of the rtc, the clock count value, and counting itself; the current settings of the rtc, the clock count, and the valid resolution setting(s) for the rtc can also be obtained by the same call. In addition, all ioctl(2) calls use the structure and/or constants defined in <sys/rtc.h>. Note that this device does not support the read(2) and write(2) system calls.
Ioctl Calls
All of the following ioctl(2) calls require the user to have read and write access to the device.
Two of the ioctl(2) calls have the form:
#include <sys/types.h>
#include <sys/rtc.h>
ioctl(fildes, command, arg)
int fildes, command;
struct rtc ∗arg;
The two commands are:
RTCIOCSETSet up the rtc according to the structure pointed to by arg. This includes setting the mode of the clock, the clock count value, and the resolution per clock count.
RTCIOCGETPlace the current value of each member of the data structure associated with the rtc into the structure pointed to by arg.
The rtc data structure is defined as follows:
struct rtc {
intr_modes;/∗ modes (see below) ∗/
u_shortr_clkcnt;/∗ clock count value ∗/
u_shortr_res;/∗ resolution per clock count ∗/
u_shortr_master_reg;/∗ master mode register ∗/
u_shortr_counter_reg;/∗ counter mode register ∗/
u_shortr_load_reg;/∗ load register ∗/
u_shortr_hold_reg;/∗ hold register ∗/
};
The r_modes field contains the modes of the rtc as follows:
#defineRTC_DEFAULT0x0000/∗ default mode ∗/
#defineRTC_DIRECT0x0001/∗ direct mode ∗/
/∗ the following are valid only in default mode ∗/
#defineRTC_CNTUP0x0002/∗ count up ∗/
#defineRTC_REPEAT0x0004/∗ count repetitively ∗/
On an RTCIOCSET command one of the following modes must be set in the r_modes field:
RTC_DIRECTSet the mode of the rtc to direct, as described above.
RTC_DEFAULTSet the mode of the rtc to count down once. If (r_modes & RTC_CNTUP) is "true," the rtc will count up instead of down. If (r_modes & RTC_REPEAT) is "true," the rtc will count repetitively instead of once.
An RTCIOCGET command results in r_modes being set to the current value stored in the data structure associated with the rtc in the device driver.
The rest of the fields are selectively used based on the mode (default/direct) set in r_modes. If (r_modes & RTC_DIRECT) is "false" (default mode), the r_clkcnt and r_res fields are used. Otherwise, the r_master_reg, r_counter_reg, r_load_reg, and r_hold_reg are used.
The r_clkcnt field contains the clock count value if (r_modes & RTC_DIRECT) is "false." On an RTCIOCSET command, the value of this field is loaded into the rtc’s counter. An RTCIOCGET command results in this field being set to the last value loaded into the rtc’s counter.
Due to hardware constraints, there are a few clock count values r_clkcnt which are invalid and thus not allowed by the real-time clock driver. A clock count value of zero is always illegal. Furthermore, a clock count value of one (1) also is invalid if repetitive mode is selected (r_modes & RTC_REPEAT is "true"). Finally, a clock count value greater than 65535 causes unpredictable behavior because the clock’s registers are only 16-bits wide.
The r_res field contains the resolution per clock count if (r_modes & RTC_DIRECT) is "false." The value in this field is the number of 250 nanosecond intervals that must pass before the clock count is decremented (incremented) by one. The following resolutions are valid in default mode:
#defineUSEC4/∗ 1 microsecond resolution ∗/
#defineUSEC1040/∗ 10 microsecond resolution ∗/
#defineUSEC100400/∗ 100 microsecond resolution ∗/
#defineMSEC4000/∗ 1 millisecond resolution ∗/
#defineMSEC1040000/∗ 10 millisecond resolution ∗/
On an RTCIOCSET command, the resolution per clock count is set to value in r_res. An RTCIOCGET command results in this field being set to the current value stored in the data structure associated with the rtc in the device driver.
The r_master_reg, r_counter_reg, r_load_reg, and r_hold_reg fields represent the hardware registers associated with the rtc and are used only if (r_modes & RTC_DIRECT) is "true."
On an RTCIOCSET command, the contents of these fields are loaded into the corresponding hardware registers on the rtc. An RTCIOCGET command results in these fields being set to the current values stored in the data structure associated with the rtc in the device driver.
The additional ioctl(2) calls have the form:
#include <sys/types.h>
#include <sys/rtc.h>
ioctl(fildes, command, arg)
int fildes, command;
u_short ∗arg;
The commands are:
RTCIOCSETCNTSet the clock count to the value pointed to by arg.
RTCIOCMODCNTModify the clock count to the value pointed to by arg, and start the clock counting. (Note to those who plan to use direct mode: these two commands destroy the previous contents of the load register. They also make the assumption that the load command will use the load register. Therefore, if you are using a mode that alternates loading the rtc’s counter from the load and hold register, these commands may not work. In such cases, use the RTCIOCSET command to load the clock count.)
RTCIOCGETCNTPlace the current clock count value in arg. (Note to those who plan to use direct mode: this command destroys the previous contents of the hold register.)
RTCIOCRESPlace the current resolution for the controller on which this rtc is located in arg. If the value placed in arg is zero, any of the supported resolutions are available. Since rtcs on the same controller must have the same resolution, this command enables a process to determine if its resolution is available now. Only Series 4000 systems have this restriction on resolutions, and so only Series 4000 systems will return a non-zero value.
The following commands ignore arg:
RTCIOCSTARTStart the rtc counting.
RTCIOCSTOPStop the rtc counting.
RTCIOCWAITWait on the clock count value to reach zero.
Two ioctl(2) calls are specific to frequency-based scheduling. These calls have the form:
#include <sys/types.h>
#include <sys/rtc.h>
ioctl(fildes, command, arg)
int fildes, command;
int ∗arg;
The commands are:
RTCIOCFBSSet the mode of the clock to frequency-based scheduling. This enables the clock to be closed (see close(2)) without destroying the modes of the clock (i.e., clock count value, resolution of the clock, counting of clock, etc.). Note that arg is not used by this command.
IOCTLVECNUMPlace the interrupt vector number of the clock in arg. Any device being attached to a frequency-based scheduler must support this ioctl command. For compatibility reasons, this command is defined to have the same value as the FBSIOCVEC command.
The vector number returned from this call may be used on a subsequent iconnect(2) system service call to connect a user-level interrupt routine to the clock interrupt. For more information on user-level interrupt routines, see iconnect(2).
FILES
/dev/rrtc/[0-7]c[0-3] rtc raw (character) special files
ERROR CODES
Ioctl will fail if one or more of the following are true:
[ENXIO] Command is not a valid real-time clock ioctl command.
[EINVAL] Command is RTCIOCSET, and the resolution per clock count is not supported in default mode.
[ENIVAL] Command is either RTCIOCSET or RTCIOCSETCNT, and the clock count value is 0 in non-repetitive mode (RTC_REPEAT bit not set), or the clock count value is 0 or 1 in repetitive mode (RTC_REPEAT bit set).
[EINVAL] Command is RTCIOCSET, and the features set in the master and/or counter mode register are not supported in direct mode. The features not supported are comparators, time-of-day mode, and concatenation of registers.
[EIO] Command is RTCIOCWAIT, and rtc is not currently counting.
[EIO] Command is either RTCIOCSET or RTCIOCSETCNT, and rtc is currently counting.
[EIO] Command is RTCIOCSTART, RTCIOCSTOP, RTCIOCGETCNT, RTCIOCSETCNT, or RTCIOCGET, and rtc has not been previously initialized via an RTCIOCSET command.
[EIO] Command is RTCIOCSET, and the requested resolution is different from a currently active rtc on the same controller.
[EIO] Command is RTCIOCRES, and the resolution has been set by an rtc which is in direct mode. Arg is set to the value of this rtc’s master mode register.
SEE ALSO
ioctl(2), open(2), close(2), iconnect(2), hrtconfig(1M)
BUGS
There is no sanity checking in direct mode. This means that two users of direct mode on the same controller could possibly get in each other’s way. This would most likely happen when programming the master mode register. However, the driver ensures that direct mode cannot affect a currently active rtc in default mode.
CX/UX Administrator’s Reference