linux下三种MS级定时器的实现

来源:互联网 发布:淘宝企业店铺什么意思 编辑:程序博客网 时间:2024/05/02 15:19

方法1和3已经经过测试,方法2未测试,有几个中断函数中的宏不知道应该在哪个头文件中,请有知道的可以教下.

1.通过系统调用

 

/*mytimer.c----提供50ms,10ms计数器*/
 
#include <stdio.h>
#include <stdlib.h>
#include <error.h>
#include <unistd.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include  <sys/ipc.h>
#include  <sys/shm.h>

#include "mytimer.h"

#define  keyFIFTYMSCOUNT  0x10001101
//ITIMER_REAL //数值为0,以系统真实的时间来计算,发送的信号是SIGALRM。
static unsigned int fiftyMsCount = 0x00000000;
unsigned int *pFiftyMsCount;
void sigroutine(int signum);
//unsigned int getFiftyMsCount(void);


int main()
{
 int which;
 struct itimerval tval,otval;
/* sigset_t set;
 int result;*/
 
 int shm_id;
 int shm_flg;

 shm_flg = IPC_CREAT|0666;
 /*申请系统数据区共享内存块*/
 shm_id = shmget( keyFIFTYMSCOUNT, sizeof(unsigned int), shm_flg);
 if( shm_id == -1 )
 {
  printf("shmget(%x) error", keyFIFTYMSCOUNT);
  return(-1);
 }
 /*将系统数据区共享内存块附加到自己的内存段*/
 if( (pFiftyMsCount = (unsigned int *)shmat(shm_id, 0, 0) ) < (char *)0 )
 {
  printf("shmat(%x) error", keyFIFTYMSCOUNT);
  return(-1);
 }
 
 
 signal(SIGALRM, (void *)sigroutine);
 
 which = ITIMER_REAL;
 
 tval.it_interval.tv_sec = 0;
 tval.it_interval.tv_usec = 50000;
 
 tval.it_value.tv_sec = 0;
 tval.it_value.tv_usec = 50000;
 
 setitimer(which, &tval, &otval);
 
/* if((result = sigemptyset(&set))<0)
  {
   perror("sigemptyset err:");
   exit(EXIT_FAILURE);
   }
 
 if((result = sigaddset(&set, SIGTERM))<0)
  {
   perror("sigaddset err:");
   exit(EXIT_FAILURE);
   }
*/
  while(1);
}

void sigroutine(int signum)
{
 (*pFiftyMsCount)++;
 printf("50ms count = %d/n",(*pFiftyMsCount));
}

 

2.方法2

#include <stdio.h>
#include <stdlib.h>
#include <error.h>
#include <unistd.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <rtc.h>
#include <sys/time.h>
#include <sys/types.h>

int main()
{
 unsigned long i = 0;
 unsigned long data = 0;
 int retval = 0;
 int fd;
 
 fd = open("/dev/rtc",O_RDONLY);
 ioctl(fd,RTC_IRQP_SET,4);
 ioctl(fd,RTC_PIE_ON,4);
 
 for(i=0;i<100;i++)
 {
  read(fd,&data,sizeof(unsigned long));
  printf("timer:/n");
  }
  
 ioctl(fd,RTC_PIE_OFF,0);
 close(fd);
 
 return 0;
}

 

3.通过累加实现

#include <stdio.h>
#include <stdlib.h>
#include <error.h>
#include <unistd.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include  <sys/ipc.h>
#include  <sys/shm.h>

int jiffes = 0;
int ecception_task(int timer);

int main(int argc, char *argv[])
{
 int timer = 1000;
 exception_task(timer);
 return 0;
}

int exception_task(int timer)
{
 int i = timer;
 
 while(1)
 {
  usleep(1000);
  jiffes++;
  
  if(i<jiffes)
   {
    printf("timer = %d/n",jiffes);
    //break;
    }
  }
  return 0;
 }