etisserant@0: #include etisserant@0: etisserant@0: #include robert@793: #include etisserant@0: #include edouard@631: #include etisserant@0: robert@793: #include Edouard@801: #include etisserant@0: edouard@631: static pthread_mutex_t CanFestival_mutex = PTHREAD_MUTEX_INITIALIZER; etisserant@0: edouard@631: static struct timeval last_sig; etisserant@32: edouard@631: static timer_t timer; etisserant@0: greg@454: void TimerCleanup(void) greg@454: { greg@454: /* only used in realtime apps */ greg@454: } greg@454: etisserant@0: void EnterMutex(void) etisserant@0: { edouard@631: if(pthread_mutex_lock(&CanFestival_mutex)) { edouard@631: fprintf(stderr, "pthread_mutex_lock() failed\n"); edouard@631: } etisserant@0: } etisserant@0: etisserant@0: void LeaveMutex(void) etisserant@0: { edouard@631: if(pthread_mutex_unlock(&CanFestival_mutex)) { edouard@631: fprintf(stderr, "pthread_mutex_unlock() failed\n"); edouard@631: } etisserant@0: } etisserant@0: etisserant@145: void timer_notify(sigval_t val) etisserant@32: { edouard@631: if(gettimeofday(&last_sig,NULL)) { edouard@631: perror("gettimeofday()"); edouard@631: } etisserant@32: EnterMutex(); etisserant@32: TimeDispatch(); etisserant@32: LeaveMutex(); etisserant@32: // printf("getCurrentTime() return=%u\n", p.tv_usec); etisserant@32: } etisserant@32: greg@454: void TimerInit(void) etisserant@32: { etisserant@32: struct sigevent sigev; etisserant@32: etisserant@32: // Take first absolute time ref. edouard@631: if(gettimeofday(&last_sig,NULL)){ edouard@631: perror("gettimeofday()"); edouard@631: } etisserant@32: greg@607: #if defined(__UCLIBC__) greg@607: int ret; greg@607: ret = timer_create(CLOCK_PROCESS_CPUTIME_ID, NULL, &timer); greg@607: signal(SIGALRM, timer_notify); greg@607: #else etisserant@32: memset (&sigev, 0, sizeof (struct sigevent)); etisserant@32: sigev.sigev_value.sival_int = 0; etisserant@32: sigev.sigev_notify = SIGEV_THREAD; etisserant@32: sigev.sigev_notify_attributes = NULL; etisserant@32: sigev.sigev_notify_function = timer_notify; etisserant@32: edouard@631: if(timer_create (CLOCK_REALTIME, &sigev, &timer)) { edouard@631: perror("timer_create()"); edouard@631: } greg@607: #endif etisserant@32: } etisserant@32: greg@454: void StopTimerLoop(TimerCallback_t exitfunction) etisserant@32: { etisserant@149: EnterMutex(); edouard@631: if(timer_delete (timer)) { edouard@631: perror("timer_delete()"); edouard@631: } greg@454: exitfunction(NULL,0); etisserant@149: LeaveMutex(); etisserant@32: } etisserant@32: etisserant@32: void StartTimerLoop(TimerCallback_t init_callback) etisserant@0: { etisserant@149: EnterMutex(); etisserant@0: // At first, TimeDispatch will call init_callback. etisserant@0: SetAlarm(NULL, 0, init_callback, 0, 0); etisserant@149: LeaveMutex(); etisserant@0: } etisserant@0: etisserant@507: void canReceiveLoop_signal(int sig) etisserant@507: { etisserant@507: } etisserant@507: /* We assume that ReceiveLoop_task_proc is always the same */ etisserant@508: static void (*unixtimer_ReceiveLoop_task_proc)(CAN_PORT) = NULL; etisserant@507: etisserant@507: /** etisserant@507: * Enter in realtime and start the CAN receiver loop etisserant@507: * @param port etisserant@507: */ etisserant@540: void* unixtimer_canReceiveLoop(void* port) etisserant@507: { etisserant@507: /*get signal*/ fbeaulier@663: // if(signal(SIGTERM, canReceiveLoop_signal) == SIG_ERR) { fbeaulier@663: // perror("signal()"); fbeaulier@663: //} robert@793: robert@793: // Set the cancelation state for immediatly cancel the task robert@793: int ret; robert@793: robert@793: ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); robert@793: robert@793: if (ret != 0) robert@793: perror("Can't enable the cancelation of the receiving task"); robert@793: robert@793: ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); robert@793: robert@793: if (ret != 0) robert@793: perror("Can't set the asynchronous cancel typ"); robert@793: etisserant@540: unixtimer_ReceiveLoop_task_proc((CAN_PORT)port); edouard@631: edouard@631: return NULL; etisserant@507: } etisserant@507: etisserant@145: void CreateReceiveTask(CAN_PORT port, TASK_HANDLE* Thread, void* ReceiveLoopPtr) etisserant@0: { etisserant@508: unixtimer_ReceiveLoop_task_proc = ReceiveLoopPtr; edouard@631: if(pthread_create(Thread, NULL, unixtimer_canReceiveLoop, (void*)port)) { edouard@631: perror("pthread_create()"); edouard@631: } etisserant@0: } etisserant@0: etisserant@401: void WaitReceiveTaskEnd(TASK_HANDLE *Thread) etisserant@0: { robert@793: if(pthread_cancel(*Thread)) { robert@793: perror("pthread_cancel()"); edouard@631: } edouard@631: if(pthread_join(*Thread, NULL)) { edouard@631: perror("pthread_join()"); edouard@631: } etisserant@0: } etisserant@0: etisserant@48: #define maxval(a,b) ((a>b)?a:b) etisserant@0: void setTimer(TIMEVAL value) etisserant@0: { etisserant@0: // printf("setTimer(TIMEVAL value=%d)\n", value); etisserant@32: // TIMEVAL is us whereas setitimer wants ns... etisserant@38: long tv_nsec = 1000 * (maxval(value,1)%1000000); etisserant@32: time_t tv_sec = value/1000000; etisserant@32: struct itimerspec timerValues; etisserant@32: timerValues.it_value.tv_sec = tv_sec; etisserant@32: timerValues.it_value.tv_nsec = tv_nsec; etisserant@0: timerValues.it_interval.tv_sec = 0; etisserant@32: timerValues.it_interval.tv_nsec = 0; etisserant@32: etisserant@32: timer_settime (timer, 0, &timerValues, NULL); etisserant@0: } etisserant@0: etisserant@0: TIMEVAL getElapsedTime(void) etisserant@0: { etisserant@0: struct timeval p; edouard@631: if(gettimeofday(&p,NULL)) { edouard@631: perror("gettimeofday()"); edouard@631: } etisserant@0: // printf("getCurrentTime() return=%u\n", p.tv_usec); etisserant@0: return (p.tv_sec - last_sig.tv_sec)* 1000000 + p.tv_usec - last_sig.tv_usec; etisserant@0: }