nico@215: nico@215:
nico@215:00001 #include <stdlib.h> nico@215: 00002 nico@215: 00003 #include <sys/time.h> nico@215: 00004 #include <pthread.h> nico@215: 00005 #include <signal.h> nico@215: 00006 nico@215: 00007 #include "applicfg.h" nico@215: 00008 #include "timer.h" nico@215: 00009 etisserant@240: 00010 pthread_mutex_t CanFestival_mutex = PTHREAD_MUTEX_INITIALIZER; nico@215: 00011 etisserant@240: 00012 TASK_HANDLE TimerLoopThread; nico@215: 00013 etisserant@240: 00014 TIMEVAL last_time_set = TIMEVAL_MAX; nico@215: 00015 etisserant@240: 00016 struct timeval last_sig; nico@215: 00017 etisserant@240: 00018 timer_t timer; nico@215: 00019 etisserant@240: 00020 void EnterMutex(void) nico@215: 00021 { etisserant@240: 00022 pthread_mutex_lock(&CanFestival_mutex); nico@215: 00023 } nico@215: 00024 etisserant@240: 00025 void LeaveMutex(void) nico@215: 00026 { etisserant@240: 00027 pthread_mutex_unlock(&CanFestival_mutex); nico@215: 00028 } nico@215: 00029 etisserant@240: 00030 void timer_notify(sigval_t val) nico@215: 00031 { etisserant@240: 00032 gettimeofday(&last_sig,NULL); etisserant@240: 00033 EnterMutex(); etisserant@240: 00034 TimeDispatch(); etisserant@240: 00035 LeaveMutex(); nico@215: 00036 // printf("getCurrentTime() return=%u\n", p.tv_usec); nico@215: 00037 } nico@215: 00038 etisserant@240: 00039 void initTimer(void) nico@215: 00040 { nico@215: 00041 struct sigevent sigev; nico@215: 00042 nico@215: 00043 // Take first absolute time ref. etisserant@240: 00044 gettimeofday(&last_sig,NULL); nico@215: 00045 nico@215: 00046 memset (&sigev, 0, sizeof (struct sigevent)); nico@215: 00047 sigev.sigev_value.sival_int = 0; nico@215: 00048 sigev.sigev_notify = SIGEV_THREAD; nico@215: 00049 sigev.sigev_notify_attributes = NULL; etisserant@240: 00050 sigev.sigev_notify_function = timer_notify; nico@215: 00051 etisserant@240: 00052 timer_create (CLOCK_REALTIME, &sigev, &timer); nico@215: 00053 } nico@215: 00054 etisserant@240: 00055 void StopTimerLoop(void) nico@215: 00056 { etisserant@240: 00057 EnterMutex(); etisserant@240: 00058 timer_delete (timer); etisserant@240: 00059 LeaveMutex(); nico@215: 00060 } nico@215: 00061 etisserant@240: 00062 void StartTimerLoop(TimerCallback_t init_callback) nico@215: 00063 { etisserant@240: 00064 initTimer(); etisserant@240: 00065 EnterMutex(); nico@215: 00066 // At first, TimeDispatch will call init_callback. etisserant@240: 00067 SetAlarm(NULL, 0, init_callback, 0, 0); etisserant@240: 00068 LeaveMutex(); nico@215: 00069 } nico@215: 00070 etisserant@240: 00071 void CreateReceiveTask(CAN_PORT port, TASK_HANDLE* Thread, void* ReceiveLoopPtr) nico@215: 00072 { nico@215: 00073 pthread_create(Thread, NULL, ReceiveLoopPtr, (void*)port); nico@215: 00074 } nico@215: 00075 etisserant@240: 00076 void WaitReceiveTaskEnd(TASK_HANDLE Thread) nico@215: 00077 { nico@215: 00078 pthread_kill(Thread, SIGTERM); nico@215: 00079 pthread_join(Thread, NULL); nico@215: 00080 } nico@215: 00081 etisserant@240: 00082 #define maxval(a,b) ((a>b)?a:b) etisserant@240: 00083 void setTimer(TIMEVAL value) nico@215: 00084 { nico@215: 00085 // printf("setTimer(TIMEVAL value=%d)\n", value); nico@215: 00086 // TIMEVAL is us whereas setitimer wants ns... etisserant@240: 00087 long tv_nsec = 1000 * (maxval(value,1)%1000000); nico@215: 00088 time_t tv_sec = value/1000000; nico@215: 00089 struct itimerspec timerValues; nico@215: 00090 timerValues.it_value.tv_sec = tv_sec; nico@215: 00091 timerValues.it_value.tv_nsec = tv_nsec; nico@215: 00092 timerValues.it_interval.tv_sec = 0; nico@215: 00093 timerValues.it_interval.tv_nsec = 0; nico@215: 00094 etisserant@240: 00095 timer_settime (timer, 0, &timerValues, NULL); nico@215: 00096 } nico@215: 00097 etisserant@240: 00098 TIMEVAL getElapsedTime(void) nico@215: 00099 { nico@215: 00100 struct timeval p; nico@215: 00101 gettimeofday(&p,NULL); nico@215: 00102 // printf("getCurrentTime() return=%u\n", p.tv_usec); etisserant@240: 00103 return (p.tv_sec - last_sig.tv_sec)* 1000000 + p.tv_usec - last_sig.tv_usec; nico@215: 00104 } etisserant@240: