nico@207: nico@207: nico@207: CanFestival: /home/epimerde/documents/tc11/CanFestival-3/drivers/win32/drivers_win32.cpp Source File nico@207: nico@207: nico@207: nico@207: nico@207:
nico@207:
nico@207:
nico@207:
nico@207:

/home/epimerde/documents/tc11/CanFestival-3/drivers/win32/drivers_win32.cpp

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

Generated on Mon Jun 4 16:29:06 2007 for CanFestival by  nico@207: nico@207: doxygen 1.5.1
nico@207: nico@207: