drivers/unix/unix.c
changeset 145 e747d2e26af0
child 149 fe50ada8020b
equal deleted inserted replaced
144:3ebf16150b2e 145:e747d2e26af0
       
     1 /*
       
     2 This file is part of CanFestival, a library implementing CanOpen Stack. 
       
     3 
       
     4 Copyright (C): Edouard TISSERANT and Francis DUPIN
       
     5 
       
     6 See COPYING file for copyrights details.
       
     7 
       
     8 This library is free software; you can redistribute it and/or
       
     9 modify it under the terms of the GNU Lesser General Public
       
    10 License as published by the Free Software Foundation; either
       
    11 version 2.1 of the License, or (at your option) any later version.
       
    12 
       
    13 This library is distributed in the hope that it will be useful,
       
    14 but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    16 Lesser General Public License for more details.
       
    17 
       
    18 You should have received a copy of the GNU Lesser General Public
       
    19 License along with this library; if not, write to the Free Software
       
    20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    21 */
       
    22 #include <unistd.h>
       
    23 #include <stdio.h>
       
    24 #include <stdlib.h>
       
    25 
       
    26 #ifndef NOT_USE_DYNAMIC_LOADING
       
    27 #define DLL_CALL(funcname) (* funcname##_driver)
       
    28 #define FCT_PTR_INIT =NULL
       
    29 
       
    30 #ifdef WIN32
       
    31 #define DLSYM(name)\
       
    32     *(void **) (&_##name) = GetProcAddress(handle, TEXT(#name"_driver"));\
       
    33 	if (name##_driver == NULL)  {\
       
    34 		fprintf (stderr, "Error loading symbol %s\n",#name"_driver");\
       
    35 		UnLoadCanDriver(handle);\
       
    36 		return NULL;\
       
    37 	}
       
    38  
       
    39 #else
       
    40 #define DLSYM(name)\
       
    41 	*(void **) (&name##_driver) = dlsym(handle, #name"_driver");\
       
    42 	if ((error = dlerror()) != NULL)  {\
       
    43 		fprintf (stderr, "%s\n", error);\
       
    44 		UnLoadCanDriver(handle);\
       
    45 		return NULL;\
       
    46 	}
       
    47 #endif
       
    48 
       
    49 #else /*NOT_USE_DYNAMIC_LOADING*/
       
    50 
       
    51 /*Function call is direct*/
       
    52 #define DLL_CALL(funcname) funcname##_driver
       
    53 
       
    54 #endif /*NOT_USE_DYNAMIC_LOADING*/
       
    55 
       
    56 #include "data.h"
       
    57 #include "canfestival.h"
       
    58 #include "timers_driver.h"
       
    59 
       
    60 #define MAX_NB_CAN_PORTS 16
       
    61 
       
    62 typedef struct {
       
    63   char used;
       
    64   CAN_HANDLE fd;
       
    65   TASK_HANDLE receiveTask;
       
    66   CO_Data* d;
       
    67 } CANPort;
       
    68 
       
    69 #include "can_driver.h"
       
    70 
       
    71 /*Declares the funtion pointers for dll binding or simple protos*/
       
    72 /*UNS8 DLL_CALL(canReceive)(CAN_HANDLE, Message *);
       
    73 UNS8 DLL_CALL(canSend)(CAN_HANDLE, Message *);
       
    74 CAN_HANDLE DLL_CALL(canOpen)(s_BOARD *);
       
    75 int DLL_CALL(canClose)(CAN_HANDLE);
       
    76 */
       
    77 CANPort canports[MAX_NB_CAN_PORTS] = {{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,}};
       
    78 
       
    79 #ifndef NOT_USE_DYNAMIC_LOADING
       
    80 
       
    81 /*UnLoads the dll*/
       
    82 UNS8 UnLoadCanDriver(LIB_HANDLE handle)
       
    83 {
       
    84 	if(handle!=NULL)
       
    85 	{
       
    86 #ifdef WIN32
       
    87 	        FreeLibrary(handle);    
       
    88 #else
       
    89 		dlclose(handle);
       
    90 #endif
       
    91 		handle=NULL;
       
    92 		return 0;
       
    93 	}
       
    94 	return -1;
       
    95 }
       
    96 
       
    97 /*Loads the dll and get funcs ptr*/
       
    98 LIB_HANDLE LoadCanDriver(char* driver_name)
       
    99 {
       
   100 	LIB_HANDLE handle = NULL;
       
   101 	char *error;
       
   102 	
       
   103 #ifdef WIN32
       
   104 
       
   105 	if(handle==NULL)
       
   106 	{
       
   107 		handle = LoadLibrary(driver_name);
       
   108 	}
       
   109  
       
   110 	if (handle == NULL) {
       
   111         	fprintf(stderr,"Error loading Can Driver dll \n");
       
   112         	return -1;
       
   113 	}
       
   114 
       
   115 #else
       
   116 	if(handle==NULL)
       
   117 	{
       
   118 		handle = dlopen(driver_name, RTLD_LAZY);
       
   119 	}
       
   120 
       
   121 	if (!handle) {
       
   122 		fprintf (stderr, "%s\n", dlerror());
       
   123         	return NULL;
       
   124 	}
       
   125 #endif
       
   126  
       
   127 	/*Get function ptr*/
       
   128 	DLSYM(canReceive)
       
   129 	DLSYM(canSend)
       
   130 	DLSYM(canOpen)
       
   131 	DLSYM(canClose)
       
   132 
       
   133 	return 0;
       
   134 }
       
   135 
       
   136 #endif
       
   137 
       
   138 
       
   139 
       
   140 /*Not needed -- canReceiveLoop calls _canReceive directly *//*
       
   141 UNS8 canReceive(CAN_PORT port, Message *m)
       
   142 {
       
   143 	return DLL_CALL(canReceive)(port->fd, Message *m);
       
   144 }
       
   145 */
       
   146 
       
   147 UNS8 canSend(CAN_PORT port, Message *m)
       
   148 {
       
   149 	return DLL_CALL(canSend)(((CANPort*)port)->fd, m);
       
   150 }
       
   151 
       
   152 void canReceiveLoop(CAN_PORT port)
       
   153 {
       
   154        Message m;
       
   155 
       
   156        while (1) {
       
   157                if (DLL_CALL(canReceive)(((CANPort*)port)->fd, &m) != 0)
       
   158                        break;
       
   159 
       
   160                EnterMutex();
       
   161                canDispatch(((CANPort*)port)->d, &m);
       
   162                LeaveMutex();
       
   163        }
       
   164 }
       
   165 CAN_PORT canOpen(s_BOARD *board, CO_Data * d)
       
   166 {
       
   167 	int i;
       
   168 	for(i=0; i < MAX_NB_CAN_PORTS; i++)
       
   169 	{
       
   170 		if(!canports[i].used)
       
   171 		break;
       
   172 	}
       
   173 	
       
   174 #ifndef NOT_USE_DYNAMIC_LOADING
       
   175 	if (&DLL_CALL(canOpen)==NULL) {
       
   176         	fprintf(stderr,"CanOpen : Can Driver dll not loaded\n");
       
   177         	return NULL;
       
   178 	}
       
   179 #endif	
       
   180 	CAN_HANDLE fd0 = DLL_CALL(canOpen)(board);
       
   181 
       
   182 	canports[i].used = 1;
       
   183 	canports[i].fd = fd0;
       
   184 	canports[i].d = d;
       
   185 
       
   186 	CreateReceiveTask(&(canports[i]), &canports[i].receiveTask, &canReceiveLoop);
       
   187 		
       
   188 	return (CAN_PORT)&canports[i];
       
   189 }
       
   190 
       
   191 int canClose(CAN_PORT port)
       
   192 {
       
   193 	((CANPort*)port)->used = 0;
       
   194 	int res = DLL_CALL(canClose)(((CANPort*)port)->fd);
       
   195 	
       
   196 	WaitReceiveTaskEnd(((CANPort*)port)->receiveTask);
       
   197 	return res;
       
   198 }
       
   199 
       
   200