2014-02-25 67 views
0
#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 = 18033; 


void TASK1(Task2ms_Raster) 
{ 

    struct timespec start, stop; 
    uint32 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 %ld", stopTime); 

      duration2ms = (uint32)(stopTime- startTime); 
      // printf("time difference is= %ld\n", duration2ms); 



} 



void TASK3(Task100ms_Raster) 
{ 
    struct timespec start, stop; 
    uint32 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 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) 
{ 
    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; 
} 



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"); 

     } 

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


     // create a timer 

       makeTimer("First Timer", &firstTimerID, 2, 2); //2ms 
      makeTimer("Second Timer", &secondTimerID, 10, 10); //10ms 
       makeTimer("Third Timer", &thirdTimerID, 100, 100); //100ms 
      } 


    } 

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

我正在處理客戶端和服務器體系結構。服務器代碼如上所示,我創建了一個套接字來通過IP地址和端口號從客戶端接收請求。服務器正在等待來自客戶端的請求並將響應發送回客戶端。我還創建了定時器,每2ms,10ms和100ms調用te任務。我沒有爲定時器任務創建一個分離的線程。剛創建了一個處理程序來處理(信號處理程序)。當客戶端向服務器發送請求時,我接收recvfrom api中的數據,然後調用maketimer(它是2ms),之後它不會從2ms任務中出來。如何並行運行函數?

客戶端是一種用於將數據發送到服務器的工具(INCA)。我正在研究Linux操作系統。

有人能告訴我上面的程序有什麼問題?

回答

0

您需要爲while(rc!= - 1)循環創建單獨的線程,因爲recvfrom()是一個阻塞函數。它將你的線程置於無效狀態,直到新數據出現爲止。

+0

你能給我舉個例子嗎? – user3345539

+0

您可以通過[pthreads](http://en.wikipedia.org/wiki/Pthreads)在單獨的線程中執行某些操作,但它可能不是必需的。您可能需要考慮使用非阻塞I/O。 – Jason