如何解决这个Linux Timer

#include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #define million 1000000L timer_t firstTimerID, secondTimerID, thirdTimerID; double Task2ms_Raster, Task10ms_Raster, Task100ms_Raster; struct sockaddr_in addr, client; int acceptSocket; char buf[256]; long rc, sentbytes; int port = 18037; void TASK1(Task2ms_Raster) { struct timespec start, stop; double startTime, stopTime; if( (startTime = clock_gettime( CLOCK_REALTIME, &start)) == -1 ) { perror("clock gettime"); } startTime =start.tv_sec + 0.0000001 * start.tv_nsec; printf("start time is %lf", startTime); // return EXIT_SUCCESS; /* Trigger DAQ for the 2ms XCP raster. */ if( XCPEVENT_DAQ_OVERLOAD & Xcp_DoDaqForEvent_2msRstr( )) { ++numDaqOverload2ms; } /* Update those variables which are modified every 2ms. */ counter32 += slope32; /* Trigger STIM for the 2ms XCP raster. */ if( enableBypass2ms ) { if( XCPEVENT_MISSING_DTO & Xcp_DoStimForEvent_2msRstr( ) ) { ++numMissingDto2ms; } } if( (stopTime = clock_gettime( CLOCK_REALTIME, &stop)) == -1 ) { perror( "clock gettime" ); } stopTime = stop.tv_sec + 0.0000001 * stop.tv_nsec; printf("stop time is %lf", stopTime); duration2ms = (stopTime- startTime); printf( "time difference for task1 is= %ld\n", duration2ms ); } void TASK2(Task10ms_Raster) { struct timespec start, stop; double startTime, stopTime; if( (startTime = clock_gettime( CLOCK_REALTIME, &start)) == -1 ) { perror( "clock gettime" ); } startTime =start.tv_sec + 0.0000001 * start.tv_nsec; printf("start time is %lf", startTime); /* Trigger DAQ for the 10ms XCP raster. */ if( XCPEVENT_DAQ_OVERLOAD & Xcp_DoDaqForEvent_10msRstr( )) { ++numDaqOverload10ms; } /* Update those variables which are modified every 10ms. */ counter16 += slope16; /* Trigger STIM for the 10ms XCP raster. */ if( enableBypass10ms ) { if( XCPEVENT_MISSING_DTO & Xcp_DoStimForEvent_10msRstr( ) ) { ++numMissingDto10ms; } } if( (stopTime = clock_gettime( CLOCK_REALTIME, &stop)) == -1 ) { perror( "clock gettime" ); } stopTime = stop.tv_sec + 0.0000001 * stop.tv_nsec; printf("stop time is %lf", stopTime); duration10ms = ( stop.tv_sec - start.tv_sec ) + (double)( stop.tv_nsec - start.tv_nsec ) / (double)million; printf( "time difference for task2 is= %ld\n", duration10ms ); } void TASK3(Task100ms_Raster) { struct timespec start, stop; double startTime, stopTime; if( (startTime = clock_gettime( CLOCK_REALTIME, &start)) == -1 ) { perror("clock gettime"); } startTime =start.tv_sec + 0.0000001 * start.tv_nsec; printf("start time is %lf", startTime); /* Trigger DAQ for the 100ms XCP raster. */ if( XCPEVENT_DAQ_OVERLOAD & Xcp_DoDaqForEvent_100msRstr( )) { ++numDaqOverload100ms; } /* Update those variables which are modified every 100ms. */ counter8 += slope8; /* Trigger STIM for the 100ms XCP raster. */ if( enableBypass100ms ) { if( XCPEVENT_MISSING_DTO & Xcp_DoStimForEvent_100msRstr( ) ) { ++numMissingDto100ms; } } if((stopTime = clock_gettime( CLOCK_REALTIME, &stop)) == -1 ) { perror( "clock gettime" ); } stopTime = stop.tv_sec + 0.0000001 * stop.tv_nsec; printf("stop time is %lf", stopTime); Xcp_CmdProcessor(); duration100ms = ( stop.tv_sec - start.tv_sec ) + (double)( stop.tv_nsec - start.tv_nsec ) / (double)million; printf( "time difference for task3 is= %ld\n", duration100ms ); } /*The handler checks that the value stored in sival_ptr matches a given timerID variable. The sival_ptr is the same as the one we set in makeTimer(), though here it lives in a different structure. Obviously, it got copied from there to here on the way to this signal handler. The point is that the timerID is what is used to determine which timer just went off and determine what to do next */ static void timerHandler( int sig, siginfo_t *si, void *uc ) { timer_t *tidp; tidp = si->si_value.sival_ptr; if ( *tidp == firstTimerID ) TASK1(Task2ms_Raster); else if ( *tidp == secondTimerID ) TASK2(Task10ms_Raster); else if ( *tidp == thirdTimerID ) TASK3(Task100ms_Raster); } /* The function takes a pointer to a timer_t variable that will be filled with the timer ID created by timer_create(). This pointer is also saved in the sival_ptr variable right before calling timer_create(). In this function notice that we always use the SIGRTMIN signal, so expiration of any timer causes this signal to be raised. The signal handler I've written for that signal is timerHandler. */ static int makeTimer( char *name, timer_t *timerID, int expireMS, int intervalMS ) { //sigset_t mask; struct sigevent te; struct itimerspec its; struct sigaction sa; int sigNo = SIGRTMIN; /* Set up signal handler. */ sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = timerHandler; sigemptyset(&sa.sa_mask); if (sigaction(sigNo, &sa, NULL) == -1) { perror("sigaction"); } /* Set and enable alarm */ te.sigev_notify = SIGEV_SIGNAL; te.sigev_signo = sigNo; te.sigev_value.sival_ptr = timerID; timer_create(CLOCK_REALTIME, &te, timerID); its.it_interval.tv_sec = 0; its.it_interval.tv_nsec = intervalMS * 1000000; its.it_value.tv_sec = 0; its.it_value.tv_nsec = expireMS * 1000000; timer_settime(*timerID, 0, &its, NULL); return 1; } void timerCalculation() { makeTimer("First Timer", &firstTimerID, 2, 2); //2ms makeTimer("Second Timer", &secondTimerID, 10, 10); //10ms makeTimer("Third Timer", &thirdTimerID, 100, 100); //100ms } int CreateSocket() { socklen_t len = sizeof(client); // Socket creation for UDP acceptSocket=socket(AF_INET,SOCK_DGRAM,0); if(acceptSocket==-1) { printf("Failure: socket creation is failed, failure code\n"); return 1; } else { printf("Socket started!\n"); } //non blocking mode /* rc = ioctl(acceptSocket, FIONBIO, (char *)&flag); if (rc < 0) { printf("\n ioctl() failed \n"); return 0; }*/ //Bind the socket memset(&addr, 0, sizeof(addr)); addr.sin_family=AF_INET; addr.sin_port=htons(port); addr.sin_addr.s_addr=htonl(INADDR_ANY); rc=bind(acceptSocket,(struct sockaddr*)&addr,sizeof(addr)); if(rc== -1) { printf("Failure: listen, failure code:\n"); return 1; } else { printf("Socket an port %d \n",port); } if(acceptSocket == -1) { printf("Fehler: accept, fehler code:\n"); return 1; } else { while(rc!=-1) { rc=recvfrom(acceptSocket,buf, 256, 0, (struct sockaddr*) &client, &len); if(rc==0) { printf("Server has no connection..\n"); break; } if(rc==-1) { printf("something went wrong with data %s", strerror(errno)); break; } XcpIp_RxCallback( (uint16) rc, (uint8*) buf, (uint16) port ); timerCalculation(); } } close(acceptSocket); return 0; } int main() { Xcp_Initialize(); CreateSocket(); return 0; } void XcpApp_IpTransmit( uint16 XcpPort, Xcp_StatePtr8 pBytes, uint16 numBytes ) { if ((long)XcpPort==port){ sentbytes = sendto(acceptSocket,(char*)pBytes,(long)numBytes,0, (struct sockaddr*)&client, sizeof(client)); } XcpIp_TxCallback(port,(uint16)sentbytes); } 

