20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 */ |
21 */ |
22 |
22 |
23 #include <stdio.h> |
23 #include <stdio.h> |
24 #include <string.h> |
24 #include <string.h> |
25 #include <stdlib.h> |
|
26 #include <errno.h> |
25 #include <errno.h> |
27 #include <stddef.h> /* for NULL */ |
|
28 #include <sys/ioctl.h> |
|
29 #include <fcntl.h> |
26 #include <fcntl.h> |
30 #include <signal.h> |
|
31 #include <sys/time.h> |
|
32 #include <unistd.h> |
|
33 |
27 |
34 #include "canmsg.h" |
28 #include "canmsg.h" |
35 #include "lincan.h" |
29 #include "lincan.h" |
36 |
30 |
37 struct CANPort; |
|
38 #define CAN_HANDLE struct CANPort * |
|
39 |
|
40 #include <applicfg.h> |
|
41 |
|
42 #include "timer.h" |
|
43 #include "can_driver.h" |
31 #include "can_driver.h" |
44 #include "timers_driver.h" |
|
45 |
|
46 typedef struct CANPort { |
|
47 char used; |
|
48 HANDLE fd; |
|
49 TASK_HANDLE receiveTask; |
|
50 CO_Data* d; |
|
51 } CANPort; |
|
52 |
32 |
53 /*********functions which permit to communicate with the board****************/ |
33 /*********functions which permit to communicate with the board****************/ |
54 UNS8 canReceive(CAN_HANDLE fd0, Message *m) |
34 UNS8 canReceive_driver(CAN_HANDLE fd0, Message *m) |
55 { |
35 { |
56 int res; |
36 int res; |
57 struct canmsg_t canmsg; |
37 struct canmsg_t canmsg; |
58 |
38 |
59 canmsg.flags = 0; /* Ensure standard receive, not required for LinCAN>=0.3.1 */ |
39 canmsg.flags = 0; /* Ensure standard receive, not required for LinCAN>=0.3.1 */ |
60 |
40 |
61 do{ |
41 do{ |
62 res = read(fd0->fd,&canmsg,sizeof(canmsg_t)); |
42 res = read(fd0,&canmsg,sizeof(canmsg_t)); |
63 if((res<0)&&(errno == -EAGAIN)) res = 0; |
43 if((res<0)&&(errno == -EAGAIN)) res = 0; |
64 }while(res==0); |
44 }while(res==0); |
65 |
45 |
66 if(res != sizeof(canmsg_t)) // No new message |
46 if(res != sizeof(canmsg_t)) // No new message |
67 return 1; |
47 return 1; |
80 } |
60 } |
81 |
61 |
82 return 0; |
62 return 0; |
83 } |
63 } |
84 |
64 |
85 void canReceiveLoop(CAN_HANDLE fd0) |
|
86 { |
|
87 CO_Data* d = fd0->d; |
|
88 Message m; |
|
89 while (fd0->used) { |
|
90 if(!canReceive(fd0, &m)) |
|
91 { |
|
92 EnterMutex(); |
|
93 canDispatch(d, &m); |
|
94 LeaveMutex(); |
|
95 }else{ |
|
96 printf("canReceive returned error\n"); |
|
97 break; |
|
98 } |
|
99 } |
|
100 } |
|
101 |
|
102 /***************************************************************************/ |
65 /***************************************************************************/ |
103 UNS8 canSend(CAN_HANDLE fd0, Message *m) |
66 UNS8 canSend_driver(CAN_HANDLE fd0, Message *m) |
104 { |
67 { |
105 int res; |
68 int res; |
106 struct canmsg_t canmsg; |
69 struct canmsg_t canmsg; |
107 |
70 |
108 |
71 |
117 |
80 |
118 if(canmsg.id >= 0x800){ |
81 if(canmsg.id >= 0x800){ |
119 canmsg.flags |= MSG_EXT; |
82 canmsg.flags |= MSG_EXT; |
120 } |
83 } |
121 |
84 |
122 res = write(fd0->fd,&canmsg,sizeof(canmsg_t)); |
85 res = write(fd0,&canmsg,sizeof(canmsg_t)); |
123 if(res!=sizeof(canmsg_t)) |
86 if(res!=sizeof(canmsg_t)) |
124 return 1; |
87 return 1; |
125 |
88 |
126 return 0; |
89 return 0; |
127 } |
90 } |
128 |
91 |
129 /***************************************************************************/ |
92 /***************************************************************************/ |
130 static const char lnx_can_dev_prefix[] = "/dev/can"; |
93 static const char lnx_can_dev_prefix[] = "/dev/can"; |
131 |
94 |
132 CAN_HANDLE canOpen(s_BOARD *board) |
95 CAN_HANDLE canOpen_driver(s_BOARD *board) |
133 { |
96 { |
134 int name_len = strlen(board->busname); |
97 int name_len = strlen(board->busname); |
135 int prefix_len = strlen(lnx_can_dev_prefix); |
98 int prefix_len = strlen(lnx_can_dev_prefix); |
136 char dev_name[prefix_len+name_len+1]; |
99 char dev_name[prefix_len+name_len+1]; |
137 int o_flags = 0; |
100 int o_flags = 0; |
145 |
108 |
146 memcpy(dev_name,lnx_can_dev_prefix,prefix_len); |
109 memcpy(dev_name,lnx_can_dev_prefix,prefix_len); |
147 memcpy(dev_name+prefix_len,board->busname,name_len); |
110 memcpy(dev_name+prefix_len,board->busname,name_len); |
148 dev_name[prefix_len+name_len] = 0; |
111 dev_name[prefix_len+name_len] = 0; |
149 |
112 |
150 fd0->fd = open(dev_name, O_RDWR|o_flags); |
113 fd0 = open(dev_name, O_RDWR|o_flags); |
151 if(fd0->fd < 0){ |
114 if(fd0 < 0){ |
152 fprintf(stderr,"!!! Board %s is unknown. See can_lincan.c\n", board->busname); |
115 fprintf(stderr,"!!! Board %s is unknown. See can_lincan.c\n", board->busname); |
153 goto error_ret; |
116 goto error_ret; |
154 } |
117 } |
155 |
118 |
156 fd0->d = board->d; |
|
157 fd0->used = 1; |
|
158 CreateReceiveTask(fd0, &fd0->receiveTask); |
|
159 return fd0; |
119 return fd0; |
160 |
120 |
161 error_ret: |
121 error_ret: |
162 free(fd0); |
122 free(fd0); |
163 return NULL; |
123 return NULL; |
164 } |
124 } |
165 |
125 |
166 /***************************************************************************/ |
126 /***************************************************************************/ |
167 int canClose(CAN_HANDLE fd0) |
127 int canClose_driver(CAN_HANDLE fd0) |
168 { |
128 { |
169 if(!fd0) |
129 if(!fd0) |
170 return 0; |
130 return 0; |
171 fd0->used = 0; |
131 close(fd0); |
172 WaitReceiveTaskEnd(&fd0->receiveTask); |
|
173 close(fd0->fd); |
|
174 free(fd0); |
|
175 return 0; |
132 return 0; |
176 } |
133 } |