# HG changeset patch # User greg # Date 1247643396 -7200 # Node ID 8296acd119a9f482b7039087e041e4c03ce6a8f4 # Parent ee24dcbd3e64193cac1af33ae995faf2e7dca47e Rewrite win32 code (C only) diff -r ee24dcbd3e64 -r 8296acd119a9 drivers/timers_win32/Makefile.in --- a/drivers/timers_win32/Makefile.in Wed Jul 15 09:32:35 2009 +0200 +++ b/drivers/timers_win32/Makefile.in Wed Jul 15 09:36:36 2009 +0200 @@ -46,7 +46,7 @@ driver: $(OBJS) -%o: %cpp +%o: %c $(CXX) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $< install: diff -r ee24dcbd3e64 -r 8296acd119a9 drivers/timers_win32/timers_win32.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/timers_win32/timers_win32.c Wed Jul 15 09:36:36 2009 +0200 @@ -0,0 +1,161 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN +Copyright (C) Win32 Port Leonid Tochinski + +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 +#include +#include + +#include "applicfg.h" +#include "can_driver.h" +#include "timer.h" +#include "timers_driver.h" + + +struct _timeb timebuffer; + +/* Synchronization Object Implementation */ +CRITICAL_SECTION CanFestival_mutex; +HANDLE timer_thread = NULL; +HANDLE timer = NULL; + +stop_timer=0; + +static TimerCallback_t init_callback; + + +void EnterMutex(void) +{ + EnterCriticalSection(&CanFestival_mutex); +} + +void LeaveMutex(void) +{ + 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); +} + +void WaitReceiveTaskEnd(TASK_HANDLE *Thread) +{ + WaitForSingleObject(*Thread, INFINITE); + CloseHandle(*Thread); +} + +int TimerThreadLoop(void) +{ + int ret = 0; + EnterMutex(); + // At first, TimeDispatch will call init_callback. + SetAlarm(NULL, 0, init_callback, 0, 0); + LeaveMutex(); + + while(!stop_timer && ret == WAIT_OBJECT_0) + { + ret = WaitForSingleObject(timer, INFINITE); + _ftime(&timebuffer); + EnterMutex(); + TimeDispatch(); + LeaveMutex(); + } + return 0; +} + +void TimerInit(void) +{ + LARGE_INTEGER liDueTime; + liDueTime.QuadPart = 0; + + InitializeCriticalSection(&CanFestival_mutex); + + timer = CreateWaitableTimer(NULL, TRUE, NULL); + if(NULL == timer) + { + printf("CreateWaitableTimer failed (%d)\n", GetLastError()); + } + + // Take first absolute time ref in milliseconds. + _ftime(&timebuffer); +} + +void TimerCleanup(void) +{ + DeleteCriticalSection(&CanFestival_mutex); +} + +void StopTimerLoop(TimerCallback_t exitfunction) +{ + EnterMutex(); + exitfunction(NULL,0); + LeaveMutex(); + + stop_timer = 1; + CloseHandle(timer); + WaitForSingleObject(timer_thread, INFINITE); + CloseHandle(timer_thread); +} + +void StartTimerLoop(TimerCallback_t _init_callback) +{ + unsigned long timer_thread_id; + stop_timer = 0; + init_callback = _init_callback; + timer_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TimerThreadLoop, NULL, 0, &timer_thread_id); +} + +/* Set the next alarm */ +void setTimer(TIMEVAL value) +{ + if(value == TIMEVAL_MAX) + { + /* cancel timer */ + 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 */ +TIMEVAL getElapsedTime(void) +{ + struct _timeb timetmp; + _ftime(&timetmp); + return (timetmp.time - timebuffer.time) * 1000000 + (timetmp.millitm - timebuffer.millitm) * 1000; +} + diff -r ee24dcbd3e64 -r 8296acd119a9 drivers/timers_win32/timers_win32.cpp --- a/drivers/timers_win32/timers_win32.cpp Wed Jul 15 09:32:35 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,246 +0,0 @@ -/* -This file is part of CanFestival, a library implementing CanOpen Stack. - -Copyright (C): Edouard TISSERANT and Francis DUPIN -Copyright (C) Win32 Port Leonid Tochinski - -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 -#include - -extern "C" -{ -#include "applicfg.h" -#include "can_driver.h" -#include "timer.h" -#include "timers_driver.h" -}; - -// --------------- Synchronization Object Implementation --------------- -class ccritical_section - { - public: - ccritical_section() - { - ::InitializeCriticalSection(&m_cs); - } - ~ccritical_section() - { - ::DeleteCriticalSection(&m_cs); - } - void enter() - { - ::EnterCriticalSection(&m_cs); - } - void leave() - { - ::LeaveCriticalSection(&m_cs); - } - private: - CRITICAL_SECTION m_cs; - }; - -static ccritical_section g_cs; - - -void EnterMutex(void) - { - g_cs.enter(); - } - -void LeaveMutex(void) - { - g_cs.leave(); - } -// --------------- Synchronization Object Implementation --------------- - - -// --------------- 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); - } - -void WaitReceiveTaskEnd(TASK_HANDLE *Thread) - { - ::WaitForSingleObject(*Thread, INFINITE); - ::CloseHandle(*Thread); - //*Thread = NULL; - } -// --------------- CAN Receive Thread Implementation --------------- - - -// --------------- Timer Thread Implementation --------------- -class class_timers - { - public: - class_timers(); - ~class_timers(); - void start_timer_thread(); - void resume_timer_thread(); - void stop_timer_thread(); - void set_timer(TIMEVAL value); - TIMEVAL get_elapsed_time(); - private: - TIMEVAL get_timer() const; - static DWORD WINAPI timer_loop_thread_proc(void* arg); - private: - TIMEVAL m_last_occured_alarm_time; - volatile TIMEVAL m_last_alarm_set_time; - HANDLE m_timer_thread; - volatile bool m_continue_timer_loop; - bool m_use_hi_res_timer; - double m_counts_per_usec; - }; - -class_timers::class_timers() : m_last_occured_alarm_time(TIMEVAL_MAX), - m_last_alarm_set_time(TIMEVAL_MAX), - m_timer_thread(0), - m_continue_timer_loop(false), - m_use_hi_res_timer(false), - m_counts_per_usec(0.) - { - // initialize hi resolution timer - LARGE_INTEGER counts_per_sec = {0, 0}; - if (::QueryPerformanceFrequency(&counts_per_sec) && counts_per_sec.QuadPart > 0) - { - m_use_hi_res_timer = true; - m_counts_per_usec = counts_per_sec.QuadPart / 1000000.; - } - m_use_hi_res_timer = true; - } - -class_timers::~class_timers() - { - stop_timer_thread(); - } - -// time is in micro seconds -TIMEVAL class_timers::get_timer() const - { - if (m_use_hi_res_timer) - { - LARGE_INTEGER performance_count = {0, 0}; - ::QueryPerformanceCounter(&performance_count); - return (TIMEVAL)(performance_count.QuadPart / m_counts_per_usec); - } - // hi-res timer is unavailable - return 1000 * ::GetTickCount(); - } - -DWORD WINAPI class_timers::timer_loop_thread_proc(void* arg) - { - class_timers* This = reinterpret_cast(arg); - while (This->m_continue_timer_loop) - { - TIMEVAL cur_time = This->get_timer(); - if (cur_time >= This->m_last_alarm_set_time) - { - This->m_last_occured_alarm_time = cur_time; - This->m_last_alarm_set_time = TIMEVAL_MAX; - EnterMutex(); - TimeDispatch(); - LeaveMutex(); - } - else - { - ::Sleep(1); - } - } - return 0; - } - -void class_timers::start_timer_thread() - { - if (m_timer_thread == 0) - { - unsigned long thread_id = 0; - m_timer_thread = ::CreateThread(NULL, 0, &timer_loop_thread_proc, this, CREATE_SUSPENDED, &thread_id); - m_last_alarm_set_time = TIMEVAL_MAX; - m_last_occured_alarm_time = get_timer(); - } - } - -void class_timers::resume_timer_thread() - { - if (m_timer_thread) - { - m_continue_timer_loop = true; - ::ResumeThread(m_timer_thread); - } - } - -void class_timers::stop_timer_thread() - { - if (m_timer_thread) - { - m_continue_timer_loop = false; - ::WaitForSingleObject(m_timer_thread, INFINITE); - ::CloseHandle(m_timer_thread); - m_timer_thread = 0; - } - } - -void class_timers::set_timer(TIMEVAL value) - { - m_last_alarm_set_time = (value == TIMEVAL_MAX) ? TIMEVAL_MAX : get_timer() + value; - } - -// elapsed time since last occured alarm -TIMEVAL class_timers::get_elapsed_time() - { - return get_timer() - m_last_occured_alarm_time; - } - -// ---------------------------------------------------------- - -static class_timers s_timers; - -void TimerCleanup(void) -{ - /* only used in realtime apps */ -} - -void StartTimerLoop(TimerCallback_t init_callback) - { - s_timers.start_timer_thread(); - // At first, TimeDispatch will call init_callback. - if (init_callback != NULL) - SetAlarm(NULL, 0, init_callback, (TIMEVAL)0, (TIMEVAL)0); - s_timers.resume_timer_thread(); - } - -void StopTimerLoop(TimerCallback_t init_callback) - { - s_timers.stop_timer_thread(); - } - -void setTimer(TIMEVAL value) - { - s_timers.set_timer(value); - } - -TIMEVAL getElapsedTime(void) - { - return s_timers.get_elapsed_time(); - } diff -r ee24dcbd3e64 -r 8296acd119a9 drivers/win32/Makefile.in --- a/drivers/win32/Makefile.in Wed Jul 15 09:32:35 2009 +0200 +++ b/drivers/win32/Makefile.in Wed Jul 15 09:36:36 2009 +0200 @@ -54,7 +54,7 @@ driver: $(OBJS) -%o: %cpp +%o: %c $(CXX) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $< #../$(TIMERS_DRIVER)/$(TIMERS_DRIVER).o: diff -r ee24dcbd3e64 -r 8296acd119a9 drivers/win32/win32.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/win32/win32.c Wed Jul 15 09:36:36 2009 +0200 @@ -0,0 +1,200 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN +Copyright (C) Win32 Port Leonid Tochinski + +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 +*/ + +/* + CAN driver interface. +*/ + +#include + +#include "canfestival.h" +#include "timer.h" +#include "timers_driver.h" + +// GetProcAddress doesn't have an UNICODE version for NT +#ifdef UNDER_CE + #define myTEXT(str) TEXT(str) +#else + #define myTEXT(str) str +#endif + +#define MAX_NB_CAN_PORTS 16 + +typedef UNS8 (CALLBACK* CANRECEIVE_DRIVER_PROC)(void* inst, Message *m); +typedef UNS8 (CALLBACK* CANSEND_DRIVER_PROC)(void* inst, const Message *m); +typedef void* (CALLBACK* CANOPEN_DRIVER_PROC)(s_BOARD *board); +typedef int (CALLBACK* CANCLOSE_DRIVER_PROC)(void* inst); +typedef UNS8 (CALLBACK* CANCHANGEBAUDRATE_DRIVER_PROC)(void* fd, char* baud); + +CANRECEIVE_DRIVER_PROC m_canReceive; +CANSEND_DRIVER_PROC m_canSend; +CANOPEN_DRIVER_PROC m_canOpen; +CANCLOSE_DRIVER_PROC m_canClose; +CANCHANGEBAUDRATE_DRIVER_PROC m_canChangeBaudRate; + +/* CAN port structure */ +typedef struct +{ + char used; /**< flag indicating CAN port usage, will be used to abort Receiver task*/ + CAN_HANDLE fd; /**< CAN port file descriptor*/ + TASK_HANDLE receiveTask; /**< CAN Receiver task*/ + CO_Data* d; /**< CAN object data*/ +}CANPort; + +CANPort canports[MAX_NB_CAN_PORTS] = {{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,}}; + + +/***************************************************************************/ +UNS8 UnLoadCanDriver(LIB_HANDLE handle) +{ + if(handle != NULL) + { + FreeLibrary(handle); + handle=NULL; + return 0; + } + return -1; +} + +/***************************************************************************/ +/** + * Loads the dll and get funcs ptr + * + * @param driver_name String containing driver's dynamic library name + * @return Library handle + */ +LIB_HANDLE LoadCanDriver(LPCTSTR driver_name) +{ + // driver module handle + LIB_HANDLE handle = NULL; + + if(handle == NULL) + { + handle = LoadLibrary(driver_name); + } + + if (!handle) + { + fprintf (stderr, "%s\n", GetLastError()); + return NULL; + } + + m_canReceive = (CANRECEIVE_DRIVER_PROC)GetProcAddress(handle, myTEXT("canReceive_driver")); + m_canSend = (CANSEND_DRIVER_PROC)GetProcAddress(handle, myTEXT("canSend_driver")); + m_canOpen = (CANOPEN_DRIVER_PROC)GetProcAddress(handle, myTEXT("canOpen_driver")); + m_canClose = (CANCLOSE_DRIVER_PROC)GetProcAddress(handle, myTEXT("canClose_driver")); + m_canChangeBaudRate = (CANCHANGEBAUDRATE_DRIVER_PROC)GetProcAddress(handle, myTEXT("canChangeBaudRate_driver")); + + return handle; +} + +/***************************************************************************/ +UNS8 canSend(CAN_PORT port, Message *m) +{ + UNS8 res; + if (port && (m_canSend != NULL)) + { + res = m_canSend(((CANPort*)port)->fd, m); + if (res) return 1; // OK + } + return 0; // NOT OK +} + +/***************************************************************************/ +void canReceiveLoop(CAN_PORT port) +{ + Message m; + while(((CANPort*)port)->used) + { + if(m_canReceive(((CANPort*)port)->fd, &m) != 0) break; + EnterMutex(); + canDispatch(((CANPort*)port)->d, &m); + LeaveMutex(); + } +} + +/***************************************************************************/ +CAN_HANDLE canOpen(s_BOARD *board, CO_Data * d) +{ + int i; + for(i=0; i < MAX_NB_CAN_PORTS; i++) + { + if(!canports[i].used) + break; + } + + #ifndef NOT_USE_DYNAMIC_LOADING + if (m_canOpen == NULL) + { + fprintf(stderr,"CanOpen : Can Driver dll not loaded\n"); + return NULL; + } + #endif + + CAN_HANDLE fd0 = m_canOpen(board); + if(fd0) + { + canports[i].used = 1; + canports[i].fd = fd0; + canports[i].d = d; + d->canHandle = (CAN_PORT)&canports[i]; + CreateReceiveTask(&(canports[i]), &canports[i].receiveTask, &canReceiveLoop); + return (CAN_PORT)&canports[i]; + } + else + { + MSG("CanOpen : Cannot open board {busname='%s',baudrate='%s'}\n",board->busname, board->baudrate); + return NULL; + } +} + +/***************************************************************************/ +int canClose(CO_Data * d) +{ + UNS8 res; + + ((CANPort*)d->canHandle)->used = 0; + CANPort* tmp = (CANPort*)d->canHandle; + d->canHandle = NULL; + + // close CAN port + res = m_canClose(tmp->fd); + + // kill receiver task + WaitReceiveTaskEnd(&tmp->receiveTask); + + return res; +} + +UNS8 canChangeBaudRate(CAN_PORT port, char* baud) +{ + if(port){ + UNS8 res; + //LeaveMutex(); + res = m_canChangeBaudRate(((CANPort*)port)->fd, baud); + //EnterMutex(); + return res; // OK + } + return 1; // NOT OK +} + diff -r ee24dcbd3e64 -r 8296acd119a9 drivers/win32/win32.cpp --- a/drivers/win32/win32.cpp Wed Jul 15 09:32:35 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,218 +0,0 @@ -/* -This file is part of CanFestival, a library implementing CanOpen Stack. - -Copyright (C): Edouard TISSERANT and Francis DUPIN -Copyright (C) Win32 Port Leonid Tochinski - -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 -*/ - -/* - CAN driver interface. -*/ - -#include - -extern "C" - { -#define DLL_CALL(funcname) (*_##funcname) -#define FCT_PTR_INIT =NULL -#include "canfestival.h" -#include "timer.h" - -#include "timers_driver.h" - }; - -typedef UNS8 (*CANRECEIVE_DRIVER_PROC)(void* inst, Message *m); -typedef UNS8 (*CANSEND_DRIVER_PROC)(void* inst, const Message *m); -typedef void* (*CANOPEN_DRIVER_PROC)(s_BOARD *board); -typedef int (*CANCLOSE_DRIVER_PROC)(void* inst); - - -class driver_procs - { - public: - driver_procs(); - ~driver_procs(); - - HMODULE load_canfestival_driver(LPCTSTR driver_name); - bool can_driver_valid() const; - - public: - // can driver - CANRECEIVE_DRIVER_PROC m_canReceive; - CANSEND_DRIVER_PROC m_canSend; - CANOPEN_DRIVER_PROC m_canOpen; - CANCLOSE_DRIVER_PROC m_canClose; - - // driver module habndle - HMODULE m_driver_handle; - }; - -driver_procs::driver_procs() : m_canReceive(0), - m_canSend(0), - m_canOpen(0), - m_canClose(0), - m_driver_handle(0) - {} - -driver_procs::~driver_procs() - { - if (m_driver_handle) - ::FreeLibrary(m_driver_handle); - } - -bool driver_procs::can_driver_valid() const - { - return ((m_canReceive != NULL) && - (m_canSend != NULL) && - (m_canOpen != NULL) && - (m_canClose != NULL)); - } - -// GetProcAddress doesn't have an UNICODE version for NT -#ifdef UNDER_CE - #define myTEXT(str) TEXT(str) -#else - #define myTEXT(str) str -#endif - -HMODULE driver_procs::load_canfestival_driver(LPCTSTR driver_name) - { - //LPCTSTR driver1 = "C:\\msys\\1.0\\home\\Ontaide\\can\\CanFestival-3\\drivers\\can_peak_win32\\cygcan_peak_win32.dll"; - //LPCTSTR driver2 = "C:\\msys\\1.0\\home\\Ontaide\\can\\CanFestival-3\\drivers\\can_peak_win32\\cygcan_peak_win32.dll"; - //printf("can_driver_valid=%d\n",can_driver_valid()); - if (can_driver_valid()) - return m_driver_handle; - printf("driver_name=%s\n",driver_name); - m_driver_handle = ::LoadLibrary(driver_name); - //printf("m_driver_handle=%d\n",m_driver_handle); - //printf("testerror =%s\n",GetLastError()); - if (m_driver_handle == NULL) - return NULL; - - m_canReceive = (CANRECEIVE_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canReceive_driver")); - m_canSend = (CANSEND_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canSend_driver")); - m_canOpen = (CANOPEN_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canOpen_driver")); - m_canClose = (CANCLOSE_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canClose_driver")); - return can_driver_valid()?m_driver_handle:NULL; - } - -struct driver_data - { - CO_Data * d; - HANDLE receive_thread; - void* inst; - volatile bool continue_receive_thread; - }; - -driver_procs s_driver_procs; - -LIB_HANDLE LoadCanDriver(const char* driver_name) - { - return s_driver_procs.load_canfestival_driver((LPCTSTR)driver_name); - } - -UNS8 canReceive(CAN_PORT fd0, Message *m) - { - - if (fd0 != NULL && s_driver_procs.m_canReceive != NULL) - { - driver_data* data = (driver_data*)fd0; - return (*s_driver_procs.m_canReceive)(data->inst, m); - } - return 1; - } - -void* canReceiveLoop(CAN_PORT fd0) - { - driver_data* data = (driver_data*)fd0; - Message m; - while (data->continue_receive_thread) - { - if (!canReceive(fd0, &m)) - { - EnterMutex(); - canDispatch(data->d, &m); - LeaveMutex(); - } - else - { - break; - ::Sleep(1); - } - } - return 0; - } - -/***************************************************************************/ -UNS8 canSend(CAN_PORT fd0, Message *m) - { - if (fd0 != NULL && s_driver_procs.m_canSend != NULL) - { - UNS8 res; - driver_data* data = (driver_data*)fd0; - res = (*s_driver_procs.m_canSend)(data->inst, m); - if (res) - return 1; // OK - } - return 0; // NOT OK - } - -/***************************************************************************/ -CAN_HANDLE canOpen(s_BOARD *board, CO_Data * d) - { - if (board != NULL && s_driver_procs.m_canOpen != NULL) - { - void* inst = (*s_driver_procs.m_canOpen)(board); - if (inst != NULL) - { - driver_data* data = new driver_data; - data->d = d; - data->inst = inst; - data->continue_receive_thread = true; - CreateReceiveTask(data, &data->receive_thread, (void*)&canReceiveLoop); - EnterMutex(); - d->canHandle = data; - LeaveMutex(); - return data; - } - } - return NULL; - } - -/***************************************************************************/ -int canClose(CO_Data * d) - { - if (s_driver_procs.m_canClose != NULL) - { - driver_data* data; - EnterMutex(); - if(d->canHandle != NULL){ - data = (driver_data*)d->canHandle; - d->canHandle = NULL; - data->continue_receive_thread = false;} - LeaveMutex(); - (*s_driver_procs.m_canClose)(data->inst); - WaitReceiveTaskEnd(&data->receive_thread); - delete data; - return 0; - } - return 0; - } - -