




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、-目 录中文摘要1ABSTRACT2第1章 Linu*概述31.1 Linu*操作系统的诞生和发行版31.1.1 Linu*系统的诞生31.1.2 Linu* 发行版31.2 Linu*应用和特性41.2.1 linu* 的应用41.2.2 linu* 的特性4第2章 Tiny210开发板62.1 Tiny210 简介62.2 Tiny210硬件配置62.3软件支持7第3章移植前准备83.1软件平台的搭建83.1.1 虚拟机的安装83.1.2 Red Hat linu* 的安装83.1.3 软件包和源码包的准备和下载8第4章 Linu* 核9第5章 RTC芯片105.1 RTC芯片简述105.
2、2I2C总线简介10第6章字符设备驱动相关知识116.1 模块机制116.2 字符设备开发根本步骤126.3 主设备号和次设备号126.4 实现字符驱动程序13第7章 RTC驱动实现167.1 设计思路167.2 RTC程序实现167.2.1 RTC根本数据构造16注册字符设备167.2.3 定义操作函数177.2.4 函数声明187.3编译生成.ko文件187.4 实际运行及结果18第8章 结论20辞21参考文献22附录A RTC驱动程序23附录B Makefile文件41附录C 应用层测试程序41. z-基于Linu*操作系统下RTC驱动开发摘 要:论文主要研究了Linu*系统下的RTC芯
3、片驱动架构,并设计了一个基于Tiny210开发板的RTC字符设备驱动。首先对Linu*体系进展了简单介绍,分析了Linu*系统的应用和特性,并对现有平台Tiny210开发板进展了简单分析。在对实际工程RTC驱动开发的分析设计的根底上,采用了以动态模块加载方式的字符设备驱动模型。在对RTC芯片各个模块的简单介绍中快速构建和开发了一个该芯片的驱动模型,实现了对硬件时间的读写、闹钟的设置功能。减少了开发的复杂性,缩短了开发时间,且具有很强的可扩展、可移植性。关键词:Linu*操作系统;Tiny210开发板;字符设备驱动;RTC芯片. z-Driver Development of Real Time
4、rClock(RTC) Based on Linu*Abstract:In this thesis, the RTC chip driver under Linu* system architecture and design of a development board based Tiny210 RTC character device drivers. First, a brief introduction Linu* system to analyze the application and features of Linu* systems, and e*isting platfor
5、ms Tiny210 development board for a simple analysis. On the basis of the actual project RTC-driven development of analysis and design, using a dynamic module loading character device driver model. Quickly build in RTC chip for each module in a brief and develop a model of the chip driver, the realiza
6、tion of hardware time to read and write, alarm setting function. Reducing the ple*ity of development and shorten the development time, and has a strong scalability, portability.Keywords: Linu* operating system;Tiny210 development board;Character device driver;RTC chip第1章 Linu*概述1.1 Linu*操作系统的诞生和发行版1
7、.1.1 Linu*系统的诞生1981年IBM推出了微型计算机IBM PC。在它推出的前10年,MS-DOS操作系统主宰了整个计算机操作系统界。而在当时,计算机硬件的价格在不断下跌,但软件仍处于高位。苹果的操作系统MacOS的是无疑是最好的性能,但价格高,没有人可以轻易接近。到1991年,随着GNU方案开发出来了一些工具,以及GNU C编译器的发布。甚至MINI*也因为开场需要购置才能获得源代码。在GNU HURD操作系统的开发工作却不是能在几年完成的。对于莱纳斯来说,已经等不及了。起初,他只是为了学习386架构的编程技术,但随后的Linu*开发过程已经彻底改变了他的主意。在1991年初,莱纳
8、斯在学习MINI*的操作系统的时候产生了开发一个新的属于自己的理想中的操作系统的想法。最早与Linu*当然此时还不叫Linu* 这个名称相关的新闻是莱纳斯在1991年7月3号的p.os.mini*上发布的消息。而在莱纳斯8 月25 日发布的消息中,他第一次向外界透露出有开发免费的操作系统的意向,可是它并不会象GNU 那种现在已经在行业中成型的系统那样专业,而代码量不会很大1。直到1991 年的10 月5 日,莱纳斯在p.os.mini* 新闻组上发布消息,正式向外宣布Linu* 核系统的诞生Free mini*-like kernel sources for 386-AT。这段消息就是直到今日
9、都广为流传的被称为Linu*的诞生宣言。因此对Linu* 社区,及其所用用户来说,10月5日都是一个特殊的日子。直到今天,包括现在的Red Hat公司在的很多公司都会在发布许多Linu* 的新版本时选择了这个日子。 Linu*是一种源于UNI*的操作系统,虽然从严格意义上讲,Linu*这个词实际上是指Linu*核,但实际上人们已经习惯了把整个基于Linu*核以及在此根底上的各种工具的操作系统统称为Linu*。1.1.2 Linu* 发行版通常来讲,一个Linu*的发行版不仅仅是指Linu*核,还包括了使用Linu*的软件的安装工具,以及各种工具软件,而在一些特定的版本中中也有一些特定软件,只不
10、过现在都习惯于把它们统称为Linu*发行版。每一种发行版的开发都是针对着不同的目标,像是支持不同计算机构造,更强调实时应用,和专门面向嵌入式系统等。主流的Linu*发型版有Ubuntu,Red Hat等等。1.2 Linu*应用和特性1.2.1 Linu* 的应用Linu*的根本思想就是万物皆文件,因此它拥有极高的灵活性和可移植性,再加上它的UNI*背景,使它Linu*在效劳器的操作系统方面具有广泛运用。直到现在,Linu*还是提供效劳供应商最常使用的平台。虽然因为新的编程语言的兴起,它的市场份额在不断减少,但在嵌入式行业,Linu*基于其低廉本钱与小体积依然是不可动摇的霸主,像在机顶盒、手机
11、及移动装置等硬件平台上,Linu*已经是不可或缺的3。1.2.2 Linu* 的特性 完全兼容 因为Linu*兼容了POSI*1.0标准,所以一些常见的Windows的程序完全可以在Linu*上无障碍运行,这也为用户从Windows转到Linu*提供了方便。因为现在Windows的巨大影响力,许多用户在使用Linu*前,都会因为以前Windows的使用习惯而担忧能否适应新的环境,而这一点就使他们不在顾虑。 完全免费,开展迅速 Linu*是一款完全免费的操作系统。因为Linu*社区的存在,所有的Linu*用户都可以轻易的得到当前任意版本的Linu*的源代码,并按照自己的意愿来修改它。正是由于这一
12、点,每时每刻,每一次的技术进步,每一种新平台面世,都有来自世界各地的精英都参与了Linu*的更新和实现,无数的灵感跟不断进步的技术与编程思想,让Linu*有了无穷的可能性,并在无数程序员的努力下不断壮大。 多用户、多任务 正如当今世界开展的主流那样,Linu*也支持多用户。这保证了各用户的相对独立,之间互不影响,都对于自己的文件设备有自己的权利。而多任务则是现在各种智能设备的主要特点,为了节省运行时间和解放更多的系统资源,实现了多进程的并行执行,Linu*操作系统就是其中的典。 良好的界面因为现在Windows系统的强烈影响,Linu*同时具有可以通过键盘输入相应的指令来进展操作的字符界面和类
13、似Windows图形界面的*-Window系统提供的图形界面。后者使用户可以类似于Windows操作系统使用鼠标对其进展操作,而不会因为转换了操作系统感到不适应。 丰富的网络功能Uni*最大的优势就是其强大的网络功能,而从Uni*衍生出来的Linu*系统也继承了它在网络功能上的优势。Linu*的网络功能和其核严密相连,在这方面它要比其他操作系统更有优势。 可靠的平安、稳定性能Linu*采取了许多平安技术措施为部信息平安提供了保障。而且Linu*的极高的稳定性使它在对要应用到网络效劳器这类有较高稳定性要求的效劳上有非常高的适应性。 支持多种平台Linu*作为一种嵌入式操作系统,在各种移动装置上应
14、用广泛。Linu*因为其开源的特性使它根本可以在市场上绝大局部的硬件平台上运行,这也使它精简体积小的核可以方便地移植多种嵌入式处理器上。. z-第2章 Tiny210开发板2.1 Tiny210 简介Tiny210是一款高性能的Corte* A8核心板,它由友善之臂设计、生产和发行销售。它采用三星S5PV210作为主处理器,运行主频可高达1GHz。S5PV210部集成了PowerVR SG*540高性能图形引擎,支持3D图形流畅运行,并可流畅播放1080P大尺寸视频4。Tiny210主要采用了2.0mm间距的双排针,引出CPU大局部常用功能引脚,并力求和Tiny6410核心板三排引脚兼容(P1
15、,P2,CON2)5。2.2 Tiny210硬件配置如图2-1:2.3 软件支持Superboot-210Android 4.0WindowsCE6第3章 移植前准备3.1软件平台的搭建3.1.1 虚拟机的安装在有了硬件平台的支持下Tiny210开发板开场进展软件平台的搭建。在pc机上安装一个虚拟机,本文选用的虚拟机是VMware Workstation 。虚拟机其实就是在主机中占用一块存在主机的硬件平台上搭建一个类似主机的运行环境,在 VMware中,你可以在一个以主机的分割的存为根底的窗口中加载一台虚拟机,运行自己的操作系统和应用程序,而不影响主机任何操作。3.1.2 Red Hat Li
16、nu* 的安装在安装了Vmware Workstation 的条件下,创立一个虚拟机给它分配20G的磁盘大小。512M的存空间。然后从网上下载Red Hat Linu* 操作系统安装包iso文件,我下载的是Red Hat Linu*-5的iso文件,该版本的Linu*核时3.0的,相对来说是版本比较高的核。在获得Red Hat的iso文件后,在创立的虚拟机中安装该Linu*操作系统。3.1.3 软件包和源码包的准备和下载需要的软件有穿插编译器arm-Linu*-gcc ,我选用的穿插编译器为Tiny210的开发自带的穿插编译器,该编译器是4.0版本以上的,正是由于我即将下载核源码版本比较高,因
17、此我们选用的穿插编译器的版本也是相对来说比较高的。从.下载Linu*的核源代码linu*-3.0.8.tar.gzRTC 。Boot Loader 是在硬件平台运行之前完成对硬件的初始化病唤醒操作系统的程序。就是通过Boot Loader来实现初始化硬件设备,从而给操作系统提供了一个适宜的软硬件环境,并为调用它做好准备。我选择的Boot Loader是U_boot6。第4章 Linu* 核现在自己的当前目录,即目录下,解压自己的核源代码: tar *vzf linu*-3.0.8.tgz解压Linu*核源码包,在当前目录下生成一相应的文件夹linu*-3.0.8,这就是该核
18、的所有实现代码。Linu*的核的目录包含很多个文件夹,分别用于实现不同的功能如图4-17。假设相对于Linu*-3.0.8:图4-1 Linu*根目录 其中有几个比较重要的需要着重了解:/drivers 驱动目录,该目录是所有被加载到核的设备驱动的程序。其中又把设备驱动进一步划分成几类,如字符设备驱动,块设备驱动等。/include 该目录包括编译核心所需要的大局部头文件,也是Linu*下程序编译的查找默认路径。/net 该目录里不用说就是核心的网络层代码。/init 该目录中包含核的所有硬件初始化代码,这是核所有工作的起点,像是main.c和Version.c这两个C语言程序的编译入口文件就
19、在其中,同时也是是所有进程的最初父进程。 /kernel 该核管理的核心代码放在这里,也就是通常所说的核的具体实现,一般除了核裁剪都不需要对它进展操作。/documentation 该目录下是对每个目录作用的具体说明的文档以及一些功能的实例,就相当于产品说明书。/ipc 该目录包含了核心进程间的通信代码,是Linu*多任务特性具体实现。/lib 该目录是编译默认路径,包含了核绝大局部的库文件与代码。 /modules 该目录存放了已建好的、可动态加载的模块,裁剪核的主要工作目标。第5章 RTC芯片5.1 RTC芯片简述 RTC(real time clock)实时时钟,顾名思义,拥有真实时间的
20、时钟,其实它的主要作用就是在操作系统没有工作的时候自主维护时间表,并在需要的时候给操作系统提供系统时间。开发板的时间系统可以分成两种,分别是系统时间和硬件时间。硬件时间指的就是RTC芯片自主维护的时间,因为RTC芯片是电池供电的,所以在硬件平台掉电后时间表不会丧失。Linu*核就把RTC芯片当作“离线的时间与日期维护器。当Linu*核启动时,都要通过RTC来进展初始化,从RTC中读取时间保存到系统中,得到系统时间。而在运行期间,核以软件的形式维护系统的当前时间与日期,并在关机或必要的时候将时间回写RTC芯片,由它自主维护。另外如果RTC拥有了IRQ中断并且可以定时,则RTC还可以作为一个闹钟用
21、来在核睡眠时唤醒核。Linu*有两种RTC驱动的接口,一个是老的接口,专门用在PC机上的。另外一钟新接口是基于Linu*设备驱动程序的。而后者创立了一个RTC驱动模型,并注册到RTC核心中,把所有工作交由RTC芯片完成。5.2 I2C总线简介I2C总线是一种由Philips公司开发的两线式串行总线标准,用于微控制器及其外围设备。I2C有100K和400K两种工作速率,它支持多机通讯和多主控模块设计,并且每个电路模块都有唯一的地址,还允许每个在I2C总线上的期间都可以使用独立的电源。本文就是介绍基于I2C总线的Linu*字符设备驱动。I2C由数据线SDA和时钟线SCL构成的同步串行总线,可发送和
22、承受数据,在处理器与控制芯片之间、芯片与芯片之间进展双向传送8。I2C总线在传送数据过程中共有三种类型信号,它们分别是开场信号、完毕信号和应答信号9。第6章 字符设备驱动相关知识6.1模块机制Linu*提供了一种被称为模块Module的机制提供了对许多模块支持,设备驱动每个模块由不同代码组成,实现不同功能10所有的模块在一起才是一个可执行程序。insmod 将模块动态加载到正在运行核;rmmod 程序移除模块;Linu*核模块的程序构造:module_init()加载模块函数必须 使用insmod命令加载模块时,核就会执行该模块的加载函数,也就是说这就是整个模块函数的入口,就是通过它来完成模块
23、的初始化相关工作。module_e*it()卸载模块函数必须 当使用rmmod命令卸载*模块时,核就会执行该这段函数,完成对模块的删除和空间的释放。MODULE_LICENSE()模块许可证声明必须这一段函数就是描述核将要加载的模块的工作权限,如果在加载模块时不声明LICENSE,核就会报警:kernel tainted,意思就是核被污染。module_param()模块参数可选 这个函数括号放置着模块部声明的全局变量,对应着在加载模块时rommod命令后面跟着的参数,这些参数就会被传入模块。E*PORT_SYMBOL()模块导出符号可选 这个函数括号也放置着数量不等参数,也就是符号可以是函数
24、或变量,而在这个模块完毕之后,其他模块就可以通过这个符号使用本模块中这些到处的参数,变量或函数。其他一些声明MODULE_*()模块声明可选不同的声明对应着不同的功能选项,视实际情况而定。模块加载函数:static int _init initialization_rtc(void) /* 初始化代码 */module_init(initialization_rtc); 模块卸载函数static void _e*it cleanup_rtc(void) /* 释放资源 */module_e*it(cleanup_rtc); 6.2字符设备开发根本步骤 向核确定主该设备的主次设备号实现字符驱动程
25、序: 填充file_operations构造体 实现模块加载函数用以注册字符设备 实现模块卸载函数完成模块的释放和删除创立设备文件节点6.3主、次设备号11主设备号是核识别一个设备的标识。整数(占12bits),围从0到4095,通常使用1到255。次设备号由核使用,用于正确确定设备文件所指的设备。整数(占20bits),围从0到1048575,一般使用0到255。设备编号的部表达 dev_t类型(32位,其中主设备号12位,次设备号20位): 是属于Linu*核编程的专有类型,用来保存设备编号。 从dev_t类型变量中获得主设备号和次设备号:这是两个封装好的函数MAJOR(dev_t rtc
26、);/获得主设备号MINOR(dev_t rtc);/获得次设备号 将主设备号和次设备号转换成dev_t类型:这也是一个封装好的函数dev_t =MKDEV(int ,int ); 分配主设备号 手工分配主设备号的函数:*include <linu*/fs.h> /这是Linu*核中有关设备号的头文件int register_chrdev_region( dev_t num, unsigned int , char *rtc );这是自己手动把num分配给rtc作为主设备号。动态分配主设备号:*include <linu*/fs.h> /这是Linu*核中有关设备号的头
27、文件int alloc_chrdev_resion(dev_t *,unsigned int ,unsigned int ,char *rtc);这是核自动分配一个设备好给rtc。释放设备号void unregister_chrdev(dev_t, unsigned int );在该设备号不再使用之后,释放并删除它,以节约核资源。6.4实现字符驱动程序实现字符设备驱动,最重要的就是字符设备构造体cdev,以及驱动接口构造体-file_operations。cdev 构造体struct cdev struct kobject *; /* 核嵌的对象 */ struct module *; /*所
28、属模块*/ struct file_operations *; /*文件操作构造体*/ struct list_head *; /*不常用*/ dev_t *; /*设备号*/ unsigned int *; /*不常用*/ ;file_operations 构造体字符驱动和核的接口:在核代码中,./include/linu*/fs.h下的代码实现,定义了字符驱动程序只要填充一个file_operations构造体并把它注册到核中,核就有了通过它操作这个字符设备的能力。file_operations的主要成员:struct module *: 指向模块本身open: 提供翻开设备的函数接口;r
29、elease:提供关闭设备的函数接口;read: 实现从设备上读取数据的函数接口;write: 实现向设备上写入数据的函数接口;ioctl: I/O控制函数;llseek: 定位读写指针位置并把他们输出出来;ioctl函数为设备驱动程序执行用户空间的“命令提供了一个特有的接口用来设置或者读取设备的具体信息。cmd 参数的定义Linu*核对file_operations的ioctl()函数的cmd参数有特殊的定义:如图6-1。图6-1 cmd参数构造命令编号的宏:_IO() 给没有参数的命令;_IOR() 给从驱动中读数据的命令;_IOW() 给写入数据的命令;_IOWR() 用于双向传输。Io
30、ctl函数模板static long rtc_dev_ioctl(struct file *file,unsigned int cmd, unsigned long arg).switch (cmd) case RTC_EPOCH_SET:.Break;case RTC_SET_TIME:.break;case RTC_IRQP_SET:.break;case RTC_PIE_ON:.break;.图6-2 字符设备驱动 第7章 RTC驱动实现7.1 设计思路Linu*设备驱动属于核的一局部,Linu*核的驱动模块可以用两种不同的方式加载和编译: 通过核裁剪,随同Linu*的启动直接加载编译进
31、Linu*核; 把驱动程序编译成一个可加载和删除的动态模块,可以在需要时随时使用insmod命令加载,rmmod命令删除。这种方式更快,也节省了核资源,控制了核的大小,而模块一旦被插入核,就和其他被直接初始化到核中的模块一样了。这次的RTC驱动就采用动态模块加载的方式,将程序主体分成3个局部。分别是注册字符设备的class.c,定义操作函数的dev.c和提供接口说明的ioctl.c。7.2 RTC程序实现7.2.1 RTC根本数据构造struct rtc_time 构造体struct rtc_time int sec;int min;int h
32、our;int mday;int mon;int year;int wday;int yday;int isdst;这个构造体代表了硬件时间与日期,从RTC芯片读取的时间和日期就分开保存在这个构造体中7.2.2注册字符设备模块初始化函数: init_rtc static int _init init_rtc(void) rtc_class = class_create(THIS_MO
33、DULE, "rtc"); int err;err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MA*, "rtc"); rtc_dev_init(); rtc_sysfs_init(rtc_class); if (err < 0)printk(KERN_ERR "%s: failed to allocate char
34、dev regionn",_FILE_); return 0; Init_rtc首先创立了一个类rtc12。类本身就是一个高度面向对象的产物,而用户空间就可以在不知道如何实现的情况下直接得到结果,驱动程序也不用直接处理,只要调用就行了。7.2.3 定义操作函数 dev.c 填充了file_operations构造rtc_foperations,以及这些操作函数的具体实现。rtc_foperations- rtc根本的文件操作:
35、0;static const struct file_operations rtc_foperations = .owner = THIS_MODULE, .llseek = null, .read = read,
36、60;.poll = poll, .unlocked_ioctl = ioctl, .open = openfile, .release = release, .fasync = fa
37、sync, 7.2.4 函数声明ioctl.c里的所有函数的实现都对应于dev.c 中rtc_ioctl相应的命令,其中RTC_RD_TIME与RTC_SET_TIME两个命令需要特别注意,这是RTC最根本的功能函数获取时间和设置时间。7.3 运行步骤通过编写的Makefile及arm-linu*-gcc编译生成rtc.ko文件,如图7-1。图7-1 编译生成.ko文件编写用户层测试程序,并编译成可执行程序qq。7.4 实际运行及结果将生成的.ko模块和应用层测试程序qq下载的目标板,运行过程如图7-2:用insmod装载模板。创立设备
38、节点: mknod /dev/rtc c 250 0修改执行程序权限: chmod 777 qq执行测试程序。图7-2 运行过程结果如图7-3:图7-3 运行结果第8章 结论本论文中对Linu*的开展跟现状进展了了解,还在对课题基于Linu*操作系统下RTC驱动开发的根底上对Linu*核进展了大致的分析,并在课题最后进展了相对于RTC驱动模块的应用层测试软件的编写。在本文中嵌入式系统选择的是Linu*系统,它具有占有存小和运行速率高的优点。并采用了模块化的指导设计方法开发设备驱动,提高了程序的可读性和可移植性。本文将字符设备分为了设备注册、函数功能实现以及调用接口,并对程序进展了应用层的实例验
39、证。由于时间的原因,本文中RTC字符驱动的程序设计还是有些简单,在以后的学习工作中还需要进一步改善。在以后对驱动的学习中,希望能够不断完善RTC芯片的功能实现,并在在嵌入式Linu*操作系统的建立中,以核剪裁的方式将驱动程序移植到Linu*核中去,努力做出更为精简稳定的核系统。 辞首先,向我的指导教师教师和教师表示感,感教师们一直以来对我的关心和悉心指导,并在完成毕业设计的过程中让我体会到了也学到了很多。在整个毕业设计指导活动中,教师的丰富经历和对整个行业脉络的把握,都是年轻的我难以望其项背的,并在整个课题的完成过程中起到了至关重要的作用。教师教学作风的和教师的治学风格都让我留下了很深的印象。
40、 同时也要感培训班的所有同学,在临近毕业的培训过程中,对我的关心和帮助。感他们不厌其烦地指导我解决了不少工程上的难题,她们积极向上的学习态度也是我奋斗下去的动力。感我的亲人,在这四年里是他们给我无数的鼓励、支持和帮助,正因为有他们我才能快乐顺利的完成大学学业,并学到了很多专业,以及很多人生道路上的珍贵财富。 最后感各位评阅教师在百忙之中抽空评阅我的论文。. z-参 考 文 献1*俊仕.基于嵌入式Linu*的车载GPS导航系统设计与实现D:西北工业大学机械电子工程学院,2007.2戴明华,长云,曾志浩,海燕. 嵌入式Linu*驱动程序框架研究综述J. 大学学报,2021,02:52-53.3 方
41、先康.基于powerpc处理器MPC8541E的嵌入式Linu*系统开发D:邮电大学计算机科学与技术学院,2021.4 利平.基于MPC8536的雷达嵌入式数据处理平台设计D.:中国西南电子技术研究所,2021.5 罗泽勇.一种基于powerpc的嵌入式信号处理平台的设计D.:电子科技大学,2021.6董文军. Linu*驱动程序兼容性的相关问题J.单片机与嵌入式系统应用,2021,03:16-18.7 董闯.基于MPC85*的U-boot启动流程分析和移植D,:邮电大学,2021.8 周立功,明计,渝ARM嵌入式Linu*系统构建与驱动开发例M:航空航天大学,2006.9王淑贞U-Boot在
42、S3C2410上的移植J.微计算机应用,2021,29(4):95-97.10LTIB user manual Linu* Target Image Builder,Freescale,2006.11 史胜辉.基于嵌入式Linu*的频谱分析仪软件系统设计D.:电子科技大学,2021.12 MPC8536 datasheet MPC8536E PowerQUICC III tm Integrated Processor Product Brief ,2021.附录A RTC驱动程序Class.c*include <linu*/module.h>*include <linu*/r
43、tc.h>*include <linu*/kdev_t.h>*include <linu*/idr.h>*include <linu*/slab.h>*include <linu*/workqueue.h>*include "rtc-core.h"static DEFINE_IDR(rtc_idr);static DEFINE_MUTE*(idr_lock);struct class *rtc_class;static void rtc_device_release(struct device *dev)struct r
44、tc_device *rtc = to_rtc_device(dev);mute*_lock(&idr_lock);idr_remove(&rtc_idr, rtc->id);mute*_unlock(&idr_lock);kfree(rtc);*if defined(CONFIG_PM) && defined(CONFIG_RTC_HCTOSYS_DEVICE)static struct timespec old_rtc, old_system, old_delta;static int rtc_suspend(struct device *de
45、v, pm_message_t mesg)struct rtc_device*rtc = to_rtc_device(dev);struct rtc_timetm;struct timespecdelta, delta_delta;if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)return 0;delta = timespec_sub(old_system, old_rtc);delta_delta = timespec_sub(delta, old_delta);if (delta_delta.t
46、v_sec < -2 | delta_delta.tv_sec >= 2) old_delta = delta; else old_system = timespec_sub(old_system, delta_delta);return 0;static int rtc_resume(struct device *dev)struct rtc_device*rtc = to_rtc_device(dev);struct rtc_timetm;struct timespecnew_system, new_rtc;struct timespecsleep_time;if (strcm
47、p(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)return 0;getnstimeofday(&new_system);rtc_read_time(rtc, &tm);if (rtc_valid_tm(&tm) != 0) pr_debug("%s: bogus resume timen", dev_name(&rtc->dev);return 0;rtc_tm_to_time(&tm, &new_rtc.tv_sec);new_rtc.tv_
48、nsec = 0;if (new_rtc.tv_sec < old_rtc.tv_sec) pr_debug("%s: time travel!n", dev_name(&rtc->dev);return 0;sleep_time = timespec_sub(new_rtc, old_rtc);sleep_time = timespec_sub(sleep_time,timespec_sub(new_system, old_system);if (sleep_time.tv_sec >= 0)timekeeping_inject_sleeptim
49、e(&sleep_time);return 0;*else*define rtc_suspendNULL*define rtc_resumeNULL*endifstruct rtc_device *rtc_device_register(const char *name, struct device *dev,const struct rtc_class_ops *ops,struct module *owner)struct rtc_device *rtc;struct rtc_wkalrm alrm;int id, err;if (idr_pre_get(&rtc_idr,
50、 GFP_KERNEL) = 0) err = -ENOMEM;goto e*it;mute*_lock(&idr_lock);err = idr_get_new(&rtc_idr, NULL, &id);mute*_unlock(&idr_lock);if (err < 0)goto e*it;id = id & MA*_ID_MASK;rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL);if (rtc = NULL) err = -ENOMEM;goto e*it_idr;rtc->i
51、d = id;rtc->ops = ops;rtc->owner = owner;rtc->irq_freq = 1;rtc->ma*_user_freq = 64;rtc->dev.parent = dev;rtc->dev.class = rtc_class;rtc->dev.release = rtc_device_release;mute*_init(&rtc->ops_lock);spin_lock_init(&rtc->irq_lock);spin_lock_init(&rtc->irq_task_
52、lock);init_waitqueue_head(&rtc->irq_queue);timerqueue_init_head(&rtc->timerqueue);INIT_WORK(&rtc->irqwork, rtc_timer_do_work);rtc_timer_init(&rtc->aie_timer, rtc_aie_update_irq, (void *)rtc);rtc_timer_init(&rtc->uie_rtctimer, rtc_uie_update_irq, (void *)rtc);hrtime
53、r_init(&rtc->pie_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);rtc->pie_timer.function = rtc_pie_update_irq;rtc->pie_enabled = 0;err = _rtc_read_alarm(rtc, &alrm);if (!err && !rtc_valid_tm(&alrm.time)rtc_initialize_alarm(rtc, &alrm);strlcpy(rtc->name, name, RTC_DEVICE
54、_NAME_SIZE);dev_set_name(&rtc->dev, "rtc%d", id);rtc_dev_prepare(rtc);err = device_register(&rtc->dev);if (err) put_device(&rtc->dev);goto e*it_kfree;rtc_dev_add_device(rtc);rtc_sysfs_add_device(rtc);rtc_proc_add_device(rtc);dev_info(dev, "rtc core: registered %s
55、as %sn",rtc->name, dev_name(&rtc->dev);return rtc;e*it_kfree:kfree(rtc);e*it_idr:mute*_lock(&idr_lock);idr_remove(&rtc_idr, id);mute*_unlock(&idr_lock);e*it:dev_err(dev, "rtc core: unable to register %s, err = %dn",name, err);return ERR_PTR(err);E*PORT_SYMBOL_GPL
56、(rtc_device_register);void rtc_device_unregister(struct rtc_device *rtc)if (get_device(&rtc->dev) != NULL) mute*_lock(&rtc->ops_lock);rtc_sysfs_del_device(rtc);rtc_dev_del_device(rtc);rtc_proc_del_device(rtc);device_unregister(&rtc->dev);rtc->ops = NULL;mute*_unlock(&rtc-
57、>ops_lock);put_device(&rtc->dev);E*PORT_SYMBOL_GPL(rtc_device_unregister);static int _init rtc_init(void)rtc_class = class_create(THIS_MODULE, "rtc");if (IS_ERR(rtc_class) printk(KERN_ERR "%s: couldn't create classn", _FILE_);return PTR_ERR(rtc_class);rtc_class->suspend = rtc_suspend;rtc_class->resume = rtc_resume;rtc_dev_init();rtc_sysfs_init(rtc_class);return 0;static void _e*it rtc_e*it(void)rtc_dev_e*it();class_destroy(rtc_class);idr_des
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 家庭暴力防范安全教育计划
- 夫妻忠诚保障与子女社会实践教育合同
- 亲子早教中心师资培训与派遣合作协议
- 基于核心素养的河南省中考数学试题研究
- 婚礼现场特效与无人机航拍服务合同
- 动画电影角色形象授权及影视改编合同
- 茶碱-异烟酰胺共晶的制备及研究
- 企业电商直播场地布置与直播效果优化合同
- 景观叙事视角下乡镇工业特色小镇景观更新设计-以双峰永丰镇农机小镇示范园为例
- 景区水上乐园委托经营与管理合同
- CNAS-GL040-2019 仪器验证实施指南
- 《中医基础理论》课件-肝的生理功能
- 地质勘查合作协议
- 《声光影的内心感动:电影视听语言》期末考试
- 芯粒互联系统集成与标准化研究-洞察分析
- 2025年中国对外文化集团公司招聘笔试参考题库含答案解析
- 《无人机搭载红外热像设备检测建筑外墙及屋面作业》
- 2025年5月日历表(含农历-周数-方便记事备忘)
- KTV服务礼仪培训
- 与其他专业施工单位的交叉施工及配合协调措施及成品保护措施
- 煤矿测量新手培训课件
评论
0/150
提交评论