Root/Documentation/timers/hpet_example.c

1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <fcntl.h>
5#include <string.h>
6#include <memory.h>
7#include <malloc.h>
8#include <time.h>
9#include <ctype.h>
10#include <sys/types.h>
11#include <sys/wait.h>
12#include <signal.h>
13#include <errno.h>
14#include <sys/time.h>
15#include <linux/hpet.h>
16
17
18extern void hpet_open_close(int, const char **);
19extern void hpet_info(int, const char **);
20extern void hpet_poll(int, const char **);
21extern void hpet_fasync(int, const char **);
22extern void hpet_read(int, const char **);
23
24#include <sys/poll.h>
25#include <sys/ioctl.h>
26
27struct hpet_command {
28    char *command;
29    void (*func)(int argc, const char ** argv);
30} hpet_command[] = {
31    {
32        "open-close",
33        hpet_open_close
34    },
35    {
36        "info",
37        hpet_info
38    },
39    {
40        "poll",
41        hpet_poll
42    },
43    {
44        "fasync",
45        hpet_fasync
46    },
47};
48
49int
50main(int argc, const char ** argv)
51{
52    int i;
53
54    argc--;
55    argv++;
56
57    if (!argc) {
58        fprintf(stderr, "-hpet: requires command\n");
59        return -1;
60    }
61
62
63    for (i = 0; i < (sizeof (hpet_command) / sizeof (hpet_command[0])); i++)
64        if (!strcmp(argv[0], hpet_command[i].command)) {
65            argc--;
66            argv++;
67            fprintf(stderr, "-hpet: executing %s\n",
68                hpet_command[i].command);
69            hpet_command[i].func(argc, argv);
70            return 0;
71        }
72
73    fprintf(stderr, "do_hpet: command %s not implemented\n", argv[0]);
74
75    return -1;
76}
77
78void
79hpet_open_close(int argc, const char **argv)
80{
81    int fd;
82
83    if (argc != 1) {
84        fprintf(stderr, "hpet_open_close: device-name\n");
85        return;
86    }
87
88    fd = open(argv[0], O_RDONLY);
89    if (fd < 0)
90        fprintf(stderr, "hpet_open_close: open failed\n");
91    else
92        close(fd);
93
94    return;
95}
96
97void
98hpet_info(int argc, const char **argv)
99{
100    struct hpet_info info;
101    int fd;
102
103    if (argc != 1) {
104        fprintf(stderr, "hpet_info: device-name\n");
105        return;
106    }
107
108    fd = open(argv[0], O_RDONLY);
109    if (fd < 0) {
110        fprintf(stderr, "hpet_info: open of %s failed\n", argv[0]);
111        return;
112    }
113
114    if (ioctl(fd, HPET_INFO, &info) < 0) {
115        fprintf(stderr, "hpet_info: failed to get info\n");
116        goto out;
117    }
118
119    fprintf(stderr, "hpet_info: hi_irqfreq 0x%lx hi_flags 0x%lx ",
120        info.hi_ireqfreq, info.hi_flags);
121    fprintf(stderr, "hi_hpet %d hi_timer %d\n",
122        info.hi_hpet, info.hi_timer);
123
124out:
125    close(fd);
126    return;
127}
128
129void
130hpet_poll(int argc, const char **argv)
131{
132    unsigned long freq;
133    int iterations, i, fd;
134    struct pollfd pfd;
135    struct hpet_info info;
136    struct timeval stv, etv;
137    struct timezone tz;
138    long usec;
139
140    if (argc != 3) {
141        fprintf(stderr, "hpet_poll: device-name freq iterations\n");
142        return;
143    }
144
145    freq = atoi(argv[1]);
146    iterations = atoi(argv[2]);
147
148    fd = open(argv[0], O_RDONLY);
149
150    if (fd < 0) {
151        fprintf(stderr, "hpet_poll: open of %s failed\n", argv[0]);
152        return;
153    }
154
155    if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
156        fprintf(stderr, "hpet_poll: HPET_IRQFREQ failed\n");
157        goto out;
158    }
159
160    if (ioctl(fd, HPET_INFO, &info) < 0) {
161        fprintf(stderr, "hpet_poll: failed to get info\n");
162        goto out;
163    }
164
165    fprintf(stderr, "hpet_poll: info.hi_flags 0x%lx\n", info.hi_flags);
166
167    if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
168        fprintf(stderr, "hpet_poll: HPET_EPI failed\n");
169        goto out;
170    }
171
172    if (ioctl(fd, HPET_IE_ON, 0) < 0) {
173        fprintf(stderr, "hpet_poll, HPET_IE_ON failed\n");
174        goto out;
175    }
176
177    pfd.fd = fd;
178    pfd.events = POLLIN;
179
180    for (i = 0; i < iterations; i++) {
181        pfd.revents = 0;
182        gettimeofday(&stv, &tz);
183        if (poll(&pfd, 1, -1) < 0)
184            fprintf(stderr, "hpet_poll: poll failed\n");
185        else {
186            long data;
187
188            gettimeofday(&etv, &tz);
189            usec = stv.tv_sec * 1000000 + stv.tv_usec;
190            usec = (etv.tv_sec * 1000000 + etv.tv_usec) - usec;
191
192            fprintf(stderr,
193                "hpet_poll: expired time = 0x%lx\n", usec);
194
195            fprintf(stderr, "hpet_poll: revents = 0x%x\n",
196                pfd.revents);
197
198            if (read(fd, &data, sizeof(data)) != sizeof(data)) {
199                fprintf(stderr, "hpet_poll: read failed\n");
200            }
201            else
202                fprintf(stderr, "hpet_poll: data 0x%lx\n",
203                    data);
204        }
205    }
206
207out:
208    close(fd);
209    return;
210}
211
212static int hpet_sigio_count;
213
214static void
215hpet_sigio(int val)
216{
217    fprintf(stderr, "hpet_sigio: called\n");
218    hpet_sigio_count++;
219}
220
221void
222hpet_fasync(int argc, const char **argv)
223{
224    unsigned long freq;
225    int iterations, i, fd, value;
226    sig_t oldsig;
227    struct hpet_info info;
228
229    hpet_sigio_count = 0;
230    fd = -1;
231
232    if ((oldsig = signal(SIGIO, hpet_sigio)) == SIG_ERR) {
233        fprintf(stderr, "hpet_fasync: failed to set signal handler\n");
234        return;
235    }
236
237    if (argc != 3) {
238        fprintf(stderr, "hpet_fasync: device-name freq iterations\n");
239        goto out;
240    }
241
242    fd = open(argv[0], O_RDONLY);
243
244    if (fd < 0) {
245        fprintf(stderr, "hpet_fasync: failed to open %s\n", argv[0]);
246        return;
247    }
248
249
250    if ((fcntl(fd, F_SETOWN, getpid()) == 1) ||
251        ((value = fcntl(fd, F_GETFL)) == 1) ||
252        (fcntl(fd, F_SETFL, value | O_ASYNC) == 1)) {
253        fprintf(stderr, "hpet_fasync: fcntl failed\n");
254        goto out;
255    }
256
257    freq = atoi(argv[1]);
258    iterations = atoi(argv[2]);
259
260    if (ioctl(fd, HPET_IRQFREQ, freq) < 0) {
261        fprintf(stderr, "hpet_fasync: HPET_IRQFREQ failed\n");
262        goto out;
263    }
264
265    if (ioctl(fd, HPET_INFO, &info) < 0) {
266        fprintf(stderr, "hpet_fasync: failed to get info\n");
267        goto out;
268    }
269
270    fprintf(stderr, "hpet_fasync: info.hi_flags 0x%lx\n", info.hi_flags);
271
272    if (info.hi_flags && (ioctl(fd, HPET_EPI, 0) < 0)) {
273        fprintf(stderr, "hpet_fasync: HPET_EPI failed\n");
274        goto out;
275    }
276
277    if (ioctl(fd, HPET_IE_ON, 0) < 0) {
278        fprintf(stderr, "hpet_fasync, HPET_IE_ON failed\n");
279        goto out;
280    }
281
282    for (i = 0; i < iterations; i++) {
283        (void) pause();
284        fprintf(stderr, "hpet_fasync: count = %d\n", hpet_sigio_count);
285    }
286
287out:
288    signal(SIGIO, oldsig);
289
290    if (fd >= 0)
291        close(fd);
292
293    return;
294}
295

Archive Download this file



interactive