转自:http://blog.csdn.net/waverider2012/article/details/38305785

hrtimer高精度定时器的interval由ktime_set(const long secs, const unsigned long nsecs)决定,可做到ns级。此处的例子为5ms interval:

  1. #include <linux/kernel.h>
  2. #include <linux/module.h>
  3. #include <linux/hrtimer.h>
  4. #include <linux/ktime.h>
  5. MODULE_LICENSE("GPL");
  6. static struct hrtimer hr_timer;
  7. static struct work_struct wq_hrtimer;
  8. static ktime_t ktime;
  9. static unsigned int interval=5000; /* unit: us */
  10. struct timespec uptimeLast;
  11. static unsigned int count=0;
  12. #define COUNT_INTERVAL 4000
  13. unsigned long long diff_tv(struct timespec start, struct timespec end) {
  14. return (end.tv_sec-start.tv_sec)*1000000000+(end.tv_nsec-start.tv_nsec);
  15. }
  16. enum hrtimer_restart my_hrtimer_callback( struct hrtimer *timer )
  17. {
  18. schedule_work(&wq_hrtimer);
  19. return HRTIMER_NORESTART;
  20. }
  21. static void wq_func_hrtimer(struct work_struct *work)
  22. {
  23. struct timespec uptime;
  24. hr_timer.function = my_hrtimer_callback;
  25. ktime = ktime_set( interval/1000000, (interval%1000000)*1000 );
  26. hrtimer_start(&hr_timer, ktime, HRTIMER_MODE_REL );
  27. /* print time every COUNT_INTERVAL*interval second*/
  28. if(count%COUNT_INTERVAL==0)
  29. {
  30. do_posix_clock_monotonic_gettime(&uptime);
  31. printk(KERN_INFO"hrtimer:%9lu sec, %9lu ns, interval_delay=%lu ns\n",
  32. (unsigned long) uptime.tv_sec, uptime.tv_nsec,
  33. (unsigned long)(diff_tv(uptimeLast, uptime)-interval*1000*COUNT_INTERVAL) \
  34. /COUNT_INTERVAL);
  35. uptimeLast=uptime;
  36. }
  37. count++;
  38. }
  39. static int __init module_hrtimer_init( void )
  40. {
  41. struct timespec uptime;
  42. printk(KERN_INFO"HR Timer module installing\n");
  43. hrtimer_init( &hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
  44. ktime = ktime_set( interval/1000000, (interval%1000000)*1000 );
  45. hr_timer.function = my_hrtimer_callback;
  46. hrtimer_start( &hr_timer, ktime, HRTIMER_MODE_REL );
  47. do_posix_clock_monotonic_gettime(&uptime);
  48. uptimeLast = uptime;
  49. printk(KERN_INFO"hrtimer:%9lu sec, %9lu ns\n", (unsigned long) uptime.tv_sec,
  50. uptime.tv_nsec );
  51. INIT_WORK(&wq_hrtimer, wq_func_hrtimer);
  52. return 0;
  53. }
  54. static void __exit module_hrtimer_exit( void )
  55. {
  56. int ret;
  57. ret = hrtimer_cancel( &hr_timer );
  58. if (ret)
  59. printk("The timer was still in use...\n");
  60. printk("HR Timer module uninstalling\n");
  61. return;
  62. }
  63. module_init(module_hrtimer_init);
  64. 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误差)。

    1. root@zynq:~/nfs/hrtimer# insmod hrtimer.ko
    2. HR Timer module installing
    3. hrtimer:    2900 sec, 993366078 ns
    4. hrtimer:    2900 sec, 998395278 ns, interval_delay=369966 ns
    5. hrtimer:    2921 sec,  69525447 ns, interval_delay=17782 ns
    6. hrtimer:    2941 sec, 139764655 ns, interval_delay=17559 ns
    7. hrtimer:    2961 sec, 210029519 ns, interval_delay=17566 ns
    8. hrtimer:    2981 sec, 280465631 ns, interval_delay=17609 ns
    9. hrtimer:    3001 sec, 350677038 ns, interval_delay=17552 ns
    10. hrtimer:    3021 sec, 420625114 ns, interval_delay=17487 ns
    11. hrtimer:    3041 sec, 490744847 ns, interval_delay=17529 ns

