|
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 |