Board logo

标题: linux驱动之内核定时器驱动设计 [打印本页]

作者: 苹果也疯狂    时间: 2015-7-27 22:02     标题: linux驱动之内核定时器驱动设计

定时器在linux内核中主要是采用一个结构体实现的。但是需要注意定时器是一个只运行一次的对象,也就是当一个定时器结束以后,还需要重现添加定时器。但是可以采用mod_timer()函数动态的改变定时器到达时间。这个驱动主要实现内核定时器的基本操作。内核定时器主要是是通过下面的结构体struct timer_list实现。需要的头文件包括#include,但是在实际开发过程中不需要包含该头文件,因为在sched.h中包含了该头文件。


定时器的实现主要是该结构体的填充和部分函数的配合即可完成。其中红色的部分是最主要的几个元素,1、expires主要是用来定义定时器到期的时间,通常采用jiffies这个全局变量和HZ这个全局变量配合设置该元素的值。比如expires = jiffies + n*HZ,其中jiffies是自启动以来的滴答数,HZ是一秒种的滴答数。
2、function可以知道是一个函数指针,该函数就是定时器的处理函数,类似我们在中断中的中断函数,其实定时器和中断有很大的相似性。定时器处理函数是自己定义的函数。
3、data通常是实现参数的传递,从function的参数类型可以知道,data可以作为定时器处理函数的参数。
其他的元素可以通过内核的函数来初始化。

初始化函数为:
init_timer(struct timer_list * timer);
或者直接DEFINE_TIMER宏实现定义和初始化操作。


添加定时器到内核的函数:


删除定时器函数,如果定时器的定时时间还没有到达,那么才可以删除定时器:
int del_timer(struct timer_list *timer)

修改定时器的到达时间,该函数的特点是,不管定时器是否到达时间,都会重现添加一个定时器到内核。所以可以在定时处理函数中可以调用该函数修改需要重新定义的到达时间。
int mode_timer(struct timer_list *timer,unsigned long expires)



从上面的分析可以看出,mod_timer的实现过程比较复杂,但是基本上说明了mod_timer函数重新注册定时器的操作过程。
一般而言定时器的基本操作主要是上面的几个函数。
我的基于内核定时器的驱动函数如下,参考了宋宝华的Linux设备驱动开发详解(第二版)。
驱动程序:


应用程序:


实验效果:
[root@EmbedSky Test]# ./app-timer                                               
Current jiffies is 2137721                                                      
second after open /dev/second0 : 1                                             
Current jiffies is 2137921                                                      
second after open /dev/second0 : 2                                             
Current jiffies is 2138121                                                      
second after open /dev/second0 : 3                                             
Current jiffies is 2138321                                                      
second after open /dev/second0 : 4                                             
Current jiffies is 2138521                                                      
second after open /dev/second0 : 5                                             
Current jiffies is 2138721                                                      
second after open /dev/second0 : 6   

以上的结果表明内核定时器基本实现了效果,但从实验结果看好像为每两秒实现一次显示。具体的原因还有待于再次分析,因为arm中的HZ应该为100,而不是200。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0