Linux下的hrtimer高精度定时器【转】的更多相关文章

  1. linux下jiffies定时器和hrtimer高精度定时器【转】

    本文转载自:http://blog.csdn.net/dosculler/article/details/7932315 一.jiffies定时器,HZ=100,精度只能达到10ms. 注:采用jif ...

  2. 使用linux内核hrtimer高精度定时器实现GPIO口模拟PWM,【原创】

    关键词:Android  linux hrtimer 蜂鸣器  等待队列 信号量 字符设备 平台信息:内核:linux3.4.39 系统:android/android5.1平台:S5P4418  作 ...

  3. Linux下的微秒级定时器: usleep, nanosleep, select, pselect

    Linux下的微秒级定时器: usleep, nanosleep, select, pselect 标签: linuxnulldelaystructdate 2012-02-07 23:29 4979 ...

  4. hrtimer高精度定时器的简单使用【学习笔记】

    #include <linux/module.h> #include <linux/kernel.h> #include <linux/hrtimer.h> #in ...

  5. 高精度定时器实现 z

    1背景Permalink .NET Framework 提供了四种定时器,然而其精度都不高(一般情况下 15ms 左右),难以满足一些场景下的需求. 在进行媒体播放.绘制动画.性能分析以及和硬件交互时 ...

  6. Linux时间子系统之六:高精度定时器(HRTIMER)的原理和实现

    转自:http://blog.csdn.net/droidphone/article/details/8074892 上一篇文章,我介绍了传统的低分辨率定时器的实现原理.而随着内核的不断演进,大牛们已 ...

  7. Linux下的定时器:alarm()与setitimer()

    Linux下的定时器有两种,以下分别介绍: 1.alarm 如果不要求很精确的话,用alarm()和signal()就够了 unsigned int alarm(unsigned int second ...

  8. Linux下的定时器

    以下摘自linux下的man文件:(man  getitimer) #include  <sys/time.h> int  getitimer(int which,  struct iti ...

  9. Linux下定时器

    http://unix8.net/linux%E4%B8%8B%E5%AE%9A%E6%97%B6%E5%99%A8.html 一. 基础知识 1.时间类型.Linux下常用的时间类型有4个:time ...

随机推荐

  1. (原创)白话KMP算法(续)

    第二章:KMP改良算法 第一章里面我们讲完了KMP算法的next数组实现法,回忆一下其实最重要的内容无非就是一.理解 i 指针无用回溯的意义,二.理解 j 指针的定位和模式串中每个元素重复度的关系,三 ...

  2. mysql 连接问题

    用两个表(a_table.b_table),关联字段a_table.a_id和b_table.b_id来演示一下MySQL的内连接.外连接( 左(外)连接.右(外)连接.全(外)连接). MySQL版 ...

  3. 【Python】python函数每日一讲 - dir()

    最近确实是有些忙,刚过了年,积攒了很多事情需要处理,所以每日一函数只能是每两天更新一篇,在这里和大家致歉. 今天我们来看一个非常重要的函数:dir() 中文说明:不带参数时,返回当前范围内的变量.方法 ...

  4. XML序列化器读取XML数据

    PS:标题我还真的不知道该怎么取比较好,大家将就下吧^_^ 场景:上周接到一个任务,要求我把ASP写的会员充值功能,用ASP.NET复制一遍,没有给我需求文档,就是让我根据代码去分析业务逻辑,然后看到 ...

  5. 物联网PPT智能家居王思齐和陈由钧第10组

    ppt做完了但是不知道怎么用博客园发ppt!只能发几个图片了

  6. Nginx代理实现跨域

    #user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #erro ...

  7. RabbitMQ 的行为艺术

    RabbitMQ 的行为艺术 目录 简介 环境搭建 示例一:简单的 Hello World 示例二:发布/订阅模式 尝试发现 - 新物种 EasyNetQ 简介 RabbitMQ:一个消息系统,基于 ...

  8. WCF身份验证三:自定义身份验证之<MessageHeader>

    关于使用SoadHeader验证Robin已经有一篇十分精彩的文章: WCF进阶:为每个操作附加身份信息, 不过我的思维方式总是跟别人有点不太一样, 还是把类似的内容用我的方式重新组织一下. 使用He ...

  9. LevelDB速记

    LevelDb的基本结构如下: 由六大部分组成: 一.MemTable,用户写入和读取的直接对象, 二.Immutable MemTable,用户状态写入的对象写满的MemTable之后会转为Immu ...

  10. 二分查找 Binaryserach

    二分查找: 二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升 ...