]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - drivers/unix/unix.c
Changes in the API:
[CanFestival-3.git] / drivers / unix / unix.c
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         if(port){
150                 UNS8 res;
151                 LeaveMutex();
152                 res = DLL_CALL(canSend)(((CANPort*)port)->fd, m);
153                 EnterMutex();
154                 return res;
155         }               
156         return -1;
157 }
158
159 void canReceiveLoop(CAN_PORT port)
160 {
161        Message m;
162
163        while (1) {
164                if (DLL_CALL(canReceive)(((CANPort*)port)->fd, &m) != 0)
165                        break;
166
167                EnterMutex();
168                canDispatch(((CANPort*)port)->d, &m);
169                LeaveMutex();
170        }
171 }
172 CAN_PORT canOpen(s_BOARD *board, CO_Data * d)
173 {
174         int i;
175         for(i=0; i < MAX_NB_CAN_PORTS; i++)
176         {
177                 if(!canports[i].used)
178                 break;
179         }
180         
181 #ifndef NOT_USE_DYNAMIC_LOADING
182         if (&DLL_CALL(canOpen)==NULL) {
183                 fprintf(stderr,"CanOpen : Can Driver dll not loaded\n");
184                 return NULL;
185         }
186 #endif  
187         CAN_HANDLE fd0 = DLL_CALL(canOpen)(board);
188
189         canports[i].used = 1;
190         canports[i].fd = fd0;
191         canports[i].d = d;
192
193         CreateReceiveTask(&(canports[i]), &canports[i].receiveTask, &canReceiveLoop);
194         
195         EnterMutex();
196         d->canHandle = (CAN_PORT)&canports[i];
197         LeaveMutex();
198         return (CAN_PORT)&canports[i];
199 }
200
201 int canClose(CO_Data * d)
202 {
203         EnterMutex();
204         ((CANPort*)d->canHandle)->used = 0;
205         CANPort* tmp = (CANPort*)d->canHandle;
206         d->canHandle = NULL;
207         LeaveMutex();
208         
209         int res = DLL_CALL(canClose)(tmp->fd);
210         
211         WaitReceiveTaskEnd(tmp->receiveTask);
212         return res;
213 }