Linux RTC驱动模型分析之rtc-proc.c

原创 2016年08月30日 17:00:11

认识rtc节点

proc下的rtc节点的位置是:  /proc/driver/rtc。 该节点可以清晰的显示出当前的时间,当前的日期,alarm的时间,日期,alarm是否使能等详细信息。在分析代码之前先认识一下。
root@test:test # cat /proc/driver/rtc 
rtc_time	: 06:25:56                                //当前的时间
rtc_date	: 2012-01-12                              //当前的日期
alrm_time	: 05:04:36                                //alarm的时间
alrm_date	: 2033-04-23                              //alarm的日期
alarm_IRQ	: no                                      //alarm IRQ是否使能
alrm_pending	: no                                      //alarm pending是否使能
update IRQ enabled	: no                              //update IRQ是否使能
periodic IRQ enabled	: no                              //periodic(周期性)IRQ是否使能
periodic IRQ frequency	: 1                               //periodic IRQ频率
max user IRQ frequency	: 64                              //periodic IRQ最大的频率
24hr		: yes                                     //24小时制
在认识了rtc节点之后,接下来分析代码。

rtc-proc.c

void rtc_proc_add_device(struct rtc_device *rtc)
{
	if (is_rtc_hctosys(rtc))                                                  //判断是否用rtc设备设置系统时间
		proc_create_data("driver/rtc", 0, NULL, &rtc_proc_fops, rtc);     //如果是,则创建proc节点
}
如下是is_rtc_hctosys的实现:
#if defined(CONFIG_RTC_HCTOSYS_DEVICE)
static bool is_rtc_hctosys(struct rtc_device *rtc)
{
	int size;
	char name[NAME_SIZE];

	size = scnprintf(name, NAME_SIZE, "rtc%d", rtc->id);
	if (size > NAME_SIZE)
		return false;

	return !strncmp(name, CONFIG_RTC_HCTOSYS_DEVICE, NAME_SIZE);            //也就是比较rtc设备与内核config中配置的是否一样。
}
#else
static bool is_rtc_hctosys(struct rtc_device *rtc)
{
	return (rtc->id == 0);
}
#endif
而此函数是通过内核配置:  CONFIG_RTC_HCTOSYS_DEVICE决定的。
可以通过kmconfig查看该配置的详细信息,如下:
CONFIG_RTC_HCTOSYS_DEVICE:                                                                                                                            
  │ The RTC device that will be used to (re)initialize the system                                                                                         
  │ clock, usually rtc0. Initialization is done when the system                                                                                           
  │ starts up, and when it resumes from a low power state. This                                                                                           
  │ device should record time in UTC, since the kernel won't do                                                                                           
  │ timezone correction.                                                                                                                                 
  │                                                                                                                                                       
  │ The driver for this RTC device must be loaded before late_initcall                                                                                    
  │ functions run, so it must usually be statically linked.                                                                                               
  │                                                                                                                                                       
  │ This clock should be battery-backed, so that it reads the correct                                                                                     
  │ time when the system boots from a power-off state. Otherwise, your                                                                                    
  │ system will need an external clock source (like an NTP server).                                                                                       
  │                                                                                                                                                       
  │ If the clock you specify here is not battery backed, it may still                                                                                     
  │ be useful to reinitialize system time when resuming from system                                                                                      
  │ sleep states. Do not specify an RTC here unless it stays powered                                                                                      
  │ during all this system's supported sleep states.            
大概意识是当系统启动时,rtc设备通常被用来设置系统时间。

如下是rtc_proc_fops的结构:
static const struct file_operations rtc_proc_fops = {
	.open		= rtc_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= rtc_proc_release,
};

