drivers/timers_win32/timers_win32.c
author Christian Taedcke <hacking@taedcke.com>
Thu, 22 Dec 2011 11:42:44 +0100
changeset 673 f511d955ac30
parent 629 b9274b595650
child 680 9a2474509269
permissions -rw-r--r--
FIXED: - the macro SUB_PROG_CFLAGS was overwritten for 64bit machines using gcc. Because of this the xenomai compilation failed.
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
     1
/*
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
     2
This file is part of CanFestival, a library implementing CanOpen Stack.
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
     3
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
     4
Copyright (C): Edouard TISSERANT and Francis DUPIN
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
     5
Copyright (C) Win32 Port Leonid Tochinski
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
     6
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
     7
See COPYING file for copyrights details.
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
     8
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
     9
This library is free software; you can redistribute it and/or
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    10
modify it under the terms of the GNU Lesser General Public
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    11
License as published by the Free Software Foundation; either
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    12
version 2.1 of the License, or (at your option) any later version.
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    13
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    14
This library is distributed in the hope that it will be useful,
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    15
but WITHOUT ANY WARRANTY; without even the implied warranty of
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    17
Lesser General Public License for more details.
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    18
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    19
You should have received a copy of the GNU Lesser General Public
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    20
License along with this library; if not, write to the Free Software
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    21
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    22
*/
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    23
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    24
#include <windows.h>
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    25
#include <stdlib.h>
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    26
#include <sys/timeb.h>
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    27
591
513f5ec8b628 add extern C to maintain compatibility with C++
greg
parents: 577
diff changeset
    28
#ifdef __cplusplus
513f5ec8b628 add extern C to maintain compatibility with C++
greg
parents: 577
diff changeset
    29
extern "C" {
513f5ec8b628 add extern C to maintain compatibility with C++
greg
parents: 577
diff changeset
    30
#endif
513f5ec8b628 add extern C to maintain compatibility with C++
greg
parents: 577
diff changeset
    31
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    32
#include "applicfg.h"
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    33
#include "can_driver.h"
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    34
#include "timer.h"
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    35
#include "timers_driver.h"
591
513f5ec8b628 add extern C to maintain compatibility with C++
greg
parents: 577
diff changeset
    36
513f5ec8b628 add extern C to maintain compatibility with C++
greg
parents: 577
diff changeset
    37
#ifdef __cplusplus
577
0bb82be64630 add extern \"C\" to keep compatibilty with C++
greg
parents: 575
diff changeset
    38
};
591
513f5ec8b628 add extern C to maintain compatibility with C++
greg
parents: 577
diff changeset
    39
#endif
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    40
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    41
struct _timeb timebuffer;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    42
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    43
/* Synchronization Object Implementation */
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    44
CRITICAL_SECTION CanFestival_mutex;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    45
HANDLE timer_thread = NULL;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    46
HANDLE timer = NULL;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    47
575
18db803e593f fix warning when compile
greg
parents: 571
diff changeset
    48
