定时器是一个很长用的一个功能,需要周期性处理的工作都要用到定时器。在使用内核定时器的时候需要注意一点,内核定时器并不是周期性运行的,超时以后就会关闭,因此想要周期性定时,就需要重启定时器。
jiffes
Linux内核使用全局变量jiffies记录系统从启动以来的系统节拍数,系统启动时,Jiffies会初始化为0。 jiffies_64用于64位系统,jiffies用于32位系统,jiffies就是jiffies_64的低32位,不管在32位还是64位系统都可以使用jiffies。
要使用内核定时器首先需要定义一个timer_list结构体。
struct timer_list timer; /* 定义一个定时器*/
1,当定义完结构体变量之后需要对结构体进行初始化
init_timer(&timerdev.timer);
2,启动定时器,需要向内核注册,注册完成之后就会定时器,但是只会启动一次
//加载之前需要将timer结构体里面的数据进行设置
//定义定时去处理函数,需要处理的数据放在处理函数里面,例如点灯
timer.function = timer_func
//传递给函数的数据,通常是设备的结构体,比如设置引脚高低电平
timer.data = (unsigned long)&timerdev
//定时器的超时时间,2000ms也就是2s
timer.expires = jffies + msecs_to_jiffies(2000);
//这个定时器启动函数只能启动定时一次,启动之后就会关闭
add_timer(&timerdev.timer);
//删除定时器有两种方法
del_timer(&timer); 多处理器的时候也会删除其他处理的的定时器
del_timer_sync(&timer); 会等待其他定时器处理完再删除
3,当想要重复使用定时器的时候,需要重启定时器
//加载之前需要将timer结构体里面的数据进行设置
//定义定时去处理函数,需要处理的数据放在处理函数里面,例如点灯
timer.function = timer_func
//传递给函数的数据,通常是设备的结构体,比如设置引脚高低电平
timer.data = (unsigned long)&timerdev
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
//与上面的代码段区别就在这里了使用的函数不一样,且expries直接放在了函数体内,不用放在外部定义了
//第二个参数数就是expries,他会按照超时时间一直重启定时器,也就是会每次定时都会处理定时器函数
mod_timer(&dev->timer, jiffies + msecs_to_jiffies(dev->timeperiod));
有时候我们需要在内核中实现短延时,尤其在linux内核驱动中,内核提供了毫秒,微妙,和纳秒延时函数。
函数timer_unlocked_ioctl,对应应用程序ioctl,应用程序调用ioctl函数向驱动发送控制信息,此函数响应并执行。此函数有三个参数:filp,cmd 和 arg,其中 filp是对应的设备文件,cmd 是应用程序发送过来的命令信息,arg 是应用程序发送过来的参数,,一共有三种命令 CLOSE_CMD,OPEN_CMD 和 SETPERIOD_CMD,这三个命令分别为关 闭定时器、打开定时器、设置定时周期。
***只有在定时器函数里面定义mod_timer()才会一直刷新定时器,不然add_timer()和mod_timer()都只会开启一次定时器函数
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/13393.html