日期:2014-05-16 浏览次数:20976 次
一.描述rtc相关结构体
1.rtc设备
struct rtc_device //rtc设备 { struct device dev; //设备文件 struct module *owner; //所有者 int id; //次设备号 char name[RTC_DEVICE_NAME_SIZE]; //rtc设备名 const struct rtc_class_ops *ops; //rtc类操作函数集 struct mutex ops_lock; struct cdev char_dev; //字符设备 unsigned long flags; //忙标志 (RTC_DEV_BUSY) unsigned long irq_data; //中断数据 spinlock_t irq_lock; wait_queue_head_t irq_queue; struct fasync_struct *async_queue; struct rtc_task *irq_task; //中断任务 spinlock_t irq_task_lock; int irq_freq; //中断频率 int max_user_freq; //默认64 };
1.1 同时也定义了一个宏,通过设备文件查找rtc设备
#define to_rtc_device(d) container_of(d, struct rtc_device, dev)
2.rtc类操作函数集
struct rtc_class_ops { int (*open)(struct device *); //打开 void (*release)(struct device *); //释放 int (*ioctl)(struct device *, unsigned int, unsigned long); //控制 int (*read_time)(struct device *, struct rtc_time *); //读时间 int (*set_time)(struct device *, struct rtc_time *); //设置时间 int (*read_alarm)(struct device *, struct rtc_wkalrm *); //读闹钟 int (*set_alarm)(struct device *, struct rtc_wkalrm *); //设闹钟 int (*proc)(struct device *, struct seq_file *); //proc接口 int (*set_mmss)(struct device *, unsigned long secs); //设置时间mmss int (*irq_set_state)(struct device *, int enabled); //设置中断状态 int (*irq_set_freq)(struct device *, int freq); //设置中断频率 int (*read_callback)(struct device *, int data); //读回调函数 int (*alarm_irq_enable)(struct device *, unsigned int enabled); //闹钟中断使能 int (*update_irq_enable)(struct device *, unsigned int enabled); //更新中断使能 };
这里有两种设置时间的方法set_time和set_mmss,看它们参数可以区别出set_time使用rtc时间来设置,
set_mmss是根据秒数来设置(“Gregorian”时间)
二.rtc架构
1.rtc设备初始化函数
void __init rtc_dev_init(void) //入口函数 { int err; err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc"); //动态分配rtc设备号 RTC_DEV_MAX=16个 if (err < 0) printk(KERN_ERR "%s: failed to allocate char dev region\n",__FILE__); }
2.rtc设备的注册
rtc注册由具体设备驱动调用,同时设备驱动必须提供rtc_class_ops操作函数集
struct rtc_device *rtc_device_register(const char *name, struct device *dev,const struct rtc_class_ops *ops,struct module *owner) { struct rtc_device *rtc; //rtc设备 int id, err; if (idr_pre_get(&rtc_idr, GFP_KERNEL) == 0) { //idr机制预分配 err = -ENOMEM; goto exit; } mutex_lock(&idr_lock); err = idr_get_new(&rtc_idr, NULL, &id); //通过idr机制获取id号 mutex_unlock(&idr_lock); if (err < 0) goto exit; id = id & MAX_ID_MASK; //id掩码过滤 rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL); //分配rtc设备 if (rtc == NULL) { err = -ENOMEM; goto exit_idr; } rtc->id = id; //次设备号 rtc->ops = ops; //rtc类操作函数集 rtc->owner = owner; //所有者 rtc->max_user_freq = 64; //最大用户频率 rtc->dev.parent = dev; //设备父设备 rtc->dev.class = rtc_class; //2.1 设备类 rtc->dev.release = rtc_device_release; //设备释放方法 mutex_init(&rtc->ops_lock); spin_lock_init(&rtc->irq_lock); spin_lock_init(&rtc->irq_task_lock); init_waitqueue_head(&rtc->irq_queue); strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); //设置rtc设备名 dev_set_name(&rtc->dev, "rtc%d", id); //设置设备名 rtc_dev_prepare(rtc); //2.2 rtc设备准备 err = device_register(&rtc->dev); //注册设备文件 if (err) { put_device(&rtc->dev); goto exit_kfree; } rtc_dev_add_device(rtc); //2.3 rtc添加设备 rtc_sysfs_add_device(rtc); //sysfs添加设备文件 rtc_proc_add_device(rtc); //procfs添加设备文件 dev_info(dev, "rtc core: registered %s as %s\n",rtc->name, dev_name(&rtc->dev)); return rtc; exit_kfree: kfree(rtc); exit_idr: mutex_lock(&idr_lock); idr_remove(&rtc_idr, id); mutex_unlock(&idr_lock); exit: dev_err(dev, "rtc core: unable to regi