int stop_timer=0;
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    49
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    50
static TimerCallback_t init_callback;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    51
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    52
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    53
void EnterMutex(void)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    54
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    55
	EnterCriticalSection(&CanFestival_mutex);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    56
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    57
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    58
void LeaveMutex(void)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    59
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    60
	LeaveCriticalSection(&CanFestival_mutex);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    61
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    62
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    63
// --------------- CAN Receive Thread Implementation ---------------
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    64
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    65
void CreateReceiveTask(CAN_HANDLE fd0, TASK_HANDLE* Thread, void* ReceiveLoopPtr)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    66
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    67
	unsigned long thread_id = 0;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    68
	*Thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReceiveLoopPtr, fd0, 0, &thread_id);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    69
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    70
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    71
void WaitReceiveTaskEnd(TASK_HANDLE *Thread)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    72
{
600
7767029937aa add timeout for waitreceivetaskend for the win32, fix GetLastError print
'Gr?gory Tr?lat <gregory.trelat@lolitech.fr>'
parents: 591
diff changeset
    73
	if(WaitForSingleObject(*Thread, 1000) == WAIT_TIMEOUT)
7767029937aa add timeout for waitreceivetaskend for the win32, fix GetLastError print
'Gr?gory Tr?lat <gregory.trelat@lolitech.fr>'
parents: 591
diff changeset
    74
	{
7767029937aa add timeout for waitreceivetaskend for the win32, fix GetLastError print
'Gr?gory Tr?lat <gregory.trelat@lolitech.fr>'
parents: 591
diff changeset
    75
		TerminateThread(*Thread, -1);
7767029937aa add timeout for waitreceivetaskend for the win32, fix GetLastError print
'Gr?gory Tr?lat <gregory.trelat@lolitech.fr>'
parents: 591
diff changeset
    76
	}
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    77
	CloseHandle(*Thread);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    78
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    79
629
b9274b595650 CosateQ contribution.
edouard
parents: 606
diff changeset
    80
#if !defined(WIN32) || defined(__CYGWIN__)
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    81
int TimerThreadLoop(void)
629
b9274b595650 CosateQ contribution.
edouard
parents: 606
diff changeset
    82
#else
b9274b595650 CosateQ contribution.
edouard
parents: 606
diff changeset
    83
DWORD TimerThreadLoop(LPVOID arg)
b9274b595650 CosateQ contribution.
edouard
parents: 606
diff changeset
    84
#endif
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    85
{
605
f91ee161b3a1 -add LeaveMutex to avoid canopenshell deadlock when call NodeInit
greg
parents: 591
diff changeset
    86
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    87
571
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
    88
	while(!stop_timer)
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    89
	{
571
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
    90
		WaitForSingleObject(timer, INFINITE);
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
    91
		if(stop_timer)
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
    92
			break;
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    93
		_ftime(&timebuffer);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    94
		EnterMutex();
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    95
		TimeDispatch();
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    96
		LeaveMutex();
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    97
	}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    98
	return 0;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    99
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   100
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   101
void TimerInit(void)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   102
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   103
	LARGE_INTEGER liDueTime;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   104
	liDueTime.QuadPart = 0;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   105
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   106
	InitializeCriticalSection(&CanFestival_mutex);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   107
571
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
   108
	timer = CreateWaitableTimer(NULL, FALSE, NULL);
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   109
	if(NULL == timer)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   110
    {
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   111
        printf("CreateWaitableTimer failed (%d)\n", GetLastError());
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   112
    }
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   113
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   114
	// Take first absolute time ref in milliseconds.
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   115
	_ftime(&timebuffer);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   116
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   117
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   118
void TimerCleanup(void)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   119
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   120
	DeleteCriticalSection(&CanFestival_mutex);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   121
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   122
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   123
void StopTimerLoop(TimerCallback_t exitfunction)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   124
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   125
	EnterMutex();
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   126
	exitfunction(NULL,0);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   127
	LeaveMutex();
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   128
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   129
	stop_timer = 1;
571
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
   130
	setTimer(0);
599
b2d2c3fab094 Added timeout for waiting timer thread end on windows.
edouard
parents: 591
diff changeset
   131
	if(WaitForSingleObject(timer_thread,1000) == WAIT_TIMEOUT)
b2d2c3fab094 Added timeout for waiting timer thread end on windows.
edouard
parents: 591
diff changeset
   132
	{
b2d2c3fab094 Added timeout for waiting timer thread end on windows.
edouard
parents: 591
diff changeset
   133
		TerminateThread(timer_thread, -1);
b2d2c3fab094 Added timeout for waiting timer thread end on windows.
edouard
parents: 591
diff changeset
   134
	}
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   135
	CloseHandle(timer);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   136
	CloseHandle(timer_thread);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   137
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   138
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   139
void StartTimerLoop(TimerCallback_t _init_callback)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   140
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   141
	unsigned long timer_thread_id;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   142
	stop_timer = 0;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   143
	init_callback = _init_callback;
605
f91ee161b3a1 -add LeaveMutex to avoid canopenshell deadlock when call NodeInit
greg
parents: 591
diff changeset
   144
	EnterMutex();
f91ee161b3a1 -add LeaveMutex to avoid canopenshell deadlock when call NodeInit
greg
parents: 591
diff changeset
   145
		// At first, TimeDispatch will call init_callback.
f91ee161b3a1 -add LeaveMutex to avoid canopenshell deadlock when call NodeInit
greg
parents: 591
diff changeset
   146
	SetAlarm(NULL, 0, init_callback, 0, 0);
f91ee161b3a1 -add LeaveMutex to avoid canopenshell deadlock when call NodeInit
greg
parents: 591
diff changeset
   147
	LeaveMutex();
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   148
	timer_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TimerThreadLoop, NULL, 0, &timer_thread_id);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   149
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   150
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   151
/* Set the next alarm */
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   152
void setTimer(TIMEVAL value)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   153
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   154
	if(value == TIMEVAL_MAX)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   155
		CancelWaitableTimer(timer);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   156
	else
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   157
	{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   158
		LARGE_INTEGER liDueTime;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   159
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   160
		/* arg 2 of SetWaitableTimer take 100 ns interval */
591
513f5ec8b628 add extern C to maintain compatibility with C++
greg
parents: 577
diff changeset
   161
		liDueTime.QuadPart = (-1 * value);
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   162
		//printf("SetTimer(%llu)\n", value);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   163
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   164
		if (!SetWaitableTimer(timer, &liDueTime, 0, NULL, NULL, FALSE))
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   165
		{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   166
			printf("SetWaitableTimer failed (%d)\n", GetLastError());
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   167
		}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   168
	}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   169
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   170
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   171
/* Get the elapsed time since the last occured alarm */
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   172
TIMEVAL getElapsedTime(void)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   173
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   174
	struct _timeb timetmp;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   175
	_ftime(&timetmp);
571
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
   176
	return (timetmp.time - timebuffer.time) * 10000000 + (timetmp.millitm - timebuffer.millitm) * 10000;
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   177
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   178