linux下利用rtc 实现精确定时器

2019-07-13 05:11发布

rtc是Linux系统中的一个时间设备,可以open打开,通过ioctl设置频率,然后就可以进行循环read操作,每次read的耗时是(1/频率 单位:秒) 先上代码 [cpp] view plain copy
  1. #include   
  2. #include   
  3. #include   
  4. #include   
  5. #include   
  6. #include   
  7. #include   
  8. #include   
  9. #include   
  10. #include   
  11. #define FREQ 2048  
  12. #define USEC_PER_SECOND 1000000  
  13. typedef int MILLSEC;  
  14.   
  15. int g_fd = 0;  
  16.    
  17. int calc_cnt(MILLSEC millseconds )  
  18. {  
  19.     return (int)(millseconds * 1000.0 / USEC_PER_SECOND * FREQ + 0.5); //add 0.5 to meet precision in common  
  20. }  
  21.   
  22. void rtc_open()  
  23. {  
  24.     g_fd = open ("/dev/rtc", O_RDONLY);  
  25.     if(g_fd < 0)  
  26.     {     
  27.         perror("open");  
  28.         exit(errno);  
  29.     }  
  30.     printf("opened. ");  
  31. }  
  32.    
  33. void set_freq()  
  34. {  
  35.     /*Set the freq*/  
  36.     if(ioctl(g_fd, RTC_IRQP_SET, FREQ ) < 0)  
  37.     {  
  38.         perror("ioctl(RTC_IRQP_SET)");  
  39.         close(g_fd);  
  40.         exit(errno);  
  41.     }  
  42.     /* Enable periodic interrupts */  
  43.     if(ioctl(g_fd, RTC_PIE_ON, 0) < 0)  
  44.     {  
  45.         perror("ioctl(RTC_PIE_ON)");  
  46.         close(g_fd);  
  47.         exit(errno);  
  48.     }  
  49. }  
  50.   
  51. void rtc_task()  
  52. {  
  53.     printf("start counting... ");  
  54.     struct timeval tvs,tve;  
  55.     unsigned long i = 0;  
  56.     unsigned long data = 0;  
  57.     while(true)  
  58.     {  
  59.         int time_to_wait;  
  60.         printf("please input time to wait in millsecond, -1 to break ");  
  61.         scanf("%d",&time_to_wait);  
  62.         if(time_to_wait < 0)  
  63.             break;  
  64.         //calc how many times to loop  
  65.         int cnt = calc_cnt(time_to_wait);  
  66.         gettimeofday( &tvs , 0 );  
  67.         for(i = 0; i < cnt; i++)  
  68.         {  
  69.             if(read(g_fd, &data, sizeof(unsigned long)) < 0)  
  70.             {  
  71.                 perror("read");  
  72.                 ioctl(g_fd, RTC_PIE_OFF, 0);  
  73.                 close(g_fd);  
  74.                 exit(errno);  
  75.             }  
  76.         }  
  77.         gettimeofday(&tve,0);  
  78.         printf("[%ld]timer usec " , (tve.tv_sec - tvs.tv_sec) * 1000000LL + (tve.tv_usec-tvs.tv_usec));  
  79.     }  
  80.     /* Disable periodic interrupts */  
  81.     ioctl(g_fd, RTC_PIE_OFF, 0);  
  82.     close(g_fd);  
  83. }  
  84.   
  85. int main(int argc, char* argv[])  
  86. {  
  87.     rtc_open();  
  88.     set_freq();  
  89.     rtc_task();  
  90.     return 0;  
  91. }  
例子采用的频率是2048,频率可用范围是2~8192,一定要是2的n次方,否则会运行时错误,频率代表一秒中可以执行多少次,如果是2048次,那么一次的时间就是1.0/2048(秒),由此来确定time to wait 时间需要执行多少次。