drivers/timers_unix/timers_unix.c
author fbeaulier
Tue, 16 Aug 2011 14:15:52 +0200
changeset 663 70fc3603e36f
parent 631 08b6b903f84a
child 793 72e9e1064432
permissions -rw-r--r--
timers_unix.c : remove sigint and sigterm catch
sdo : Allow multiple servers
The sdo transfer struct is not anymore referenced by server's node id but by
client or server number in the OD. Node id is not relevant in SDO transfert.
0
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
     1
#include <stdlib.h>
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
     2
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
     3
#include <sys/time.h>
32
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
     4
#include <pthread.h> 
0
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
     5
#include <signal.h>
631
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
     6
#include <time.h>
0
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
     7
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
     8
#include "applicfg.h"
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
     9
#include "timer.h"
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
    10
631
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
    11
static pthread_mutex_t CanFestival_mutex = PTHREAD_MUTEX_INITIALIZER;
0
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
    12
631
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
    13
static struct timeval last_sig;
32
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    14
631
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
    15
static timer_t timer;
0
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
    16
454
bc000083297a - add RTAI support
greg
parents: 401
diff changeset
    17
void TimerCleanup(void)
bc000083297a - add RTAI support
greg
parents: 401
diff changeset
    18
{
bc000083297a - add RTAI support
greg
parents: 401
diff changeset
    19
	/* only used in realtime apps */
bc000083297a - add RTAI support
greg
parents: 401
diff changeset
    20
}
bc000083297a - add RTAI support
greg
parents: 401
diff changeset
    21
0
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
    22
void EnterMutex(void)
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
    23
{
631
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
    24
	if(pthread_mutex_lock(&CanFestival_mutex)) {
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
    25
		fprintf(stderr, "pthread_mutex_lock() failed\n");
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
    26
	}
0
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
    27
}
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
    28
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
    29
void LeaveMutex(void)
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
    30
{
631
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
    31
	if(pthread_mutex_unlock(&CanFestival_mutex)) {
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
    32
		fprintf(stderr, "pthread_mutex_unlock() failed\n");
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
    33
	}
0
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
    34
}
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
    35
145
e747d2e26af0 Win32 Native support and dynamicaly loaded CAN drivers for Linux, Cygwin and Win32.
etisserant
parents: 48
diff changeset
    36
void timer_notify(sigval_t val)
32
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    37
{
631
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
    38
	if(gettimeofday(&last_sig,NULL)) {
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
    39
		perror("gettimeofday()");
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
    40
	}
32
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    41
	EnterMutex();
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    42
	TimeDispatch();
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    43
	LeaveMutex();
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    44
//	printf("getCurrentTime() return=%u\n", p.tv_usec);
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    45
}
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    46
454
bc000083297a - add RTAI support
greg
parents: 401
diff changeset
    47
void TimerInit(void)
32
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    48
{
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    49
	struct sigevent sigev;
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    50
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    51
	// Take first absolute time ref.
631
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
    52
	if(gettimeofday(&last_sig,NULL)){
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
    53
		perror("gettimeofday()");
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
    54
	}
32
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    55
607
5fec528f66cf create specific timer thread for UCLIBC support (with CLOCK_PROCESS_CPUTIME_ID parameter)
greg
parents: 540
diff changeset
    56
#if defined(__UCLIBC__)
5fec528f66cf create specific timer thread for UCLIBC support (with CLOCK_PROCESS_CPUTIME_ID parameter)
greg
parents: 540
diff changeset
    57
	int ret;
5fec528f66cf create specific timer thread for UCLIBC support (with CLOCK_PROCESS_CPUTIME_ID parameter)
greg
parents: 540
diff changeset
    58
	ret = timer_create(CLOCK_PROCESS_CPUTIME_ID, NULL, &timer);
5fec528f66cf create specific timer thread for UCLIBC support (with CLOCK_PROCESS_CPUTIME_ID parameter)
greg
parents: 540
diff changeset
    59
	signal(SIGALRM, timer_notify);
5fec528f66cf create specific timer thread for UCLIBC support (with CLOCK_PROCESS_CPUTIME_ID parameter)
greg
parents: 540
diff changeset
    60
#else
32
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    61
	memset (&sigev, 0, sizeof (struct sigevent));
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    62
	sigev.sigev_value.sival_int = 0;
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    63
	sigev.sigev_notify = SIGEV_THREAD;
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    64
	sigev.sigev_notify_attributes = NULL;
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    65
	sigev.sigev_notify_function = timer_notify;
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    66
631
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
    67
	if(timer_create (CLOCK_REALTIME, &sigev, &timer)) {
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
    68
		perror("timer_create()");
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
    69
	}
607
5fec528f66cf create specific timer thread for UCLIBC support (with CLOCK_PROCESS_CPUTIME_ID parameter)
greg
parents: 540
diff changeset
    70
#endif
32
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    71
}
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    72
454
bc000083297a - add RTAI support
greg
parents: 401
diff changeset
    73
