00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <unistd.h>
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025
00026 #ifndef NOT_USE_DYNAMIC_LOADING
00027 #define DLL_CALL(funcname) (* funcname##_driver)
00028 #define FCT_PTR_INIT =NULL
00029
00030 #define DLSYM(name)\
00031 *(void **) (&name##_driver) = dlsym(handle, #name"_driver");\
00032 if ((error = dlerror()) != NULL) {\
00033 fprintf (stderr, "%s\n", error);\
00034 UnLoadCanDriver(handle);\
00035 return NULL;\
00036 }
00037
00038 #else
00039
00040
00041 #define DLL_CALL(funcname) funcname##_driver
00042
00043 #endif
00044
00045 #include "data.h"
00046 #include "canfestival.h"
00047 #include "timers_driver.h"
00048
00049 #define MAX_NB_CAN_PORTS 16
00050
00051 typedef struct {
00052 char used;
00053 CAN_HANDLE fd;
00054 TASK_HANDLE receiveTask;
00055 CO_Data* d;
00056 } CANPort;
00057
00058 #include "can_driver.h"
00059
00060
00061
00062
00063
00064
00065
00066 CANPort canports[MAX_NB_CAN_PORTS] = {{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,}};
00067
00068 #ifndef NOT_USE_DYNAMIC_LOADING
00069
00070
00071 UNS8 UnLoadCanDriver(LIB_HANDLE handle)
00072 {
00073 if(handle!=NULL)
00074 {
00075 dlclose(handle);
00076
00077 handle=NULL;
00078 return 0;
00079 }
00080 return -1;
00081 }
00082
00083
00084 LIB_HANDLE LoadCanDriver(char* driver_name)
00085 {
00086 LIB_HANDLE handle = NULL;
00087 char *error;
00088
00089
00090 if(handle==NULL)
00091 {
00092 handle = dlopen(driver_name, RTLD_LAZY);
00093 }
00094
00095 if (!handle) {
00096 fprintf (stderr, "%s\n", dlerror());
00097 return NULL;
00098 }
00099
00100
00101 DLSYM(canReceive)
00102 DLSYM(canSend)
00103 DLSYM(canOpen)
00104 DLSYM(canClose)
00105
00106 return handle;
00107 }
00108
00109 #endif
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 UNS8 canSend(CAN_PORT port, Message *m)
00121 {
00122 if(port){
00123 UNS8 res;
00124
00125 res = DLL_CALL(canSend)(((CANPort*)port)->fd, m);
00126
00127 return res;
00128 }
00129 return -1;
00130 }
00131
00132 void canReceiveLoop(CAN_PORT port)
00133 {
00134 Message m;
00135
00136 while (1) {
00137 if (DLL_CALL(canReceive)(((CANPort*)port)->fd, &m) != 0)
00138 break;
00139
00140 EnterMutex();
00141 canDispatch(((CANPort*)port)->d, &m);
00142 LeaveMutex();
00143 }
00144 }
00145 CAN_PORT canOpen(s_BOARD *board, CO_Data * d)
00146 {
00147 int i;
00148 for(i=0; i < MAX_NB_CAN_PORTS; i++)
00149 {
00150 if(!canports[i].used)
00151 break;
00152 }
00153
00154 #ifndef NOT_USE_DYNAMIC_LOADING
00155 if (&DLL_CALL(canOpen)==NULL) {
00156 fprintf(stderr,"CanOpen : Can Driver dll not loaded\n");
00157 return NULL;
00158 }
00159 #endif
00160 CAN_HANDLE fd0 = DLL_CALL(canOpen)(board);
00161 if(fd0){
00162 canports[i].used = 1;
00163 canports[i].fd = fd0;
00164 canports[i].d = d;
00165
00166 CreateReceiveTask(&(canports[i]), &canports[i].receiveTask, &canReceiveLoop);
00167
00168 EnterMutex();
00169 d->canHandle = (CAN_PORT)&canports[i];
00170 LeaveMutex();
00171 return (CAN_PORT)&canports[i];
00172 }else{
00173 fprintf(stderr,"CanOpen : Cannot open board {busname='%s',baudrate='%s'}\n",board->busname, board->baudrate);
00174 return NULL;
00175 }
00176 }
00177
00178 int canClose(CO_Data * d)
00179 {
00180 EnterMutex();
00181 ((CANPort*)d->canHandle)->used = 0;
00182 CANPort* tmp = (CANPort*)d->canHandle;
00183 d->canHandle = NULL;
00184 LeaveMutex();
00185
00186 int res = DLL_CALL(canClose)(tmp->fd);
00187
00188 WaitReceiveTaskEnd(tmp->receiveTask);
00189 return res;
00190 }