]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - drivers/unix/unix.c
Updated doc. Cleaned some code.
[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 0;
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;
128         }               
129         return -1;
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
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 }
173
174 int canClose(CO_Data * d)
175 {
176         EnterMutex();
177         ((CANPort*)d->canHandle)->used = 0;
178         CANPort* tmp = (CANPort*)d->canHandle;
179         d->canHandle = NULL;
180         LeaveMutex();
181         
182         int res = DLL_CALL(canClose)(tmp->fd);
183         
184         WaitReceiveTaskEnd(tmp->receiveTask);
185         return res;
186 }