void StopTimerLoop(TimerCallback_t exitfunction)
32
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    74
{
149
fe50ada8020b Changes in the API:
etisserant
parents: 145
diff changeset
    75
	EnterMutex();
631
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
    76
	if(timer_delete (timer)) {
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
    77
		perror("timer_delete()");
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
    78
	}
454
bc000083297a - add RTAI support
greg
parents: 401
diff changeset
    79
	exitfunction(NULL,0);
149
fe50ada8020b Changes in the API:
etisserant
parents: 145
diff changeset
    80
	LeaveMutex();
32
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    81
}
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    82
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
    83
void StartTimerLoop(TimerCallback_t init_callback)
0
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
    84
{
149
fe50ada8020b Changes in the API:
etisserant
parents: 145
diff changeset
    85
	EnterMutex();
0
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
    86
	// At first, TimeDispatch will call init_callback.
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
    87
	SetAlarm(NULL, 0, init_callback, 0, 0);
149
fe50ada8020b Changes in the API:
etisserant
parents: 145
diff changeset
    88
	LeaveMutex();
0
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
    89
}
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
    90
507
c613e6cd34fa Added more correct signal handling to unix timers.
etisserant
parents: 454
diff changeset
    91
void canReceiveLoop_signal(int sig)
c613e6cd34fa Added more correct signal handling to unix timers.
etisserant
parents: 454
diff changeset
    92
{
c613e6cd34fa Added more correct signal handling to unix timers.
etisserant
parents: 454
diff changeset
    93
}
c613e6cd34fa Added more correct signal handling to unix timers.
etisserant
parents: 454
diff changeset
    94
/* We assume that ReceiveLoop_task_proc is always the same */
508
08adb8d4b098 Added more correct signal handling to unix timers.
etisserant
parents: 507
diff changeset
    95
static void (*unixtimer_ReceiveLoop_task_proc)(CAN_PORT) = NULL;
507
c613e6cd34fa Added more correct signal handling to unix timers.
etisserant
parents: 454
diff changeset
    96
c613e6cd34fa Added more correct signal handling to unix timers.
etisserant
parents: 454
diff changeset
    97
/**
c613e6cd34fa Added more correct signal handling to unix timers.
etisserant
parents: 454
diff changeset
    98
 * Enter in realtime and start the CAN receiver loop
c613e6cd34fa Added more correct signal handling to unix timers.
etisserant
parents: 454
diff changeset
    99
 * @param port
c613e6cd34fa Added more correct signal handling to unix timers.
etisserant
parents: 454
diff changeset
   100
 */
540
6857b6ffb7a7 Removed some warnings.
etisserant
parents: 508
diff changeset
   101
