rtc在linux上的测试代码

rtc应用很广泛,在PC机和嵌入式上面几乎都能看到。下面就用最简单的代码做一个演示。相应的分析请看linux源代码中的分析文档。代码如下:
#include <stdio.h>
#include <linux/rtc.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>

/*
 * This expects the new RTC class driver framework, working with
 * clocks that will often not be clones of what the PC-AT had.
 * Use the command line to specify another RTC if you need one.
*/
static const char default_rtc[] = "/dev/rtc";
int main(int argc, char **argv)
{
    int i, fd, retval, irqcount = 0;
    unsigned long tmp, data;
    struct rtc_time rtc_tm;
    const char *rtc = default_rtc;
    switch (argc)
    {
        case 2:
            rtc = argv[1];
            /* FALLTHROUGH */
        case 1:
            break;
        default:
            fprintf(stderr, "usage:  rtctest [rtcdev]/n");
        return 1;
    }
    fd = open(rtc, O_RDONLY);
    if (fd ==  -1)
    {
        perror(rtc);
        exit(errno);
    }
    fprintf(stderr, "/n/t/t/tRTC Driver Test Example./n/n");
    /* Turn on update interrupts (one per second) */
    retval = ioctl(fd, RTC_UIE_ON, 0);
    if (retval == -1)
    {
        if (errno == ENOTTY)
        {
            fprintf(stderr,    "/n...Update IRQs not supported./n");
            goto test_READ;
        }
        perror("RTC_UIE_ON ioctl");
        exit(errno);
    }
    fprintf(stderr, "Counting 5 update (1/sec) interrupts from reading %s:",rtc);
    fflush(stderr);
    for (i=1; i<6; i++)
    {
        /* This read will block */
        retval = read(fd, &data, sizeof(unsigned long));
        if (retval == -1)
        {
            perror("read");
            exit(errno);
        }
        fprintf(stderr, " %d",i);
        fflush(stderr);
        irqcount++;
    }
    fprintf(stderr, "/nAgain, from using select(2) on /dev/rtc:");
    fflush(stderr);
    for (i=1; i<6; i++)
    {
        struct timeval tv = {5, 0};     /* 5 second timeout on select */
        fd_set readfds;
        FD_ZERO(&readfds);
        FD_SET(fd, &readfds);
        /* The select will wait until an RTC interrupt happens. */
        retval = select(fd+1, &readfds, NULL, NULL, &tv);
        if (retval == -1)
        {
            perror("select");
            exit(errno);
        }
        /* This read won't block unlike the select-less case above. */
        retval = read(fd, &data, sizeof(unsigned long));
        if (retval == -1)
        {
            perror("read");
            exit(errno);
        }
        fprintf(stderr, " %d",i);
        fflush(stderr);
        irqcount++;
    }
    /* Turn off update interrupts */
    retval = ioctl(fd, RTC_UIE_OFF, 0);
    if (retval == -1)
    {
        perror("RTC_UIE_OFF ioctl");
        exit(errno);
    }
    test_READ:
    /* Read the RTC time/date */
    retval = ioctl(fd, RTC_RD_TIME, &rtc_tm);
    if (retval == -1)
    {
        perror("RTC_RD_TIME ioctl");
        exit(errno);
    }
    fprintf(stderr, "/n/nCurrent RTC date/time is %d-%d-%d, %02d:%02d:%02d./n",rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900,rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
    /* Set the alarm to 5 sec in the future, and check for rollover */
    rtc_tm.tm_sec += 5;
    if (rtc_tm.tm_sec >= 60)
    {
        rtc_tm.tm_sec %= 60;
        rtc_tm.tm_min++;
    }
    if  (rtc_tm.tm_min == 60)
    {
        rtc_tm.tm_min = 0;
        rtc_tm.tm_hour++;
    }
    if  (rtc_tm.tm_hour == 24)
        rtc_tm.tm_hour = 0;
    retval = ioctl(fd, RTC_ALM_SET, &rtc_tm);
    if (retval == -1)
    {
        if (errno == ENOTTY)
        {
            fprintf(stderr,"/n...Alarm IRQs not supported./n");
            goto test_PIE;
        }
        perror("RTC_ALM_SET ioctl");
        exit(errno);
    }
    /* Read the current alarm settings */
    retval = ioctl(fd, RTC_ALM_READ, &rtc_tm);
    if (retval == -1)
    {
        perror("RTC_ALM_READ ioctl");
        exit(errno);
    }
    fprintf(stderr, "Alarm time now set to %02d:%02d:%02d./n",rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
    /* Enable alarm interrupts */
    retval = ioctl(fd, RTC_AIE_ON, 0);
    if (retval == -1)
    {
        perror("RTC_AIE_ON ioctl");
        exit(errno);
    }
    fprintf(stderr, "Waiting 5 seconds for alarm...");
    fflush(stderr);
    /* This blocks until the alarm ring causes an interrupt */
    retval = read(fd, &data, sizeof(unsigned long));
    if (retval == -1)
    {
        perror("read");
        exit(errno);
    }
    irqcount++;
    fprintf(stderr, " okay. Alarm rang./n");
    /* Disable alarm interrupts */
    retval = ioctl(fd, RTC_AIE_OFF, 0);
    if (retval == -1)
    {
        perror("RTC_AIE_OFF ioctl");
        exit(errno);
    }
    test_PIE:
    /* Read periodic IRQ rate */
    retval = ioctl(fd, RTC_IRQP_READ, &tmp);
    if (retval == -1)
    {
        /* not all RTCs support periodic IRQs */
        if (errno == ENOTTY)
        {
            fprintf(stderr, "/nNo periodic IRQ support/n");
            goto done;
        }
        perror("RTC_IRQP_READ ioctl");
        exit(errno);
    }
    fprintf(stderr, "/nPeriodic IRQ rate is %ldHz./n", tmp);
    fprintf(stderr, "Counting 20 interrupts at:");
    fflush(stderr);
    /* The frequencies 128Hz, 256Hz, ... 8192Hz are only allowed for root. */
    for (tmp=2; tmp<=1024; tmp*=2)
    {
        retval = ioctl(fd, RTC_IRQP_SET, tmp);
        if (retval == -1)
        {
            /* not all RTCs can change their periodic IRQ rate */
            if (errno == ENOTTY)
            {
                fprintf(stderr,"/n...Periodic IRQ rate is fixed/n");
                goto done;
            }
            perror("RTC_IRQP_SET ioctl");
            exit(errno);
        }
        fprintf(stderr, "/n%ldHz:/t", tmp);
        fflush(stderr);
        /* Enable periodic interrupts */
        retval = ioctl(fd, RTC_PIE_ON, 0);
        if (retval == -1)
        {
            perror("RTC_PIE_ON ioctl");
            exit(errno);
        }
        for (i=1; i<21; i++)
        {
            /* This blocks */
            retval = read(fd, &data, sizeof(unsigned long));
            if (retval == -1)
            {
                perror("read");
                exit(errno);
            }
            fprintf(stderr, " %d",i);
            fflush(stderr);
            irqcount++;
        }
        /* Disable periodic interrupts */
        retval = ioctl(fd, RTC_PIE_OFF, 0);
        if (retval == -1)
        {
            perror("RTC_PIE_OFF ioctl");
            exit(errno);
        }
    }
    done:
    fprintf(stderr, "/n/n/t/t/t *** Test complete ***/n");
    close(fd);
    return 0;
}
这个是linux文档中的说明代码,希望能给你做RTC程序提供相应的思路。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值