首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

RTC实时时钟驱动(9)

RTC实时时钟驱动(9)

ret = request_irq(s3c_rtc_tickno, s3c_rtc_tickirq,
              IRQF_DISABLED,  "s3c2410-rtc tick", rtc_dev);                         //申请一个计数中断,将中断函数设为s3c_rtc_tickirq(),并传递rtc_dev作为参数

    if (ret) {
        dev_err(dev, "IRQ%d error %d\n", s3c_rtc_tickno, ret);
        goto tick_err;
    }

    return ret;

tick_err:
    free_irq(s3c_rtc_alarmno, rtc_dev);
    return ret;
}
RTC设备释放函数由s3c_rtc_release()来实现。用户空间调用close()时,最终会调用s3c_rtc_release()函数。该函数主要释放s3c_rtc_open()函数申请的两个中断
static void s3c_rtc_release(struct device *dev)
{
    struct platform_device *pdev = to_platform_device(dev);         //从device结构体转到platform_device
    struct rtc_device *rtc_dev = platform_get_drvdata(pdev);         //从pdev->dev的私有数据中得到rtc_device

    /* do not clear AIE here, it may be needed for wake */

    s3c_rtc_setpie(dev, 0);
    free_irq(s3c_rtc_alarmno, rtc_dev);
    free_irq(s3c_rtc_tickno, rtc_dev);
}
RTC实时时钟获得时间安函数
当调用read()函数时会间接的调用s3c_rtc_gettime()函数来获得实时时钟的时间。时间值分别保存在RTC实时时钟的各个寄存器中。这些寄存器是秒寄存器、日期寄存器、分钟寄存器、和小时寄存器。s3c_rtc_gettime()函数会使用一个struct rtc_time 的机构体来表示一个时间值
struct rtc_time {
    int tm_sec;
    int tm_min;
    int tm_hour;
    int tm_mday;
    int tm_mon;
    int tm_year;
    int tm_wday;     //这三个RTC实时时钟未用
    int tm_yday;
    int tm_isdst;
};

存储在RTC实时时钟寄存器中的值都是以BCD码保存的。但是Linux驱动程序中使用二进制码形式。通过bcd2bin()
unsigned bcd2bin(unsigned char val)
{
              return (val & 0x0f) + (val >> 4) * 10;
}
unsigned char bin2bcd(unsigned val)
{
              return ((val / 10) << 4) + val % 10;
}
从RTC实时时钟得到时间的函数是s3c_rtc_gettime()。第一个参数是RTC设备结构体指针,第二个参数是前面提到的struct rtc_time。
static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
{
    unsigned int have_retried = 0;
    void __iomem *base = s3c_rtc_base;

retry_get_time:
    rtc_tm->tm_min  = readb(base + S3C2410_RTCMIN);
    rtc_tm->tm_hour = readb(base + S3C2410_RTCHOUR);
    rtc_tm->tm_mday = readb(base + S3C2410_RTCDATE);
    rtc_tm->tm_mon  = readb(base + S3C2410_RTCMON);
    rtc_tm->tm_year = readb(base + S3C2410_RTCYEAR);
    rtc_tm->tm_sec  = readb(base + S3C2410_RTCSEC);

    /* the only way to work out wether the system was mid-update
     * when we read it is to check the second counter, and if it
     * is zero, then we re-try the entire read
     */

    if (rtc_tm->tm_sec == 0 && !have_retried) {          //如果秒寄存器中是0,则表示过去了一分钟,那么小时,天,月,等寄存器中的值都可能已经变化,则重新读取这些寄存器的值
        have_retried = 1;
        goto retry_get_time;
    }
继承事业,薪火相传
返回列表