Linux下的hrtimer高精度定时器【转】
转自:http://blog.csdn.net/waverider2012/article/details/38305785
hrtimer高精度定时器的interval由ktime_set(const long secs, const unsigned long nsecs)决定,可做到ns级。此处的例子为5ms interval:
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/hrtimer.h>
- #include <linux/ktime.h>
- MODULE_LICENSE("GPL");
- static struct hrtimer hr_timer;
- static struct work_struct wq_hrtimer;
- static ktime_t ktime;
- static unsigned int interval=5000; /* unit: us */
- struct timespec uptimeLast;
- static unsigned int count=0;
- #define COUNT_INTERVAL 4000
- unsigned long long diff_tv(struct timespec start, struct timespec end) {
- return (end.tv_sec-start.tv_sec)*1000000000+(end.tv_nsec-start.tv_nsec);
- }
- enum hrtimer_restart my_hrtimer_callback( struct hrtimer *timer )
- {
- schedule_work(&wq_hrtimer);
- return HRTIMER_NORESTART;
- }
- static void wq_func_hrtimer(struct work_struct *work)
- {
- struct timespec uptime;
- hr_timer.function = my_hrtimer_callback;
- ktime = ktime_set( interval/1000000, (interval%1000000)*1000 );
- hrtimer_start(&hr_timer, ktime, HRTIMER_MODE_REL );
- /* print time every COUNT_INTERVAL*interval second*/
- if(count%COUNT_INTERVAL==0)
- {
- do_posix_clock_monotonic_gettime(&uptime);
- printk(KERN_INFO"hrtimer:%9lu sec, %9lu ns, interval_delay=%lu ns\n",
- (unsigned long) uptime.tv_sec, uptime.tv_nsec,
- (unsigned long)(diff_tv(uptimeLast, uptime)-interval*1000*COUNT_INTERVAL) \
- /COUNT_INTERVAL);
- uptimeLast=uptime;
- }
- count++;
- }
- static int __init module_hrtimer_init( void )
- {
- struct timespec uptime;
- printk(KERN_INFO"HR Timer module installing\n");
- hrtimer_init( &hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
- ktime = ktime_set( interval/1000000, (interval%1000000)*1000 );
- hr_timer.function = my_hrtimer_callback;
- hrtimer_start( &hr_timer, ktime, HRTIMER_MODE_REL );
- do_posix_clock_monotonic_gettime(&uptime);
- uptimeLast = uptime;
- printk(KERN_INFO"hrtimer:%9lu sec, %9lu ns\n", (unsigned long) uptime.tv_sec,
- uptime.tv_nsec );
- INIT_WORK(&wq_hrtimer, wq_func_hrtimer);
- return 0;
- }
- static void __exit module_hrtimer_exit( void )
- {
- int ret;
- ret = hrtimer_cancel( &hr_timer );
- if (ret)
- printk("The timer was still in use...\n");
- printk("HR Timer module uninstalling\n");
- return;
- }
- module_init(module_hrtimer_init);
- module_exit(module_hrtimer_exit);
如果在my_hrtimer_callback()里面直接返回HRTIMER_RESTART会导致立即重新进入my_hrtimer_callback()。这时shell对输入没有任何响应。
所以为了解决这个问题,创建了一个work queue,由my_hrtimer_callback() enqueue这个工作队列。在work queue的处理函数里面重启hrtimer。
但是这样带来的负面影响是进入hrtimer_callback和wq_func被调用之间有Linux系统调度引入的延迟,导致interval出现误差。经过实测,在ZC706缺省配置下,这个延迟大约是17.5us (hrtimer interval为5ms,每20秒计算一次interval误差)。
- root@zynq:~/nfs/hrtimer# insmod hrtimer.ko
- HR Timer module installing
- hrtimer: 2900 sec, 993366078 ns
- hrtimer: 2900 sec, 998395278 ns, interval_delay=369966 ns
- hrtimer: 2921 sec, 69525447 ns, interval_delay=17782 ns
- hrtimer: 2941 sec, 139764655 ns, interval_delay=17559 ns
- hrtimer: 2961 sec, 210029519 ns, interval_delay=17566 ns
- hrtimer: 2981 sec, 280465631 ns, interval_delay=17609 ns
- hrtimer: 3001 sec, 350677038 ns, interval_delay=17552 ns
- hrtimer: 3021 sec, 420625114 ns, interval_delay=17487 ns
- hrtimer: 3041 sec, 490744847 ns, interval_delay=17529 ns
Linux下的hrtimer高精度定时器【转】的更多相关文章
- linux下jiffies定时器和hrtimer高精度定时器【转】
本文转载自:http://blog.csdn.net/dosculler/article/details/7932315 一.jiffies定时器,HZ=100,精度只能达到10ms. 注:采用jif ...
- 使用linux内核hrtimer高精度定时器实现GPIO口模拟PWM,【原创】
关键词:Android linux hrtimer 蜂鸣器 等待队列 信号量 字符设备 平台信息:内核:linux3.4.39 系统:android/android5.1平台:S5P4418 作 ...
- Linux下的微秒级定时器: usleep, nanosleep, select, pselect
Linux下的微秒级定时器: usleep, nanosleep, select, pselect 标签: linuxnulldelaystructdate 2012-02-07 23:29 4979 ...
- hrtimer高精度定时器的简单使用【学习笔记】
#include <linux/module.h> #include <linux/kernel.h> #include <linux/hrtimer.h> #in ...
- 高精度定时器实现 z
1背景Permalink .NET Framework 提供了四种定时器,然而其精度都不高(一般情况下 15ms 左右),难以满足一些场景下的需求. 在进行媒体播放.绘制动画.性能分析以及和硬件交互时 ...
- Linux时间子系统之六:高精度定时器(HRTIMER)的原理和实现
转自:http://blog.csdn.net/droidphone/article/details/8074892 上一篇文章,我介绍了传统的低分辨率定时器的实现原理.而随着内核的不断演进,大牛们已 ...
- Linux下的定时器:alarm()与setitimer()
Linux下的定时器有两种,以下分别介绍: 1.alarm 如果不要求很精确的话,用alarm()和signal()就够了 unsigned int alarm(unsigned int second ...
- Linux下的定时器
以下摘自linux下的man文件:(man getitimer) #include <sys/time.h> int getitimer(int which, struct iti ...
- Linux下定时器
http://unix8.net/linux%E4%B8%8B%E5%AE%9A%E6%97%B6%E5%99%A8.html 一. 基础知识 1.时间类型.Linux下常用的时间类型有4个:time ...
随机推荐
- P3950部落冲突
题面 \(Solution:\) 法一:LCT裸题 又好想又好码,只不过常数太大. 法二:树链剖分 每次断边将该边权的值++,连边--,然后边权化点权(给儿子),询问就查询从x到y的路径上的边权和,树 ...
- Leetcode 674.最长递增序列
最长递增序列 给定一个未经排序的整数数组,找到最长且连续的的递增序列. 示例 1: 输入: [1,3,5,4,7] 输出: 3 解释: 最长连续递增序列是 [1,3,5], 长度为3. 尽管 [1,3 ...
- mysql 连接问题
用两个表(a_table.b_table),关联字段a_table.a_id和b_table.b_id来演示一下MySQL的内连接.外连接( 左(外)连接.右(外)连接.全(外)连接). MySQL版 ...
- Windows server 2012 R2开机进入cmd,关闭后黑屏问题
原因分析: 因为自己在卸载IIS的时候,不小心卸载了.net framework,系统没有了图形界面(由完整模式Full变为了核心模式core),需要重新恢复.net framework4.5. 解决 ...
- java--List转换成json格式
方法一 首先导入jar包,json-rpc-1.0.jar public class List2Json { public static JSONArray ProLogList2Json(List& ...
- ps aux 和ps -aux和 ps -ef的选择
转载自:足至迹留 Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想 ...
- Struts1文件上传
package org.zln.struts.domain; import org.apache.struts.upload.FormFile; /** * Created by sherry on ...
- AGC017C Snuke and Spells(巧妙的线段覆盖模型)
题目大意: 给出n个球,每个球上都有数字,然后每次都进行如下操作 如果当前的球总共有k个,那么就把球上数字为k的所有球都消除掉 注意到,并不是每种情况都可以全部消光,所以你可以选择若干球,把它们标号改 ...
- c# 以多个字符串分隔字符串数据 分组 分隔 split 正则分组
string str="aaa[##]ccc[##]ddd[##]bb" Regex regex=new Regex("[##]");//以 [##] 分割 s ...
- CF762E Radio Stations
题目戳这里. 我还以为是KDtree呢,但是KDtree应该也可以做吧. 这是一道数据结构好题.考虑到由于\(K \le 10\),所以我们用两个大vector--\(Left,Right\),\(L ...