2014-02-27 54 views
0
#include <features.h> 
#include <time.h> 
#include <sys/time.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
#include <string.h> 
#include <signal.h> 
#include <unistd.h> 
#include <errno.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netdb.h> 
#include <sys/ioctl.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 

#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); 
    } 

我創建的服務器端程序,用於從客戶端接收數據和發送響應返回給client.There是一些API,其定義不如上所示。如何解決這個Linux的定時器

我正在寫一個應用程序,它使用定時器以固定採樣率(200Hz)進行一些數據採集和處理。該應用程序像服務器一樣運行並在後臺運行。它應該可以從其他進程或來自UDP的其他機器進行控制。爲此,我使用timer_create() API定期生成信號,並調用處理程序進行採集和處理。

當從UDP收到'start'命令時調用上面的代碼。要檢查命令,我的主程序中有一個無限循環,調用recvfrom()系統調用。

問題:在調試模式下 - 我從客戶端接收數據,計時器被調用,並且卡在 - static void timerHandler(int sig, siginfo_t *si, void *uc) {

對於這個問題的原因:我創建了多個定時器,比如來自單個進程的3個定時器。並且所有都應該落在單個定時器處理程序中。

但它給出的總線錯誤和"si->si_value.sival_ptr" ==>是垃圾值和一些如何被損壞。 - 更多信息請見:http://www.graphics-muse.org/wp/?p=868#sthash.cuvJDp39.dpuf

任何人都可以幫助我?

回答

0

該問題似乎集中在CreateSockeet函數中。

在您的閱讀循環中,您可以撥打timerCalculation,然後在makeTimer中創建並設置三個計時器。它每次都通過循環完成。因此,根據數據的到達情況,您可能會在其中一個定時器失效之前創建多個定時器。這實際上並不能解決你的問題 - 最糟糕的情況是你應該讓定時器在不適當的時候啓動 - 但是我懷疑這是縮短的代碼和問題。

您至少應該將循環中的計時器創建出來,並重新使用它們,或者至少在完成時刪除它們。

此外,當讀取返回0時,您退出讀取循環。這是另一方斷開連接的tcp /流語義。在UDP中沒有相應的含義。長度爲0的UDP數據包是合法的,只是表示收到一個空的數據報。除非你與你的對端有一些協議安排,否則零長度的數據包意味着終止傳輸,這不會讓你擺脫循環。

相關問題