马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
在Linux装备驱动编程中,可以利用Linux内核中提供的一组函数和数据结构来完成定时触发工作或者完成某周期性的变乱。这组函数和数据结构使得驱动工程师在多数环境下不用关心具体的软件定时器毕竟对应着怎样的内核和硬件举动。
1.定时器结构体
- struct timer_list {
- /*
- * All fields that change during normal runtime grouped to the
- * same cacheline
- */
- struct hlist_node entry;
- unsigned long expires;
- void (*function)(struct timer_list *);
- u32 flags;
- #ifdef CONFIG_LOCKDEP
- struct lockdep_map lockdep_map;
- #endif
- };
复制代码 expires是定时器到期的时间(jiffies),定时器到期后function成员将被执行;
2. jiffies相关转换函数
- //jiffies 相当于时钟节拍
- //jiffies 转换为毫秒、微妙、纳秒
- unsigned int jiffies_to_msecs(const unsigned long j);
- unsigned int jiffies_to_usecs(const unsigned long j);
- unsigned int jiffies_to_nsecs(const unsigned long j);
- //毫秒、微妙、纳秒转换为jiffies
- unsigned long msecs_to_jiffies(const unsigned int m);
- unsigned long usecs_to_jiffies(const unsigned int u);
- unsigned long nsecs_to_jiffies(u64 n);
复制代码 3.定时器相关函数
- /**
- 初始化一个定时器
- timer为 struct timer_list 指针
- callback 为定时器周期函数
- flags 通常为0
- */
- #define timer_setup(timer, callback, flags) \
- __init_timer((timer), (callback), (flags))
- #define timer_setup_on_stack(timer, callback, flags) \
- __init_timer_on_stack((timer), (callback), (flags))
复制代码- //增加定时器
- //注册内核定时器,将定时器加入到内核动态定时器链表中
- void add_timer(struct timer_list * timer);
复制代码- //删除定时器
- int del_timer(struct timer_list * timer);
复制代码- //修改定时器,在周期函数中调用后,会自动重启定时器
- //修改定时器的到期时间,在新的被传入的expires到来后才会执行定时器函数
- int mod_timer(struct timer_list *timer, unsigned long expires);
复制代码 4.定时器编程示例
4.1Makefile
- KVERS = $(shell uname -r)
- # Kernel modules
- obj-m += hello.o
- # Specify flags for the module compilation.
- #EXTRA_CFLAGS=-g -O0
- build: kernel_modules
- kernel_modules:
- make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules
- clean:
- make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean
复制代码 4.2 源码
- #include <linux/module.h>
- #include <linux/fs.h>
- #include <linux/cdev.h>
- #include <linux/slab.h>
- #include <linux/uaccess.h>
- #include <asm/atomic.h>
- #include <linux/debugfs.h>
- #include <linux/mutex.h>
- #include <linux/spinlock.h>
- #include <linux/device.h>
- #include <linux/wait.h>
- #include <linux/sched/signal.h>
- #include <linux/poll.h>
- #include <linux/timer.h>
- struct mytimer_dev{
- struct timer_list my_timer;
- unsigned int cnt_timer;
- };
- struct mytimer_dev *pdev = NULL;
- void my_timer_function(struct timer_list *t)
- {
- struct mytimer_dev *dev;
- printk("In the my_timer_function\n");
- printk("the jiffies is :%ld\n", jiffies); //显示当前的节拍数
-
- dev = from_timer(dev, t, my_timer);//在这里从timer找到包含其的结构体首地址
- printk("my number is :%d\n", dev->cnt_timer);
- dev->cnt_timer++;
- mod_timer(t, msecs_to_jiffies(500));
- }
- static int __init mytimer_init(void)
- {
- pdev = kzalloc(sizeof(struct mytimer_dev), GFP_KERNEL);
- if(pdev == NULL){
- printk("kzalloc mem error\n");
- return -1;
- }
-
- pdev->cnt_timer = 0;
- pdev->my_timer.expires = jiffies + msecs_to_jiffies(500);
- timer_setup(&pdev->my_timer, my_timer_function, 0);//设置定时器
- add_timer(&pdev->my_timer);
-
- printk("mytimer_init ok\n");
- return 0;
- }
- static void __exit mytimer_exit(void)
- {
- del_timer(&pdev->my_timer);
- kfree(pdev);
- printk("mytimer_exit\n");
- }
- module_init(mytimer_init);
- module_exit(mytimer_exit);
- MODULE_AUTHOR("alex@xxxxxx.com");
- MODULE_LICENSE("GPL v2");
- MODULE_VERSION("V1.0");
- MODULE_ALIAS("mytimer");
- MODULE_DESCRIPTION("Timer Test");
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |