Dear Lars,

> Great that you have time to debug,fix and provide patches.
The message jitter corrupts my application ;).
http://www.aerosimrc.com/en/drone-training.htm#Users___ESC_Aerospace
  you can see PCAN-USB convertor in lower left corner.

 
> I have not testet the code, but I have a question:
> When you use DllMain, would that not create problems if you link static?
> Would it not be better to move the code in DllMain to initTimer
Yes, you are right here. I do not think such a way. I have never used static
linking, just because I do not need it.

I fixed my code and sending you a patch in attachment.

---

I can attempt to backport to some changes to shadow of your HG on bitbucket.

         My main problem of sharing same repository has been discussed long
before.
I am using DATA instead "data". "data" is a keyword and some compilers
refuses to compile CAN Festival.

regards
    Jara
/*
This file is part of CanFestival, a library implementing CanOpen Stack.

Copyright (C): Edouard TISSERANT and Francis DUPIN
Copyright (C) Win32 Port Leonid Tochinski
Modified by: Jaroslav Fojtik

See COPYING file for copyrights details.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include <windows.h>
#include <WinBase.h>
#include <stdlib.h>
#include <sys/timeb.h>


#ifdef __cplusplus
extern "C"
{
#endif
#include "applicfg.h"
#include "can_driver.h"
#include "timer.h"
#include "timers_driver.h"
#ifdef __cplusplus
};
#endif

//struct _timeb timebuffer;
DWORD timebuffer;
LARGE_INTEGER timebufferXL;
LARGE_INTEGER pFrequency = {0};


/* Synchronization Object Implementation */
CRITICAL_SECTION CanFestival_mutex;
HANDLE timer_thread = NULL;
HANDLE timer = NULL;

volatile int stop_timer=0;

static TimerCallback_t init_callback;


void EnterMutex(void)
{
  MSG_ERR(0x0, "Enter mutex", 0);
  EnterCriticalSection(&CanFestival_mutex);
}

void LeaveMutex(void)
{
  MSG_ERR(0x01, "Leave mutex", 0);
  LeaveCriticalSection(&CanFestival_mutex);
}

// --------------- CAN Receive Thread Implementation ---------------

void CreateReceiveTask(CAN_HANDLE fd0, TASK_HANDLE* Thread, void* ReceiveLoopPtr)
{
  unsigned long thread_id = 0;
  *Thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReceiveLoopPtr, fd0, 0, &thread_id);
  SetThreadPriority(*Thread, THREAD_PRIORITY_HIGHEST);
}


/** Wait one second to thread exit, otherwise kill it. */
void WaitReceiveTaskEnd(TASK_HANDLE *Thread)
{
  if(WaitForSingleObject(*Thread,1000) == WAIT_TIMEOUT)
  {
	TerminateThread(*Thread, -1);
  }
  CloseHandle(*Thread);
}


#if !defined(WIN32) || defined(__CYGWIN__)
int TimerThreadLoop(void)
#else
DWORD TimerThreadLoop(LPVOID arg)
#endif
{
  EnterMutex();
	// At first, TimeDispatch will call init_callback.
  SetAlarm(NULL, 0, init_callback, 0, 0);
  LeaveMutex();

  while(!stop_timer)
  {
    WaitForSingleObject(timer, INFINITE);
    if(stop_timer)
	break;

    EnterMutex();
    timebuffer = timeGetTime();		/* Fix from Roland Marquis */
    QueryPerformanceCounter(&timebufferXL);
    //_ftime(&timebuffer);
    TimeDispatch();
    LeaveMutex();
  }
  return 0;
}

void TimerInit(void)
{
	LARGE_INTEGER liDueTime;
	liDueTime.QuadPart = 0;

        if(QueryPerformanceFrequency(&pFrequency)==0)
	    pFrequency.QuadPart = 0;

	InitializeCriticalSection(&CanFestival_mutex);

	timer = CreateWaitableTimer(NULL, FALSE, NULL);
	if(NULL == timer)
    {
        printf("CreateWaitableTimer failed (%d)\n", GetLastError());
    }

	// Take first absolute time ref in milliseconds.
	timebuffer = timeGetTime();
        QueryPerformanceCounter(&timebufferXL);		/* Fix by J.Fojtik. */
	//_ftime(&timebuffer);
}

void TimerCleanup(void)
{
	DeleteCriticalSection(&CanFestival_mutex);
}

void StopTimerLoop(TimerCallback_t exitfunction)
{
	EnterMutex();
	exitfunction(NULL,0);
	LeaveMutex();

	stop_timer = 1;
	setTimer(0);	
	if(WaitForSingleObject(timer_thread,1000) == WAIT_TIMEOUT)
    {
	  TerminateThread(timer_thread, -1);
    }
	CloseHandle(timer);
	CloseHandle(timer_thread);
}


void StartTimerLoop(TimerCallback_t _init_callback)
{
	unsigned long timer_thread_id;
	stop_timer = 0;
	init_callback = _init_callback;
	EnterMutex();
		// At first, TimeDispatch will call init_callback.
	SetAlarm(NULL, 0, init_callback, 0, 0);
	LeaveMutex();
	timer_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TimerThreadLoop, NULL, 0, &timer_thread_id);
        SetThreadPriority(timer_thread, THREAD_PRIORITY_HIGHEST);	// JFO: Make timer thread wit highest priority.
}


/* Set the next alarm */
void setTimer(TIMEVAL value)
{
  if(value == TIMEVAL_MAX)
		CancelWaitableTimer(timer);
  else
  {
    LARGE_INTEGER liDueTime;

		/* arg 2 of SetWaitableTimer take 100 ns interval */
    liDueTime.QuadPart = -value;
		//printf("SetTimer(%llu)\n", value);

    if(!SetWaitableTimer(timer, &liDueTime, 0, NULL, NULL, FALSE))
    {
      printf("SetWaitableTimer failed (%d)\n", GetLastError());
    }
  }
}


/* Get the elapsed time since the last occured alarm.
 * Callibrated in 100ns quantum. */
TIMEVAL getElapsedTime(void)
{
  LARGE_INTEGER CurrentTime;

  // struct _timeb timetmp;
  // _ftime(&timetmp);
  // return (timetmp.time - timebuffer.time) * 10000000 + (timetmp.millitm - timebuffer.millitm) * 10000;

  if(pFrequency.QuadPart==0) 
    return (TIMEVAL)(timeGetTime()-timebuffer) * 10000;

  QueryPerformanceCounter(&CurrentTime);  
  return (TIMEVAL)(10000000*(CurrentTime.QuadPart-timebufferXL.QuadPart)/pFrequency.QuadPart);
}

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Canfestival-devel mailing list
Canfestival-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/canfestival-devel

Reply via email to