2014-02-21 5 views
2

Код, приведенный ниже, предназначен для приема данных от ведущего устройства через разъем для слоя udp. В моем проекте есть некоторые API, и я создал задачу таймера для вызова задачи на каждые 2 мс, 10 мс и т. Д.Как проверить задачу таймера в фоновом режиме?

Я отлаживаю эту программу на цели встроенного ПК в Eclipse IDE, используя удаленное приложение C/C++. Я звоню maketimer (alarm) внутри функции CreateSocket. Но как проверить задачу таймера, вызывающую функции TASK1, TASK2 и TASK3 на каждые 2 мс, 10 мс и 100 мс в фоновом режиме?

#include "MAIN.h" 

#define BILLION 1000000L 

timer_t firstTimerID, secondTimerID, thirdTimerID; 
double Task2ms_Raster, Task10ms_Raster, Task100ms_Raster ; 

int connectedSocket, acceptSocket; 
struct sockaddr_in addr; 
struct sockaddr client, dest; 
char buf[128]; 
long rc, sentbytes; 
int port = 18017; 


void TASK1(Task2ms_Raster) 
{ 

    struct timespec start, stop; 
    uint32 StartTime, StopTime; 

    if((StartTime = clock_gettime(CLOCK_REALTIME, &start)) == -1) 
    { 
     perror("clock gettime"); 

    } 

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

    duration2ms = (stop.tv_sec - start.tv_sec) 
     + (double)(stop.tv_nsec - start.tv_nsec) 
     /(double)BILLION; 
    printf("time difference is= %ld\n", duration2ms); 
} 

void TASK2(Task10ms_Raster) 
{ 
    struct timespec start, stop; 

    if(clock_gettime(CLOCK_REALTIME, &start) == -1) 
    { 
     perror("clock gettime"); 
    } 

    /* 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(clock_gettime(CLOCK_REALTIME, &stop) == -1) 
    { 
     perror("clock gettime"); 
    } 
    XCP_FN_TYPE Xcp_CmdProcessor (); 

    duration10ms = (stop.tv_sec - start.tv_sec) 
     + (double)(stop.tv_nsec - start.tv_nsec) 
     /(double)BILLION; 
    printf("time difference is= %ld\n", duration10ms); 
} 


void TASK3(Task100ms_Raster) 
{ 
    struct timespec start, stop; 

    if(clock_gettime(CLOCK_REALTIME, &start) == -1) 
    { 
     perror("clock gettime"); 

    } 

    /* 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((clock_gettime(CLOCK_REALTIME, &stop)) == -1) 
    { 
     perror("clock gettime"); 
    } 

    duration100ms = (stop.tv_sec - start.tv_sec) 
     + (double)(stop.tv_nsec - start.tv_nsec) 
     /(double)BILLION; 
    printf("time difference is= %ld\n", duration100ms); 
} 

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

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() 
{ 
    if(rc!=0) 
    { 
     printf("socket failure code: %ld\n",rc); 

     return 1; 
    } 

    else 

    { 
     printf("socket started!\n"); 
    } 

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


    while(rc!=-1) 
    { 
     rc= recvfrom(acceptSocket,buf,128,0,(struct sockaddr*)&client, sizeof(client)); 
     if(rc==0) 
     { 
      printf("Server has no connection..\n"); 
      break; 
     } 
     if(rc==-1) 
     { 
      printf("failure: recv, failure code\n"); 
      break; 
     } 
     XcpIp_RxCallback((uint16) rc, (uint8*) buf, (uint16) port); 

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

     // buf[rc]='\0'; 
     // printf("Client sendet: %s\n",buf); 
     // sprintf(buf2,"Du mich auch %s",buf); 
     // rc=sendto(connectedSocket,buf2,strlen(buf2),0); 
    } 

    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*) &dest, sizeof(dest)); 
    } 
    XcpIp_TxCallback(port,(uint16)sentbytes); 
} 

ответ

1

Read time(7) и signal(7).

BTW, ваш BILLION неправ. Вы, вероятно, должны иметь

#define BILLION 1.0e9 

(так как вы используете его только в плавающем выражении точки)

Вы можете иметь три темы (читать pthreads tutorial), один для TASK1, один для TASK2, один для TASK3 (возможно, используя clock_nanosleep(2) ...). Или (желательно) у вас может быть один event loop (например, например, вызов или ppoll(2)), возможно, также используя timerfd_create(2) для получения событий таймера, а также для управления сокетами. См. this example of poll-based event loop. Вы должны адаптировать его также использовать дескриптор файла, полученный с timerfd_create .. Можно также использовать некоторые события зацикливания библиотеки как libevent или libev

Обратите внимание, что 2 миллисекунды очень малая задержка. (Насколько надежны вы хотите, чтобы быть?)

Read Advanced Linux Programming

+0

Я использую HPET в моей программе для вызова задачи для каждого, 2 мс 10 мс и 100 мс. Почему я не могу использовать один поток и вызывать makeTimer («Первый таймер», & firstTimerID, 2, 2); // 2ms makeTimer («Второй таймер», & secondTimerID, 10, 10); // 10ms makeTimer («Третий таймер», и третийTimerID, 100, 100); // 100 мс ?? – user3252048

+0

Я использую будильник и обработчик для вызова задачи на 2 мс, 10 и 100 мс. Тогда и нужно ли использовать потоки? – user3252048

+0

Я бы использовал цикл событий и 'timerfd_create' –

Смежные вопросы