1
2
3
4
5
6
7
8
9
10
11#include <stdio.h>
12#include <linux/rtc.h>
13#include <sys/ioctl.h>
14#include <sys/time.h>
15#include <sys/types.h>
16#include <fcntl.h>
17#include <unistd.h>
18#include <stdlib.h>
19#include <errno.h>
20
21
22
23
24
25
26static const char default_rtc[] = "/dev/rtc0";
27
28int main(int argc, char **argv)
29{
30 int i, fd, retval, irqcount = 0;
31 unsigned long tmp, data, old_pie_rate;
32 const char *rtc = default_rtc;
33 struct timeval start, end, diff;
34
35 switch (argc) {
36 case 2:
37 rtc = argv[1];
38
39 case 1:
40 break;
41 default:
42 fprintf(stderr, "usage: rtctest [rtcdev] [d]\n");
43 return 1;
44 }
45
46 fd = open(rtc, O_RDONLY);
47
48 if (fd == -1) {
49 perror(rtc);
50 exit(errno);
51 }
52
53
54 retval = ioctl(fd, RTC_IRQP_READ, &old_pie_rate);
55 if (retval == -1) {
56
57 if (errno == EINVAL) {
58 fprintf(stderr, "\nNo periodic IRQ support\n");
59 goto done;
60 }
61 perror("RTC_IRQP_READ ioctl");
62 exit(errno);
63 }
64 fprintf(stderr, "\nPeriodic IRQ rate is %ldHz.\n", old_pie_rate);
65
66 fprintf(stderr, "Counting 20 interrupts at:");
67 fflush(stderr);
68
69
70 for (tmp=2; tmp<=64; tmp*=2) {
71
72 retval = ioctl(fd, RTC_IRQP_SET, tmp);
73 if (retval == -1) {
74
75 if (errno == EINVAL) {
76 fprintf(stderr,
77 "\n...Periodic IRQ rate is fixed\n");
78 goto done;
79 }
80 perror("RTC_IRQP_SET ioctl");
81 exit(errno);
82 }
83
84 fprintf(stderr, "\n%ldHz:\t", tmp);
85 fflush(stderr);
86
87
88 retval = ioctl(fd, RTC_PIE_ON, 0);
89 if (retval == -1) {
90 perror("RTC_PIE_ON ioctl");
91 exit(errno);
92 }
93
94 for (i=1; i<21; i++) {
95 gettimeofday(&start, NULL);
96
97 retval = read(fd, &data, sizeof(unsigned long));
98 if (retval == -1) {
99 perror("read");
100 exit(errno);
101 }
102 gettimeofday(&end, NULL);
103 timersub(&end, &start, &diff);
104 if (diff.tv_sec > 0 ||
105 diff.tv_usec > ((1000000L / tmp) * 1.10)) {
106 fprintf(stderr, "\nPIE delta error: %ld.%06ld should be close to 0.%06ld\n",
107 diff.tv_sec, diff.tv_usec,
108 (1000000L / tmp));
109 fflush(stdout);
110 exit(-1);
111 }
112
113 fprintf(stderr, " %d",i);
114 fflush(stderr);
115 irqcount++;
116 }
117
118
119 retval = ioctl(fd, RTC_PIE_OFF, 0);
120 if (retval == -1) {
121 perror("RTC_PIE_OFF ioctl");
122 exit(errno);
123 }
124 }
125
126done:
127 ioctl(fd, RTC_IRQP_SET, old_pie_rate);
128
129 fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n");
130
131 close(fd);
132
133 return 0;
134}
135