linux RTC设备驱动

本文详细介绍了Linux实时控制系统(RTC)的设备结构体、时间结构体、闹钟结构体以及RTC类操作函数集。讨论了RTC系统的初始化,包括字符设备和sysfs下的初始化,并阐述了RTC设备的注册与注销过程。此外,还解析了rtc_dev_fops函数集及其在设备文件操作中的作用,以及如何编写RTC驱动和操作系统与RTC时间的相关方法。
摘要由CSDN通过智能技术生成

一. RTC设备结构体

struct rtc_device
{
	struct device dev;		//设备文件
	struct module *owner;	//模块所有者
	int id;			//RTC次设备
	char name[RTC_DEVICE_NAME_SIZE];	//RTC设备名
	const struct rtc_class_ops *ops;	//RTC类操作函数集
	struct mutex ops_lock;
	struct cdev char_dev;	//RTC字符设备
	unsigned long flags;	//忙标志位
	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;		//最大频率
#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
	struct work_struct uie_task;
	struct timer_list uie_timer;
	/* Those fields are protected by rtc->irq_lock */
	unsigned int oldsecs;
	unsigned int uie_irq_active:1;
	unsigned int stop_uie_polling:1;
	unsigned int uie_task_active:1;
	unsigned int uie_timer_active:1;
#endif
};

二. RTC时间结构体

struct rtc_time {
	int tm_sec;	//秒
	int tm_min;	//分
	int tm_hour;	//时
	int tm_mday;	//日
	int tm_mon;	//月
	int tm_year;	//年
	int tm_wday;	//星期
	int tm_yday;	//年中的第几天
	int tm_isdst;	//
};


三. 闹钟相关结构体

struct rtc_wkalrm {
	unsigned char enabled;/* 0 = alarm disabled, 1 = alarm enabled */	//是否支持闹钟功能
	unsigned char pending;/* 0 = alarm not pending, 1 = alarm pending */	//是否等待
	struct rtc_time time;·/* time the alarm is set to */	//闹钟时间
};

 

四. RTC 类操作函数集

struct rtc_class_ops {
	int (*open)(struct device *);	//open方法
	void (*release)(struct device *);	//release方法
	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 *);
	int (*set_mmss)(struct device *, unsigned long secs);	//秒装换为rtc_time
	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);//更新中断使能开关
};


五. RTC系统初始化
     5.1 rtc系统的初始化

static int __init rtc_init(void)
{
	rtc_class = class_create(THIS_MODULE, "rtc");		//创建rtc_class类"/sys/class/rtc"
	if (IS_ERR(rtc_class)) {
		printk(KERN_ERR "%s: couldn't create class\n", __FILE__);
		return PTR_ERR(rtc_class);
	}
	rtc_class->suspend = rtc_suspend;	//RTC挂起
	rtc_class->resume = rtc_resume;	//RTC唤醒
	rtc_dev_init();	//RTC字符设备初始化
	rtc_sysfs_init(rtc_class);
	return 0;
}

     5.2 作为字符设备的初始化

void __init rtc_dev_init(void)
{
	int err;

	err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc");	//RTC_DEV_MAX=16 系统最大支持16个rtc
	if (err < 0)
		printk(KERN_ERR "%s: failed to allocate char dev region\n",__FILE__);
}

这里rtc_devt记录了分配的第一个RTC设备的设备号,同样它也可以作为rtc类的主设备号

     5.3 RTC在sysfs下的初始化

     5.3.1

void __init rtc_sysfs_init(struct class *rtc_class)
{
	rtc_class->dev_attrs = rtc_attrs;
}

     5.3.2

static struct device_attribute rtc_attrs[] = {
	__ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL),	//“/sys/class/rtc/rtcX/name“
	__ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL),	//“/sys/class/rtc/rtcX/date“
	__ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL),	//“/sys/class/rtc/rtcX/time“
	__ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL),	//“/sys/class/rtc/rtcX/since_epoch“
	__ATTR(max_user_freq, S_IRUGO | S_IWUSR, rtc_sysfs_show_max_user_freq,rtc_sysfs_set_max_user_freq),	//.../max_user_freq
	__ATTR(hctosys, S_IRUGO, rtc_sysfs_show_hctosys, NULL),//"/sys/class/rtc/rtcX/hctosys"	
	{ },
};

     5.3.3 /sys/cl

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值