/home/epimerde/documents/tc11/CanFestival-3/drivers/unix/unix.c

Go to the documentation of this file.
00001 /*
00002 This file is part of CanFestival, a library implementing CanOpen Stack. 
00003 
00004 Copyright (C): Edouard TISSERANT and Francis DUPIN
00005 
00006 See COPYING file for copyrights details.
00007 
00008 This library is free software; you can redistribute it and/or
00009 modify it under the terms of the GNU Lesser General Public
00010 License as published by the Free Software Foundation; either
00011 version 2.1 of the License, or (at your option) any later version.
00012 
00013 This library is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 Lesser General Public License for more details.
00017 
00018 You should have received a copy of the GNU Lesser General Public
00019 License along with this library; if not, write to the Free Software
00020 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 /*NOT_USE_DYNAMIC_LOADING*/
00039 
00040 /*Function call is direct*/
00041 #define DLL_CALL(funcname) funcname##_driver
00042 
00043 #endif /*NOT_USE_DYNAMIC_LOADING*/
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 /*Declares the funtion pointers for dll binding or simple protos*/
00061 /*UNS8 DLL_CALL(canReceive)(CAN_HANDLE, Message *);
00062 UNS8 DLL_CALL(canSend)(CAN_HANDLE, Message *);
00063 CAN_HANDLE DLL_CALL(canOpen)(s_BOARD *);
00064 int DLL_CALL(canClose)(CAN_HANDLE);
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 /*UnLoads the dll*/
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 /*Loads the dll and get funcs ptr*/
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         /*Get function ptr*/
00101         DLSYM(canReceive)
00102         DLSYM(canSend)
00103         DLSYM(canOpen)
00104         DLSYM(canClose)
00105 
00106         return handle;
00107 }
00108 
00109 #endif
00110 
00111 
00112 
00113 /*Not needed -- canReceiveLoop calls _canReceive directly *//*
00114 UNS8 canReceive(CAN_PORT port, Message *m)
00115 {
00116         return DLL_CALL(canReceive)(port->fd, Message *m);
00117 }
00118 */
00119 
00120 UNS8 canSend(CAN_PORT port, Message *m)
00121 {
00122         if(port){
00123                 UNS8 res;
00124                 //LeaveMutex();
00125                 res = DLL_CALL(canSend)(((CANPort*)port)->fd, m);
00126                 //EnterMutex();
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 }

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