当系统打开这个文件的时候就调用到open函数,这都是proc文件系统的执行过程,不是这部分的重点,跳过。
static int rtc_proc_open(struct inode *inode, struct file *file)
{
	int ret;
	struct rtc_device *rtc = PDE_DATA(inode);                  //获得rtc设备结构

	if (!try_module_get(THIS_MODULE))
		return -ENODEV;

	ret = single_open(file, rtc_proc_show, rtc);              //调用顺序文件结构初始化
	if (ret)
		module_put(THIS_MODULE);
	return ret;
}
当cat /proc/driver/rtc的时候就调用到read函数,然后最终调用到rtc_proc_show函数。
static int rtc_proc_show(struct seq_file *seq, void *offset)
{
	int err;
	struct rtc_device *rtc = seq->private;
	const struct rtc_class_ops *ops = rtc->ops;
	struct rtc_wkalrm alrm;
	struct rtc_time tm;

	err = rtc_read_time(rtc, &tm);                                    //读取当前的时间
	if (err == 0) {
		seq_printf(seq,
			"rtc_time\t: %02d:%02d:%02d\n"
			"rtc_date\t: %04d-%02d-%02d\n",
			tm.tm_hour, tm.tm_min, tm.tm_sec,
			tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
	}

	err = rtc_read_alarm(rtc, &alrm);                                 //读取alarm时间
	if (err == 0) {
		seq_printf(seq, "alrm_time\t: ");                         //alarm时间
		if ((unsigned int)alrm.time.tm_hour <= 24)
			seq_printf(seq, "%02d:", alrm.time.tm_hour);
		else
			seq_printf(seq, "**:");
		if ((unsigned int)alrm.time.tm_min <= 59)
			seq_printf(seq, "%02d:", alrm.time.tm_min);
		else
			seq_printf(seq, "**:");
		if ((unsigned int)alrm.time.tm_sec <= 59)
			seq_printf(seq, "%02d\n", alrm.time.tm_sec);
		else
			seq_printf(seq, "**\n");

		seq_printf(seq, "alrm_date\t: ");                          //alarm日期
		if ((unsigned int)alrm.time.tm_year <= 200)
			seq_printf(seq, "%04d-", alrm.time.tm_year + 1900);
		else
			seq_printf(seq, "****-");
		if ((unsigned int)alrm.time.tm_mon <= 11)
			seq_printf(seq, "%02d-", alrm.time.tm_mon + 1);
		else
			seq_printf(seq, "**-");
		if (alrm.time.tm_mday && (unsigned int)alrm.time.tm_mday <= 31)
			seq_printf(seq, "%02d\n", alrm.time.tm_mday);
		else
			seq_printf(seq, "**\n");
		seq_printf(seq, "alarm_IRQ\t: %s\n",
				alrm.enabled ? "yes" : "no");                 //alarm IRQ是否使能
		seq_printf(seq, "alrm_pending\t: %s\n",      
				alrm.pending ? "yes" : "no");                 //alarm pending是否使能
		seq_printf(seq, "update IRQ enabled\t: %s\n",
			(rtc->uie_rtctimer.enabled) ? "yes" : "no");          //update IRQ是否使能
		seq_printf(seq, "periodic IRQ enabled\t: %s\n",
			(rtc->pie_enabled) ? "yes" : "no");                   //periodic IRQ是否使能
		seq_printf(seq, "periodic IRQ frequency\t: %d\n",
			rtc->irq_freq);                                       //periodic IRQ频率
		seq_printf(seq, "max user IRQ frequency\t: %d\n",             //最大的频率
			rtc->max_user_freq);
	}

	seq_printf(seq, "24hr\t\t: yes\n");

	if (ops->proc)
		ops->proc(rtc->dev.parent, seq);                               //驱动是否支持proc,一般驱动没有实现。

	return 0;
}
可以使用如下的方法卸载/proc/driver/rtc
void rtc_proc_del_device(struct rtc_device *rtc)
{
	if (is_rtc_hctosys(rtc))
		remove_proc_entry("driver/rtc", NULL);
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

linux 实时时钟(RTC)驱动

这个是linux内核文档关于rtc实时时钟部分的说明,此文档主要描述了rtc实时时钟的作用和编程接口,分别介绍了老的rtc接口和新的rtc类架构。并给出了一个测试rtc驱动的程序。     linu...
  • YAOZHENGUO2006
  • YAOZHENGUO2006
  • 2011年09月25日 19:06
  • 15595

嵌入式Linux中RTC的操作说明

对于手机、PDA的嵌入式平台的关机闹钟都使用RTC实现,RTC是一个硬件。 RTC中存储两个时间,一个是普通的滴答时间,另一个是提醒时间,RTC犹如一个滴答计时器,当RTC中时钟到达指定的提醒时间的...
  • jevonwang
  • jevonwang
  • 2010年10月18日 11:03
  • 1225

Linux RTC驱动模型分析之rtc-sysfs.c

rtc节点 rtc-sysfs文件主要的操作就是在sys下创建rtc的属性节点,可以方便用户方便快捷的访问,查找问题。下来大概看看sys下的rtc节点,有个直观的认识。 [root@test ~]# ...
  • longwang155069
  • longwang155069
  • 2016年08月30日 19:21
  • 1242

RTC驱动模型分析

①RTC设备层: 设备资源的定义:arch/arm/plat-s3c24xx/devs.c static struct resource s3c_rtc_resource[] = { [0] =...
  • u011549260
  • u011549260
  • 2015年04月21日 08:24
  • 775

linux RTC 驱动模型分析

linux RTC 驱动模型分析         RTC(real time clock)实时时钟,主要作用是给Linux系统提供时间。RTC因为是电池供电的,所以掉电后时间不丢失。Linux内核把...
  • YAOZHENGUO2006
  • YAOZHENGUO2006
  • 2011年09月27日 10:28
  • 23468

Linux rtc驱动模块分析

内核版本:linux-2.6.32
  • mcgrady_tracy
  • mcgrady_tracy
  • 2014年09月03日 14:49
  • 4181

Linux RTC驱动模型分析

RTC简介 RTC(real-time clock)简称实时时钟,主要作用是用来记时,产生闹钟等。RTC因为有备份电池,所以即使计算机关机掉电,也不会影响RTC记时。而RTC和系统时间(主要靠软件模拟...
  • longwang155069
  • longwang155069
  • 2016年08月26日 20:16
  • 1682

Linux开发十_rtc驱动

rtc为操作系统提供时钟、日历、闹钟、周期性中断等功能,并且在断电的情况下,可以由电池供电,以很小的耗电继续运行下去,Linux内核已经支持s3c2416的rtc驱动。...
  • huang20083200056
  • huang20083200056
  • 2017年04月23日 01:00
  • 231

cat /proc/driver/rtc

在drivers/rtc/rtc-proc.c 中定义了一个接口,是的可以通过cat /proc/driver/rtc 来查询rtc的情况. 在rtc_device_register->rtc_pro...
  • tiantao2012
  • tiantao2012
  • 2017年09月01日 14:47
  • 231

深入解析linux下rtc架构

一.描述rtc相关结构体 1.rtc设备 [cpp] view plain copy struct rtc_device   //rtc设备  {      struct device ...
  • zjy900507
  • zjy900507
  • 2017年05月15日 15:39
  • 266
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux RTC驱动模型分析之rtc-proc.c
举报原因:
原因补充:

(最多只允许输入30个字)