nico@215: nico@215: nico@215: CanFestival: drivers/win32/drivers_win32.cpp Source File nico@215: nico@215: nico@215: nico@215: nico@215:
nico@215:
nico@215:
nico@215:
nico@215: nico@215:

drivers_win32.cpp

Go to the documentation of this file.
00001 /*
nico@215: 00002 This file is part of CanFestival, a library implementing CanOpen Stack.
nico@215: 00003 
nico@215: 00004 Copyright (C): Edouard TISSERANT and Francis DUPIN
nico@215: 00005 Copyright (C) Win32 Port Leonid Tochinski
nico@215: 00006 
nico@215: 00007 See COPYING file for copyrights details.
nico@215: 00008 
nico@215: 00009 This library is free software; you can redistribute it and/or
nico@215: 00010 modify it under the terms of the GNU Lesser General Public
nico@215: 00011 License as published by the Free Software Foundation; either
nico@215: 00012 version 2.1 of the License, or (at your option) any later version.
nico@215: 00013 
nico@215: 00014 This library is distributed in the hope that it will be useful,
nico@215: 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
nico@215: 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
nico@215: 00017 Lesser General Public License for more details.
nico@215: 00018 
nico@215: 00019 You should have received a copy of the GNU Lesser General Public
nico@215: 00020 License along with this library; if not, write to the Free Software
nico@215: 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
nico@215: 00022 */
nico@215: 00023 
nico@215: 00024 /*
nico@215: 00025  CAN driver interface.
nico@215: 00026 */
nico@215: 00027 
nico@215: 00028 #include <windows.h>
nico@215: 00029 
nico@215: 00030 extern "C"
nico@215: 00031    {
etisserant@240: 00032 #define DLL_CALL(funcname) (*_##funcname)
etisserant@240: 00033 #define FCT_PTR_INIT =NULL
nico@215: 00034 #include "canfestival.h"
nico@215: 00035 #include "timer.h"
nico@215: 00036 
nico@215: 00037 #include "timers_driver.h"
nico@215: 00038    };
nico@215: 00039 
etisserant@240: 00040 typedef UNS8 (*CANRECEIVE_DRIVER_PROC)(void* inst, Message *m);
etisserant@240: 00041 typedef UNS8 (*CANSEND_DRIVER_PROC)(void* inst, const Message *m);
etisserant@240: 00042 typedef void* (*CANOPEN_DRIVER_PROC)(s_BOARD *board);
etisserant@240: 00043 typedef int (*CANCLOSE_DRIVER_PROC)(void* inst);
nico@215: 00044 
nico@215: 00045 
nico@215: 00046 class driver_procs
nico@215: 00047    {
nico@215: 00048    public:
etisserant@240: 00049       driver_procs();
etisserant@240: 00050       ~driver_procs();
nico@215: 00051 
etisserant@240: 00052       HMODULE load_canfestival_driver(LPCTSTR driver_name);
etisserant@240: 00053       bool can_driver_valid() const;
nico@215: 00054 
nico@215: 00055    public:
nico@215: 00056       // can driver
etisserant@240: 00057       CANRECEIVE_DRIVER_PROC m_canReceive;
etisserant@240: 00058       CANSEND_DRIVER_PROC m_canSend;
etisserant@240: 00059       CANOPEN_DRIVER_PROC m_canOpen;
etisserant@240: 00060       CANCLOSE_DRIVER_PROC m_canClose;
nico@215: 00061 
nico@215: 00062       // driver module habndle
etisserant@240: 00063       HMODULE m_driver_handle;
nico@215: 00064    };
nico@215: 00065 
etisserant@240: 00066 driver_procs::driver_procs() : m_canReceive(0),
nico@215: 00067       m_canSend(0),
nico@215: 00068       m_canOpen(0),
nico@215: 00069       m_canClose(0),
nico@215: 00070       m_driver_handle(0)
nico@215: 00071    {}
nico@215: 00072 
etisserant@240: 00073 driver_procs::~driver_procs()
nico@215: 00074    {
etisserant@240: 00075    if (m_driver_handle)
etisserant@240: 00076       ::FreeLibrary(m_driver_handle);
nico@215: 00077    }
nico@215: 00078 
etisserant@240: 00079 bool driver_procs::can_driver_valid() const
nico@215: 00080    {
etisserant@240: 00081    return ((m_canReceive != NULL) &&
etisserant@240: 00082            (m_canSend != NULL) &&
etisserant@240: 00083            (m_canOpen != NULL) &&
etisserant@240: 00084            (m_canClose != NULL));
nico@215: 00085    }
nico@215: 00086 
nico@215: 00087 // GetProcAddress doesn't have an UNICODE version for NT
nico@215: 00088 #ifdef UNDER_CE
nico@215: 00089   #define myTEXT(str) TEXT(str)
nico@215: 00090 #else
etisserant@240: 00091   #define myTEXT(str) str
nico@215: 00092 #endif
nico@215: 00093 
etisserant@240: 00094 HMODULE driver_procs::load_canfestival_driver(LPCTSTR driver_name)
nico@215: 00095    {
etisserant@240: 00096    if (can_driver_valid())
etisserant@240: 00097       return m_driver_handle;
etisserant@240: 00098    m_driver_handle = ::LoadLibrary(driver_name);
etisserant@240: 00099    if (m_driver_handle == NULL)
nico@215: 00100       return NULL;
nico@215: 00101 
etisserant@240: 00102    m_canReceive = (CANRECEIVE_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canReceive_driver"));
etisserant@240: 00103    m_canSend = (CANSEND_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canSend_driver"));
etisserant@240: 00104    m_canOpen = (CANOPEN_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canOpen_driver"));
etisserant@240: 00105    m_canClose = (CANCLOSE_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canClose_driver"));
etisserant@240: 00106    return can_driver_valid()?m_driver_handle:NULL;
nico@215: 00107    }
nico@215: 00108 
nico@215: 00109 struct driver_data
nico@215: 00110    {
etisserant@240: 00111    CO_Data * d;
etisserant@240: 00112    HANDLE receive_thread;
etisserant@240: 00113    void* inst;
etisserant@240: 00114    volatile bool continue_receive_thread;
nico@215: 00115    };
nico@215: 00116 
etisserant@240: 00117 driver_procs s_driver_procs;
nico@215: 00118 
etisserant@240: 00119 LIB_HANDLE LoadCanDriver(char* driver_name)
nico@215: 00120    {
etisserant@240: 00121                 return s_driver_procs.load_canfestival_driver((LPCTSTR)driver_name);
nico@215: 00122    }
nico@215: 00123 
etisserant@240: 00124 UNS8 canReceive(CAN_PORT fd0, Message *m)
nico@215: 00125    {
etisserant@240: 00126    if (fd0 != NULL && s_driver_procs.m_canReceive != NULL)
nico@215: 00127            {
nico@215: 00128                   driver_data* data = (driver_data*)fd0;
etisserant@240: 00129                   return (*s_driver_procs.m_canReceive)(data->inst, m);
nico@215: 00130            }
nico@215: 00131    return 1;
nico@215: 00132    }
nico@215: 00133 
etisserant@240: 00134 void* canReceiveLoop(CAN_PORT fd0)
nico@215: 00135    {
nico@215: 00136    driver_data* data = (driver_data*)fd0;
nico@215: 00137    Message m;
etisserant@240: 00138    while (data->continue_receive_thread)
nico@215: 00139       {
etisserant@240: 00140       if (!canReceive(fd0, &m))
nico@215: 00141          {
etisserant@240: 00142          EnterMutex();
etisserant@240: 00143          canDispatch(data->d, &m);
etisserant@240: 00144          LeaveMutex();
nico@215: 00145          }
nico@215: 00146       else
nico@215: 00147          {
nico@215: 00148                  break;
nico@215: 00149          ::Sleep(1);
nico@215: 00150          }
nico@215: 00151       }
nico@215: 00152    return 0;
nico@215: 00153    }
nico@215: 00154 
nico@215: 00155 /***************************************************************************/
etisserant@240: 00156 UNS8 canSend(CAN_PORT fd0, Message *m)
nico@215: 00157    {
etisserant@240: 00158    if (fd0 != NULL && s_driver_procs.m_canSend != NULL)
nico@215: 00159       {
etisserant@240: 00160       UNS8 res;
nico@215: 00161       driver_data* data = (driver_data*)fd0;
etisserant@240: 00162       LeaveMutex();
etisserant@240: 00163       res = (*s_driver_procs.m_canSend)(data->inst, m);      
etisserant@240: 00164       EnterMutex();
nico@215: 00165       if (res)
nico@215: 00166          return 0;
nico@215: 00167       }
nico@215: 00168    return 1;
nico@215: 00169    }
nico@215: 00170 
nico@215: 00171 /***************************************************************************/
etisserant@240: 00172 CAN_HANDLE canOpen(s_BOARD *board, CO_Data * d)
nico@215: 00173    {
etisserant@240: 00174    if (board != NULL && s_driver_procs.m_canOpen != NULL)
nico@215: 00175       {
etisserant@240: 00176       void* inst = (*s_driver_procs.m_canOpen)(board);
nico@215: 00177       if (inst != NULL)
nico@215: 00178          {
nico@215: 00179          driver_data* data = new driver_data;
etisserant@240: 00180          data->d = d;
etisserant@240: 00181          data->inst = inst;
etisserant@240: 00182          data->continue_receive_thread = true;
etisserant@240: 00183          CreateReceiveTask(data, &data->receive_thread, &canReceiveLoop);
etisserant@240: 00184          EnterMutex();
etisserant@240: 00185          d->canHandle = data;
etisserant@240: 00186          LeaveMutex();
nico@215: 00187          return data;
nico@215: 00188          }
nico@215: 00189       }
nico@215: 00190    return NULL;
nico@215: 00191    }
nico@215: 00192 
nico@215: 00193 /***************************************************************************/
etisserant@240: 00194 int canClose(CO_Data * d)
nico@215: 00195    {
etisserant@240: 00196    if (s_driver_procs.m_canClose != NULL)
nico@215: 00197       {
nico@215: 00198                   driver_data* data;
etisserant@240: 00199                   EnterMutex();
etisserant@240: 00200                   if(d->canHandle != NULL){
etisserant@240: 00201                         data = (driver_data*)d->canHandle;
etisserant@240: 00202                         d->canHandle = NULL;
etisserant@240: 00203                         data->continue_receive_thread = false;}
etisserant@240: 00204                   LeaveMutex();
etisserant@240: 00205                   WaitReceiveTaskEnd(&data->receive_thread);
etisserant@240: 00206                   (*s_driver_procs.m_canClose)(data->inst);
nico@215: 00207                   delete data;
nico@215: 00208                   return 0;
nico@215: 00209       }
nico@215: 00210    return 0;
nico@215: 00211    }
nico@215: 00212 
nico@215: 00213 
etisserant@240: 

Generated on Mon Jul 2 19:10:16 2007 for CanFestival by  nico@215: nico@215: doxygen 1.5.1
nico@215: nico@215: