Linux下如何编写RTC驱动

/drivers/rtc/rtc-test.c下有一个rtc驱动的框架例程。


填写 rtc_class_ops

编写RTC内核驱动的主要步骤就是填写 rtc_class_ops。

这个结构体中使用的struct device参数就是rtc_device_register()使用的那个dev,它代表总线上的物理设备。这个

struct device的driver_data数据一般保存struct device的状态,包括指向rtc_device的指针。


驱动开发者至少应该提供read_time/set_time这两个接口,其他函数都是可选的。

141  struct rtc_class_ops {
142        int (*open)(struct device *);           //打开设备时的回调函数,这个函数应该初始化硬件并申请资源                   
143        void (*release)(struct device *);     //这个函数是设备关闭时被调用的,应该注销申请的资源。
144        int (*ioctl)(struct device *, unsigned int, unsigned long);     //ioctl函数,对于想让RTC自己实现的命令应返回ENOIOCTLCMD
145        int (*read_time)(struct device *, struct rtc_time *);            //读取时间  
146        int (*set_time)(struct device *, struct rtc_time *);              //设置时间
147        int (*read_alarm)(struct device *, struct rtc_wkalrm *);      //读取下一次定时中断的时间
148        int (*set_alarm)(struct device *, struct rtc_wkalrm *);        //设置下一次定时中断的时间
149        int (*proc)(struct device *, struct seq_file *); //procfs接口,该函数决定你在终端中cat /proc/driver/rtc时输出相关的信息
150        int (*set_mmss)(struct device *, unsigned long secs);         // 将传入的参数secs转换为struct rtc_time然后调用set_time函数。程序员可以不实现这个函数,但前提是定义好了read_time/set_time,因为RTC框架需要用这两个函数来实现这个功能。
151        int (*irq_set_state)(struct device *, int enabled);                //周期采样中断的开关,根据enabled的值来设置
152        int (*irq_set_freq)(struct device *, int freq);                       //设置周期中断的频率  
153        int (*read_callback)(struct device *, int data);     //用户空间获得数据后会传入读取的数据,并用这个函数返回的数据更新数据。
154        int (*alarm_irq_enable)(struct device *, unsigned int enabled);     //alarm中断使能开关,根据enabled的值来设置
155        int (*update_irq_enable)(struct device *, unsigned int enabled);     //更新中断使能开关,根据enabled的值来设置
156  };


1.免定义的ioctl命令

这里的ioctl函数并不一定要实现所有的命令,对于一些命令如果rtc_class_ops的ioctl返回ENOIOCTLCMD的话,内核的RTC子系统会

实现这些命令的方法。不需要自己实现的命令有:

     * RTC_RD_TIME, RTC_SET_TIME     read_time/set_time

     * RTC_ALM_SET, RTC_ALM_READ, RTC_WKALM_SET, RTC_WKALM_RD 调用set_alarm/read_alarm

     * RTC_IRQP_SET, RTC_IRQP_READ        调用  irq_set_freq来实现。如果不支持修改中断频率,就不要定义这个函数。

     * RTC_PIE_ON, RTC_PIE_OFF 通过irq_set_state来实现。

RTC子系统实现这些命令的方式是调用你编写的函数,如果根本不提供这些函数的话,也根本不能实现这些命令。


2.read_callback

每次有数据可读取,read_callback便会被调用。

如果定义了read_callback,用户空间读取到的实际是read_callback返回的值。

文件/drivers/rtc/rtc-dev.c的rtc_dev_read函数中可了解read_callback与irq_data之间的关系

static ssize_t
rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{

。。。。。。。。。。
//这里睡眠并等待读取数据
。。。。。。。。。。                    

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwjzdj.html