日期:2014-05-16 浏览次数:21281 次
一.描述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