Linux 内核定时器使用 二 高精度定时器 hrtimer 的用例【转】

转自:https://blog.csdn.net/fuyuande/article/details/82193600

之前介绍了timer_list内核定时器,它的精度在毫秒级别,再高一点它就无能为力了,所幸内核提供了高精度定时器 hrtimer。

源文件在linux/kernel/hrtimer.c中。接口简单。下面介绍一下相关接口

  1. 1. 定时器定义与绑定超时回调函数
  2. static struct hrtimer timer;
  3.  
  4. /* 设置回调函数 */
  5. timer.function = hrtimer_hander;
  6.  
  7. 2. 定时器初始化
  8. /*
  9. * 参数timer是hrtimer指针,
  10. * 参数clock_id有如下常用几种选项:
  11. * CLOCK_REALTIME //实时时间,如果系统时间变了,定时器也会变
  12. * CLOCK_MONOTONIC //递增时间,不受系统影响
  13. * 参数mode有如下几种选项:
  14. * HRTIMER_MODE_ABS = 0x0, /* 绝对模式 */
  15. HRTIMER_MODE_REL = 0x1, /* 相对模式 */
  16. HRTIMER_MODE_PINNED = 0x02, /* 和CPU绑定 */
  17. HRTIMER_MODE_ABS_PINNED = 0x02, /* 第一种和第三种的结合 */
  18. HRTIMER_MODE_REL_PINNED = 0x03, /* 第二种和第三种的结合 */
  19. */
  20. void hrtimer_init(struct hrtimer *timer, clockid_t clock_id, enum hrtimer_mode mode);
  21.  
  22. 3. 定时器启动
  23. /*
  24. * 参数timer是hrtimer指针
  25. * 参数tim是时间,可以使用ktime_set()函数设置时间,
  26. * 参数mode和初始化的mode参数一致
  27. */
  28. hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode);
  29.  
  30. 4. 设置时间
  31. /*
  32. * 单位为秒和纳秒组合
  33. */
  34. ktime_t ktime_set(const long secs, const unsigned long nsecs);
  35.  
  36. /* 设置超时时间,当定时器超时后可以用该函数设置下一次超时时间 */
  37. hrtimer_forward_now(struct hrtimer *timer, ktime_t interval)
  38.  
  39. 5. 注意事项:
  40. 定时器超时后会调用回调函数,回调函数结构类似这样:
  41. enum hrtimer_restart (*function)(struct hrtimer *);
  42.  
  43. enum hrtimer_restart {
  44. HRTIMER_NORESTART, /* 不重启定时器 */
  45. HRTIMER_RESTART, /* 重启定时器 */
  46. };
  47. 在回调函数返回前要手动设置下一次超时时间。
  48. 另外,回调函数执行时间不宜过长,因为是在中断上下文中,如果有什么任务的话,最好使用工作队列等机制。
  49.  
  50. 6. 关闭定时器
  51. int hrtimer_cancel(struct hrtimer *timer);
  52.  
  53. 简单用例:
  54. /*
  55. * Description : 高精度定时器用例
  56. * Author : mason
  57. * Date : 201808
  58. */
  59.  
  60. #include <linux/module.h>
  61. #include <linux/kernel.h>
  62. #include <linux/hrtimer.h>
  63. #include <linux/jiffies.h>
  64.  
  65. static struct hrtimer timer;
  66. ktime_t kt;
  67.  
  68. /* 定时器回调函数 */
  69. static enum hrtimer_restart hrtimer_hander(struct hrtimer *timer)
  70. {
  71. printk("hrtimer up\r\n");
  72.  
  73. /* 设置下次过期时间 */
  74. kt = ktime_set(3,0);
  75. hrtimer_forward_now(timer, kt);
  76.  
  77. /* 该参数将重新启动定时器 */
  78. return HRTIMER_RESTART;
  79. }
  80.  
  81. static int __init hrtimer_demo_init(void)
  82. {
  83. printk("hello hrtimer \r\n");
  84.  
  85. kt = ktime_set(1,10);
  86.  
  87. /* hrtimer初始化 */
  88. hrtimer_init(&timer,CLOCK_MONOTONIC,HRTIMER_MODE_REL);
  89.  
  90. /* hrtimer启动 */
  91. hrtimer_start(&timer,kt,HRTIMER_MODE_REL);
  92.  
  93. /* 设置回调函数 */
  94. timer.function = hrtimer_hander;
  95.  
  96. return 0;
  97. }
  98.  
  99. static void __exit hrtimer_demo_exit(void)
  100. {
  101. /* hrtimer注销 */
  102. hrtimer_cancel(&timer);
  103. printk("bye hrtimer\r\n");
  104. }
  105.  
  106.  
  107. module_init(hrtimer_demo_init);
  108. module_exit(hrtimer_demo_exit);
  109. MODULE_LICENSE("GPL");
  110.  

参考文档 :

1. Linux 下定时器的实现方式分析

https://www.ibm.com/developerworks/cn/linux/l-cn-timers/

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

https://www.cnblogs.com/zzb-Dream-90Time/p/7084916.html

posted @ 2020-09-02 18:10  Sky&Zhang  阅读(2916)  评论(0编辑  收藏  举报