void* unixtimer_canReceiveLoop(void* port)
507
c613e6cd34fa Added more correct signal handling to unix timers.
etisserant
parents: 454
diff changeset
   102
{
c613e6cd34fa Added more correct signal handling to unix timers.
etisserant
parents: 454
diff changeset
   103
    /*get signal*/
663
70fc3603e36f timers_unix.c : remove sigint and sigterm catch
fbeaulier
parents: 631
diff changeset
   104
  	//  if(signal(SIGTERM, canReceiveLoop_signal) == SIG_ERR) {
70fc3603e36f timers_unix.c : remove sigint and sigterm catch
fbeaulier
parents: 631
diff changeset
   105
	//		perror("signal()");
70fc3603e36f timers_unix.c : remove sigint and sigterm catch
fbeaulier
parents: 631
diff changeset
   106
	//}
540
6857b6ffb7a7 Removed some warnings.
etisserant
parents: 508
diff changeset
   107
    unixtimer_ReceiveLoop_task_proc((CAN_PORT)port);
631
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
   108
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
   109
    return NULL;
507
c613e6cd34fa Added more correct signal handling to unix timers.
etisserant
parents: 454
diff changeset
   110
}
c613e6cd34fa Added more correct signal handling to unix timers.
etisserant
parents: 454
diff changeset
   111
145
e747d2e26af0 Win32 Native support and dynamicaly loaded CAN drivers for Linux, Cygwin and Win32.
etisserant
parents: 48
diff changeset
   112
void CreateReceiveTask(CAN_PORT port, TASK_HANDLE* Thread, void* ReceiveLoopPtr)
0
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
   113
{
508
08adb8d4b098 Added more correct signal handling to unix timers.
etisserant
parents: 507
diff changeset
   114
    unixtimer_ReceiveLoop_task_proc = ReceiveLoopPtr;
631
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
   115
	if(pthread_create(Thread, NULL, unixtimer_canReceiveLoop, (void*)port)) {
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
   116
		perror("pthread_create()");
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
   117
	}
0
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
   118
}
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
   119
401
2c90876b9751 Fixed segfault on quit with Xenomai, due to bat parameter type in waitReceiveTaskEnd.
etisserant
parents: 149
diff changeset
   120
void WaitReceiveTaskEnd(TASK_HANDLE *Thread)
0
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
   121
{
631
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
   122
	if(pthread_kill(*Thread, SIGTERM)) {
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
   123
		perror("pthread_kill()");
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
   124
	}
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
   125
	if(pthread_join(*Thread, NULL)) {
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
   126
		perror("pthread_join()");
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
   127
	}
0
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
   128
}
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
   129
48
adc6572caf5d minval/maxval macro operators precedence fix. Thanks Luis Jim?nez.
etisserant
parents: 38
diff changeset
   130
#define maxval(a,b) ((a>b)?a:b)
0
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
   131
void setTimer(TIMEVAL value)
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
   132
{
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
   133
//	printf("setTimer(TIMEVAL value=%d)\n", value);
32
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
   134
	// TIMEVAL is us whereas setitimer wants ns...
38
9b5bb1dcb4f5 Cygwin port. Still untested. Compiles and link.
etisserant
parents: 35
diff changeset
   135
	long tv_nsec = 1000 * (maxval(value,1)%1000000);
32
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
   136
	time_t tv_sec = value/1000000;
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
   137
	struct itimerspec timerValues;
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
   138
	timerValues.it_value.tv_sec = tv_sec;
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
   139
	timerValues.it_value.tv_nsec = tv_nsec;
0
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
   140
	timerValues.it_interval.tv_sec = 0;
32
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
   141
	timerValues.it_interval.tv_nsec = 0;
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
   142
8afa33692372 SDO callbacks.
etisserant
parents: 0
diff changeset
   143
 	timer_settime (timer, 0, &timerValues, NULL);
0
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
   144
}
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
   145
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
   146
TIMEVAL getElapsedTime(void)
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
   147
{
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
   148
	struct timeval p;
631
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
   149
	if(gettimeofday(&p,NULL)) {
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
   150
		perror("gettimeofday()");
08b6b903f84a Piotr Trojanek (ptroja) cleanup patche. Thanks.
edouard
parents: 607
diff changeset
   151
	}
0
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
   152
//	printf("getCurrentTime() return=%u\n", p.tv_usec);
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
   153
	return (p.tv_sec - last_sig.tv_sec)* 1000000 + p.tv_usec - last_sig.tv_usec;
4472ee7c6c3e Commit a new cvs repo.
etisserant
parents:
diff changeset
   154
}