linux/Documentation/timers/hpet_example.c
<<
>>
Prefs
   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