nico@207: nico@207:
nico@207: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 nico@207: 00006 See COPYING file for copyrights details. nico@207: 00007 nico@207: 00008 This library is free software; you can redistribute it and/or nico@207: 00009 modify it under the terms of the GNU Lesser General Public nico@207: 00010 License as published by the Free Software Foundation; either nico@207: 00011 version 2.1 of the License, or (at your option) any later version. nico@207: 00012 nico@207: 00013 This library is distributed in the hope that it will be useful, nico@207: 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of nico@207: 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU nico@207: 00016 Lesser General Public License for more details. nico@207: 00017 nico@207: 00018 You should have received a copy of the GNU Lesser General Public nico@207: 00019 License along with this library; if not, write to the Free Software nico@207: 00020 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA nico@207: 00021 */ nico@207: 00022 #include <unistd.h> nico@207: 00023 #include <stdio.h> nico@207: 00024 #include <stdlib.h> nico@207: 00025 nico@207: 00026 #ifndef NOT_USE_DYNAMIC_LOADING nico@207: 00027 #define DLL_CALL(funcname) (* funcname##_driver) nico@207: 00028 #define FCT_PTR_INIT =NULL nico@207: 00029 nico@207: 00030 #define DLSYM(name)\ nico@207: 00031 *(void **) (&name##_driver) = dlsym(handle, #name"_driver");\ nico@207: 00032 if ((error = dlerror()) != NULL) {\ nico@207: 00033 fprintf (stderr, "%s\n", error);\ nico@207: 00034 UnLoadCanDriver(handle);\ nico@207: 00035 return NULL;\ nico@207: 00036 } nico@207: 00037 nico@207: 00038 #else /*NOT_USE_DYNAMIC_LOADING*/ nico@207: 00039 nico@207: 00040 /*Function call is direct*/ nico@207: 00041 #define DLL_CALL(funcname) funcname##_driver nico@207: 00042 nico@207: 00043 #endif /*NOT_USE_DYNAMIC_LOADING*/ nico@207: 00044 nico@207: 00045 #include "data.h" nico@207: 00046 #include "canfestival.h" nico@207: 00047 #include "timers_driver.h" nico@207: 00048 nico@207: 00049 #define MAX_NB_CAN_PORTS 16 nico@207: 00050 nico@207: 00051 typedef struct { nico@207: 00052 char used; nico@207: 00053 CAN_HANDLE fd; nico@207: 00054 TASK_HANDLE receiveTask; nico@207: 00055 CO_Data* d; nico@207: 00056 } CANPort; nico@207: 00057 nico@207: 00058 #include "can_driver.h" nico@207: 00059 nico@207: 00060 /*Declares the funtion pointers for dll binding or simple protos*/ nico@207: 00061 /*UNS8 DLL_CALL(canReceive)(CAN_HANDLE, Message *); nico@207: 00062 UNS8 DLL_CALL(canSend)(CAN_HANDLE, Message *); nico@207: 00063 CAN_HANDLE DLL_CALL(canOpen)(s_BOARD *); nico@207: 00064 int DLL_CALL(canClose)(CAN_HANDLE); nico@207: 00065 */ nico@207: 00066 CANPort canports[MAX_NB_CAN_PORTS] = {{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,}}; nico@207: 00067 nico@207: 00068 #ifndef NOT_USE_DYNAMIC_LOADING nico@207: 00069 nico@207: 00070 /*UnLoads the dll*/ nico@207: 00071 UNS8 UnLoadCanDriver(LIB_HANDLE handle) nico@207: 00072 { nico@207: 00073 if(handle!=NULL) nico@207: 00074 { nico@207: 00075 dlclose(handle); nico@207: 00076 nico@207: 00077 handle=NULL; nico@207: 00078 return 0; nico@207: 00079 } nico@207: 00080 return -1; nico@207: 00081 } nico@207: 00082 nico@207: 00083 /*Loads the dll and get funcs ptr*/ nico@207: 00084 LIB_HANDLE LoadCanDriver(char* driver_name) nico@207: 00085 { nico@207: 00086 LIB_HANDLE handle = NULL; nico@207: 00087 char *error; nico@207: 00088 nico@207: 00089 nico@207: 00090 if(handle==NULL) nico@207: 00091 { nico@207: 00092 handle = dlopen(driver_name, RTLD_LAZY); nico@207: 00093 } nico@207: 00094 nico@207: 00095 if (!handle) { nico@207: 00096 fprintf (stderr, "%s\n", dlerror()); nico@207: 00097 return NULL; nico@207: 00098 } nico@207: 00099 nico@207: 00100 /*Get function ptr*/ nico@207: 00101 DLSYM(canReceive) nico@207: 00102 DLSYM(canSend) nico@207: 00103 DLSYM(canOpen) nico@207: 00104 DLSYM(canClose) nico@207: 00105 nico@207: 00106 return handle; nico@207: 00107 } nico@207: 00108 nico@207: 00109 #endif nico@207: 00110 nico@207: 00111 nico@207: 00112 nico@207: 00113 /*Not needed -- canReceiveLoop calls _canReceive directly *//* nico@207: 00114 UNS8 canReceive(CAN_PORT port, Message *m) nico@207: 00115 { nico@207: 00116 return DLL_CALL(canReceive)(port->fd, Message *m); nico@207: 00117 } nico@207: 00118 */ nico@207: 00119 nico@207: 00120 UNS8 canSend(CAN_PORT port, Message *m) nico@207: 00121 { nico@207: 00122 if(port){ nico@207: 00123 UNS8 res; nico@207: 00124 //LeaveMutex(); nico@207: 00125 res = DLL_CALL(canSend)(((CANPort*)port)->fd, m); nico@207: 00126 //EnterMutex(); nico@207: 00127 return res; nico@207: 00128 } nico@207: 00129 return -1; nico@207: 00130 } nico@207: 00131 nico@207: 00132 void canReceiveLoop(CAN_PORT port) nico@207: 00133 { nico@207: 00134 Message m; nico@207: 00135 nico@207: 00136 while (1) { nico@207: 00137 if (DLL_CALL(canReceive)(((CANPort*)port)->fd, &m) != 0) nico@207: 00138 break; nico@207: 00139 nico@207: 00140 EnterMutex(); nico@207: 00141 canDispatch(((CANPort*)port)->d, &m); nico@207: 00142 LeaveMutex(); nico@207: 00143 } nico@207: 00144 } nico@207: 00145 CAN_PORT canOpen(s_BOARD *board, CO_Data * d) nico@207: 00146 { nico@207: 00147 int i; nico@207: 00148 for(i=0; i < MAX_NB_CAN_PORTS; i++) nico@207: 00149 { nico@207: 00150 if(!canports[i].used) nico@207: 00151 break; nico@207: 00152 } nico@207: 00153 nico@207: 00154 #ifndef NOT_USE_DYNAMIC_LOADING nico@207: 00155 if (&DLL_CALL(canOpen)==NULL) { nico@207: 00156 fprintf(stderr,"CanOpen : Can Driver dll not loaded\n"); nico@207: 00157 return NULL; nico@207: 00158 } nico@207: 00159 #endif nico@207: 00160 CAN_HANDLE fd0 = DLL_CALL(canOpen)(board); nico@207: 00161 if(fd0){ nico@207: 00162 canports[i].used = 1; nico@207: 00163 canports[i].fd = fd0; nico@207: 00164 canports[i].d = d; nico@207: 00165 nico@207: 00166 CreateReceiveTask(&(canports[i]), &canports[i].receiveTask, &canReceiveLoop); nico@207: 00167 nico@207: 00168 EnterMutex(); nico@207: 00169 d->canHandle = (CAN_PORT)&canports[i]; nico@207: 00170 LeaveMutex(); nico@207: 00171 return (CAN_PORT)&canports[i]; nico@207: 00172 }else{ nico@207: 00173 fprintf(stderr,"CanOpen : Cannot open board {busname='%s',baudrate='%s'}\n",board->busname, board->baudrate); nico@207: 00174 return NULL; nico@207: 00175 } nico@207: 00176 } nico@207: 00177 nico@207: 00178 int canClose(CO_Data * d) nico@207: 00179 { nico@207: 00180 EnterMutex(); nico@207: 00181 ((CANPort*)d->canHandle)->used = 0; nico@207: 00182 CANPort* tmp = (CANPort*)d->canHandle; nico@207: 00183 d->canHandle = NULL; nico@207: 00184 LeaveMutex(); nico@207: 00185 nico@207: 00186 int res = DLL_CALL(canClose)(tmp->fd); nico@207: 00187 nico@207: 00188 WaitReceiveTaskEnd(tmp->receiveTask); nico@207: 00189 return res; nico@207: 00190 } nico@207: