comment résoudre cette timer Linux

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

J’ai créé un programme côté serveur pour recevoir des données du client et renvoyer la réponse au client. Il existe des API dont la définition n’est pas indiquée ci-dessus.

J’écris une application qui utilise un minuteur pour effectuer une acquisition et un traitement de données à une fréquence d’échantillonnage fixe (200Hz). L’application agit comme un serveur et s’exécute en arrière-plan. Il devrait être contrôlable depuis d’autres processus ou d’autres machines depuis UDP.

Pour ce faire, j’utilise l’API timer_create() pour générer des signaux périodiquement et appeler un gestionnaire qui effectue l’acquisition et le traitement.

Le code ci-dessus est appelé quand une commande ‘ start ‘ est reçue de UDP. Pour vérifier la commande, mon programme principal a une boucle infinie qui appelle recvfrom() syscall.

PROBLÈME: en mode débogage – je reçois les données du client, le timer a été appelé et il se static void timerHandler( int sig, siginfo_t *si, void *uc ) { – – static void timerHandler( int sig, siginfo_t *si, void *uc ) { .

RAISON du problème: je crée plusieurs timers, disons 3 timers à partir d’un seul processus. et tous sont censés atterrir dans le gestionnaire de timer unique.

Mais son erreur de bus et "si->si_value.sival_ptr" ==> valeur indésirable et, d’autre part, comment elle est corrompue. – Plus d’informations sur: http://www.graphics-muse.org/wp/?p=868#sthash.cuvJDp39.dpuf .

Quelqu’un pourrait-il m’aider dans ce domaine?

Le problème semble être centré dans votre fonction CreateSockeet .

Dans votre boucle de lecture, vous appelez timerCalculation qui crée et définit trois timers dans makeTimer . Il le fait à chaque fois dans la boucle. Donc, en fonction de l’arrivée de vos données, vous pouvez potentiellement créer plusieurs temporisateurs avant que l’un d’eux ne se déclenche. En fait, cela n’explique pas vraiment votre problème – au pire, vous devriez avoir des timers qui s’allument à des moments inappropriés – mais je soupçonne qu’il s’agit d’un code écourté et que des problèmes se manifestent par la suite.

Au minimum, vous devriez éviter la création de la timer et la réutiliser ou au moins la supprimer lorsque vous avez terminé.

En outre, vous quittez votre boucle de lecture lorsqu’une lecture renvoie 0. Il s’agit d’une sémantique tcp / stream pour la déconnexion de l’autre côté. Il n’y a pas de signification correspondante dans UDP. Un paquet UDP de longueur 0 est légal et signifie simplement qu’un datagramme vide a été reçu. À moins que vous n’ayez conclu un protocole avec votre pair, un paquet de longueur nulle signifie la fin de la transmission, cela ne vous échappera pas.