Hrtimer High-precision timer "turn" under Linux

Source: Internet
Author: User

Transferred from: http://blog.csdn.net/waverider2012/article/details/38305785

The interval of the Hrtimer high-precision timer is determined by the Ktime_set (const long secs, const unsigned long nsecs) and can be NS-level. The example here is 5ms interval:

[CPP]View PlainCopy 
  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 is 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);

If you return directly to Hrtimer_restart in My_hrtimer_callback () it will cause immediate re-entry into My_hrtimer_callback (). At this point the shell does not respond to the input.

So in order to solve this problem, a work queue was created, My_hrtimer_callback () enqueue This Task Force column. Restart Hrtimer in the work queue's handler function.

However, the negative effect is that the delay introduced by Linux system scheduling between Hrtimer_callback and Wq_func is called, resulting in interval errors. After measurement, in the ZC706 default configuration, this delay is approximately 17.5us (Hrtimer interval is 5ms, the interval error is calculated every 20 seconds).

[Plain]View PlainCopy 
    1. [Email protected]:~/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

Hrtimer High-precision timer "turn" under Linux

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.