drivers/timers_win32/timers_win32.c
author Edouard TISSERANT <edouard.tisserant@gmail.com>
Wed, 16 Dec 2009 10:15:09 +0100
changeset 621 609aff93810a
parent 606 15a175f6305d
child 629 b9274b595650
permissions -rw-r--r--
fixed typo in makefile
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
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    80
int TimerThreadLoop(void)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    81
{
605
f91ee161b3a1 -add LeaveMutex to avoid canopenshell deadlock when call NodeInit
greg
parents: 591
diff changeset
    82
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    83
571
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
    84
	while(!stop_timer)
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    85
	{
571
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
    86
		WaitForSingleObject(timer, INFINITE);
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
    87
		if(stop_timer)
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
    88
			break;
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    89
		_ftime(&timebuffer);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    90
		EnterMutex();
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    91
		TimeDispatch();
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    92
		LeaveMutex();
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    93
	}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    94
	return 0;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    95
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    96
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    97
void TimerInit(void)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    98
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
    99
	LARGE_INTEGER liDueTime;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   100
	liDueTime.QuadPart = 0;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   101
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   102
	InitializeCriticalSection(&CanFestival_mutex);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   103
571
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
   104
	timer = CreateWaitableTimer(NULL, FALSE, NULL);
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   105
	if(NULL == timer)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   106
    {
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   107
        printf("CreateWaitableTimer failed (%d)\n", GetLastError());
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   108
    }
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   109
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   110
	// Take first absolute time ref in milliseconds.
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   111
	_ftime(&timebuffer);
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
void TimerCleanup(void)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   115
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   116
	DeleteCriticalSection(&CanFestival_mutex);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   117
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   118
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   119
void StopTimerLoop(TimerCallback_t exitfunction)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   120
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   121
	EnterMutex();
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   122
	exitfunction(NULL,0);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   123
	LeaveMutex();
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   124
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   125
	stop_timer = 1;
571
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
   126
	setTimer(0);
599
b2d2c3fab094 Added timeout for waiting timer thread end on windows.
edouard
parents: 591
diff changeset
   127
	if(WaitForSingleObject(timer_thread,1000) == WAIT_TIMEOUT)
b2d2c3fab094 Added timeout for waiting timer thread end on windows.
edouard
parents: 591
diff changeset
   128
	{
b2d2c3fab094 Added timeout for waiting timer thread end on windows.
edouard
parents: 591
diff changeset
   129
		TerminateThread(timer_thread, -1);
b2d2c3fab094 Added timeout for waiting timer thread end on windows.
edouard
parents: 591
diff changeset
   130
	}
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   131
	CloseHandle(timer);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   132
	CloseHandle(timer_thread);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   133
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   134
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   135
void StartTimerLoop(TimerCallback_t _init_callback)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   136
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   137
	unsigned long timer_thread_id;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   138
	stop_timer = 0;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   139
	init_callback = _init_callback;
605
f91ee161b3a1 -add LeaveMutex to avoid canopenshell deadlock when call NodeInit
greg
parents: 591
diff changeset
   140
	EnterMutex();
f91ee161b3a1 -add LeaveMutex to avoid canopenshell deadlock when call NodeInit
greg
parents: 591
diff changeset
   141
		// At first, TimeDispatch will call init_callback.
f91ee161b3a1 -add LeaveMutex to avoid canopenshell deadlock when call NodeInit
greg
parents: 591
diff changeset
   142
	SetAlarm(NULL, 0, init_callback, 0, 0);
f91ee161b3a1 -add LeaveMutex to avoid canopenshell deadlock when call NodeInit
greg
parents: 591
diff changeset
   143
	LeaveMutex();
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   144
	timer_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TimerThreadLoop, NULL, 0, &timer_thread_id);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   145
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   146
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   147
/* Set the next alarm */
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   148
void setTimer(TIMEVAL value)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   149
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   150
	if(value == TIMEVAL_MAX)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   151
		CancelWaitableTimer(timer);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   152
	else
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   153
	{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   154
		LARGE_INTEGER liDueTime;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   155
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   156
		/* arg 2 of SetWaitableTimer take 100 ns interval */
591
513f5ec8b628 add extern C to maintain compatibility with C++
greg
parents: 577
diff changeset
   157
		liDueTime.QuadPart = (-1 * value);
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   158
		//printf("SetTimer(%llu)\n", value);
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   159
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   160
		if (!SetWaitableTimer(timer, &liDueTime, 0, NULL, NULL, FALSE))
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   161
		{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   162
			printf("SetWaitableTimer failed (%d)\n", GetLastError());
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   163
		}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   164
	}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   165
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   166
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   167
/* Get the elapsed time since the last occured alarm */
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   168
TIMEVAL getElapsedTime(void)
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   169
{
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   170
	struct _timeb timetmp;
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   171
	_ftime(&timetmp);
571
6eddab0b7ca8 fix method to exit properly the Timer Loop
greg
parents: 556
diff changeset
   172
	return (timetmp.time - timebuffer.time) * 10000000 + (timetmp.millitm - timebuffer.millitm) * 10000;
556
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   173
}
8296acd119a9 Rewrite win32 code (C only)
greg
parents:
diff changeset
   174