]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - drivers/unix/unix.c
Add win32 target (--can=win32) to compile with msys and mingw32
[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 #define DLSYM(name)\
31         *(void **) (&name##_driver) = dlsym(handle, #name"_driver");\
32         if ((error = dlerror()) != NULL)  {\
33                 fprintf (stderr, "%s\n", error);\
34                 UnLoadCanDriver(handle);\
35                 return NULL;\
36         }
37
38 #else /*NOT_USE_DYNAMIC_LOADING*/
39
40 /*Function call is direct*/
41 #define DLL_CALL(funcname) funcname##_driver
42
43 #endif /*NOT_USE_DYNAMIC_LOADING*/
44
45 #include "data.h"
46 #include "canfestival.h"
47 #include "timers_driver.h"
48
49 #define MAX_NB_CAN_PORTS 16
50
51 typedef struct {
52   char used;
53   CAN_HANDLE fd;
54   TASK_HANDLE receiveTask;
55   CO_Data* d;
56 } CANPort;
57
58 #include "can_driver.h"
59
60 /*Declares the funtion pointers for dll binding or simple protos*/
61 /*UNS8 DLL_CALL(canReceive)(CAN_HANDLE, Message *);
62 UNS8 DLL_CALL(canSend)(CAN_HANDLE, Message *);
63 CAN_HANDLE DLL_CALL(canOpen)(s_BOARD *);
64 int DLL_CALL(canClose)(CAN_HANDLE);
65 */
66 CANPort canports[MAX_NB_CAN_PORTS] = {{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,}};
67
68 #ifndef NOT_USE_DYNAMIC_LOADING
69
70 /*UnLoads the dll*/
71 UNS8 UnLoadCanDriver(LIB_HANDLE handle)
72 {
73         if(handle!=NULL)
74         {
75                 dlclose(handle);
76
77                 handle=NULL;
78                 return 0;
79         }
80         return -1;
81 }
82
83 /*Loads the dll and get funcs ptr*/
84 LIB_HANDLE LoadCanDriver(char* driver_name)
85 {
86         LIB_HANDLE handle = NULL;
87         char *error;
88         
89
90         if(handle==NULL)
91         {
92                 handle = dlopen(driver_name, RTLD_LAZY);
93         }
94
95         if (!handle) {
96                 fprintf (stderr, "%s\n", dlerror());
97                 return NULL;
98         }
99  
100         /*Get function ptr*/
101         DLSYM(canReceive)
102         DLSYM(canSend)
103         DLSYM(canOpen)
104         DLSYM(canClose)
105
106         return handle;
107 }
108
109 #endif
110
111
112
113 /*Not needed -- canReceiveLoop calls _canReceive directly *//*
114 UNS8 canReceive(CAN_PORT port, Message *m)
115 {
116         return DLL_CALL(canReceive)(port->fd, Message *m);
117 }
118 */
119
120 UNS8 canSend(CAN_PORT port, Message *m)
121 {
122         if(port){
123                 UNS8 res;
124                 //LeaveMutex();
125                 res = DLL_CALL(canSend)(((CANPort*)port)->fd, m);
126                 //EnterMutex();
127                 return res; // OK
128         }               
129         return 1; // NOT OK
130 }
131
132 void canReceiveLoop(CAN_PORT port)
133 {
134        Message m;
135
136        while (1) {
137                if (DLL_CALL(canReceive)(((CANPort*)port)->fd, &m) != 0)
138                        break;
139
140                EnterMutex();
141                canDispatch(((CANPort*)port)->d, &m);
142                LeaveMutex();
143        }
144 }
145 CAN_PORT canOpen(s_BOARD *board, CO_Data * d)
146 {
147         int i;
148         for(i=0; i < MAX_NB_CAN_PORTS; i++)
149         {
150                 if(!canports[i].used)
151                 break;
152         }
153         
154 #ifndef NOT_USE_DYNAMIC_LOADING
155         if (&DLL_CALL(canOpen)==NULL) {
156                 fprintf(stderr,"CanOpen : Can Driver dll not loaded\n");
157                 return NULL;
158         }
159 #endif  
160         CAN_HANDLE fd0 = DLL_CALL(canOpen)(board);
161         if(fd0){
162                 canports[i].used = 1;
163                 canports[i].fd = fd0;
164                 canports[i].d = d;
165         
166                 CreateReceiveTask(&(canports[i]), &canports[i].receiveTask, &canReceiveLoop);
167                 
168                 EnterMutex();
169                 d->canHandle = (CAN_PORT)&canports[i];
170                 LeaveMutex();
171                 return (CAN_PORT)&canports[i];
172         }else{
173                 fprintf(stderr,"CanOpen : Cannot open board {busname='%s',baudrate='%s'}\n",board->busname, board->baudrate);
174                 return NULL;
175         }
176 }
177
178 int canClose(CO_Data * d)
179 {
180         EnterMutex();
181         ((CANPort*)d->canHandle)->used = 0;
182         CANPort* tmp = (CANPort*)d->canHandle;
183         d->canHandle = NULL;
184         LeaveMutex();
185         
186         int res = DLL_CALL(canClose)(tmp->fd);
187         
188         WaitReceiveTaskEnd(tmp->receiveTask);
189         return res;
190 }