我创建了一个服务器端程序,用于从客户端接收数据并将响应发送回客户端。有一些api,其定义未在上面显示。

我正在编写一个应用程序,它使用计时器以固定采样率(200Hz)进行一些数据采集和处理。 该应用程序的作用类似于服务器并在后台运行。 它应该可以从UDP的其他进程或其他机器控制。

为此,我使用timer_create() API定期生成信号并调用执行获取和处理的处理程序。

当从UDP接收到“ start ”命令时,将调用上面的代码。 要检查命令,我的主程序中有一个无限循环,它调用recvfrom()系统调用。

问题:在调试模式下 – 我正在接收来自客户端的数据,调用定时器并且它被卡在 – static void timerHandler( int sig, siginfo_t *si, void *uc ) {

问题的原因:我正在创建多个计时器,比如说来自一个进程的3个计时器。 并且所有都应该落在单个Timer处理程序中。

但它给出的总线错误和"si->si_value.sival_ptr" ==>具有垃圾价值,还有一些如何被破坏。 – 请参阅: http : //www.graphics-muse.org/wp/?p = 886#sthash.cuvJDp39.dpuf 。

谁能帮我这个?

问题似乎集中在您的CreateSockeet函数中。

在read循环中,调用timerCalculation ,后者又在makeTimer创建并设置三个定时器。 它每次循环都会这样做。 因此,根据数据的到达,您可以在其中一个计时器出现之前创建许多计时器。 这实际上并没有解释你的问题 – 最坏的情况是你应该让计时器在不适当的时间出现 – 但我怀疑这是缩短的代码,问题表明自己的问题。

至少你应该从循环中获得定时器创建并重新使用它们或者至少在完成后删除它们。

此外,当读取返回0时,退出读取循环。这是另一端断开连接的tcp / stream语义。 UDP中没有相应的含义。 长度为0的UDP数据包是合法的,只是意味着收到了一个空数据报。 除非你与你的对等方有一些协议安排,零长度数据包意味着传输结束,否则这不会让你离开你的循环。