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

rtc是Linux系统中的一个时间设备,可以open打开,通过ioctl设置频率,然后就可以进行循环read操作,每次read的耗时是(1/频率 单位:秒)

先上代码

[cpp]  view plain  copy
  1. #include <sys/ioctl.h>  
  2. #include <sys/types.h>  
  3. #include <sys/stat.h>  
  4. #include <fcntl.h>  
  5. #include <linux/rtc.h>  
  6. #include <errno.h>  
  7. #include <stdio.h>  
  8. #include <stdlib.h>  
  9. #include <sys/time.h>  
  10. #include <unistd.h>  
  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.\n");  
  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...\n");  
  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\n");  
  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\n" , (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 时间需要执行多少次。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值