Xenomai  3.0.8
rtcan_socket.h
1 /*
2  * Copyright (C) 2005,2006 Sebastian Smolorz
3  * <Sebastian.Smolorz@stud.uni-hannover.de>
4  *
5  * Copyright (C) 2006 Wolfgang Grandegger <wg@grandegger.com>
6  *
7  *
8  * Derived from RTnet project file include/stack/socket.h:
9  *
10  * Copyright (C) 1999 Lineo, Inc
11  * 1999, 2002 David A. Schleef <ds@schleef.org>
12  * 2002 Ulrich Marx <marx@kammer.uni-hannover.de>
13  * 2003-2005 Jan Kiszka <jan.kiszka@web.de>
14  *
15  *
16  * This program is free software; you can redistribute it and/or modify it
17  * under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 2 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful, but
22  * WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24  * General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software Foundation,
28  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29  */
30 
31 #ifndef __RTCAN_SOCKET_H_
32 #define __RTCAN_SOCKET_H_
33 
34 #include <rtdm/driver.h>
35 
36 #include <rtdm/can.h>
37 
38 
39 
40 /* This MUST BE 2^N */
41 #define RTCAN_RXBUF_SIZE CONFIG_XENO_DRIVERS_CAN_RXBUF_SIZE
42 
43 /* Size of timestamp */
44 #define RTCAN_TIMESTAMP_SIZE sizeof(nanosecs_abs_t)
45 
46 /* Bit in the can_dlc member of struct ring_buffer_frame used to indicate
47  * whether a frame has got a timestamp or not */
48 #define RTCAN_HAS_TIMESTAMP 0x80
49 
50 /* Mask for clearing bit RTCAN_HAS_TIMESTAMP */
51 #define RTCAN_HAS_NO_TIMESTAMP 0x7F
52 
53 #define RTCAN_SOCK_UNBOUND -1
54 #define RTCAN_FLIST_NO_FILTER (struct rtcan_filter_list *)-1
55 #define rtcan_flist_no_filter(f) ((f) == RTCAN_FLIST_NO_FILTER)
56 #define rtcan_sock_has_filter(s) ((s)->flistlen > 0)
57 #define rtcan_sock_is_bound(s) ((s)->flistlen >= 0)
58 
59 /*
60  * Internal frame representation within the ring buffer of a
61  * struct rtcan_socket.
62  *
63  * The data array is of arbitrary size when the frame is actually
64  * stored in a socket's ring buffer. The timestamp member exists if the
65  * socket was set to take timestamps (then it follows direcly after the
66  * arbitrary-sized data array), otherwise it does not exist.
67  */
68 struct rtcan_rb_frame {
69 
70  /* CAN ID representation equal to struct can_frame */
71  uint32_t can_id;
72 
73  /* Interface index from which the frame originates */
74  unsigned char can_ifindex;
75 
76  /* DLC (between 0 and 15) and mark if frame has got a timestamp. The
77  * existence of a timestamp is indicated by the RTCAN_HAS_TIMESTAMP
78  * bit. */
79  unsigned char can_dlc;
80 
81  /* Data bytes */
82  uint8_t data[8];
83 
84  /* High precision timestamp indicating when the frame was received.
85  * Exists when RTCAN_HAS_TIMESTAMP bit in can_dlc is set. */
86  nanosecs_abs_t timestamp;
87 
88 } __attribute__ ((packed));
89 
90 
91 /* Size of struct rtcan_rb_frame without any data bytes and timestamp */
92 #define EMPTY_RB_FRAME_SIZE \
93  sizeof(struct rtcan_rb_frame) - 8 - RTCAN_TIMESTAMP_SIZE
94 
95 
96 /*
97  * Wrapper structure around a struct rtcan_rb_frame with actual size
98  * of the frame.
99  *
100  * This isn't really a socket buffer but only a sort of. It is constructed
101  * within the interrupt routine when a CAN frame is read from
102  * the controller. Then it's passed to the reception handler where only
103  * rb_frame finds its way to the sockets' ring buffers.
104  */
105 struct rtcan_skb {
106  /* Actual size of following rb_frame (without timestamp) */
107  size_t rb_frame_size;
108  /* Frame to be stored in the sockets' ring buffers (as is) */
109  struct rtcan_rb_frame rb_frame;
110 };
111 
112 struct rtcan_filter_list {
113  int flistlen;
114  struct can_filter flist[1];
115 };
116 
117 /*
118  * Internal CAN socket structure.
119  *
120  * Every socket has an internal ring buffer for incoming messages. A message
121  * is not stored as a struct can_frame (in order to save buffer space)
122  * but as struct rtcan_rb_frame of arbitrary length depending on the
123  * actual payload.
124  */
125 struct rtcan_socket {
126 
127  struct list_head socket_list;
128 
129  unsigned long flags;
130 
131  /* Transmission timeout in ns. Protected by rtcan_socket_lock
132  * in all socket structures. */
133  nanosecs_rel_t tx_timeout;
134 
135  /* Reception timeout in ns. Protected by rtcan_socket_lock
136  * in all socket structures. */
137  nanosecs_rel_t rx_timeout;
138 
139 
140  /* Begin of first frame data in the ring buffer. Protected by
141  * rtcan_socket_lock in all socket structures. */
142  int recv_head;
143 
144  /* End of last frame data in the ring buffer. I.e. position of first
145  * free byte in the ring buffer. Protected by
146  * rtcan_socket_lock in all socket structures. */
147  int recv_tail;
148 
149  /* Ring buffer for incoming CAN frames. Protected by
150  * rtcan_socket_lock in all socket structures. */
151  unsigned char recv_buf[RTCAN_RXBUF_SIZE];
152 
153  /* Semaphore for receivers and incoming messages */
154  rtdm_sem_t recv_sem;
155 
156 
157  /* All senders waiting to be able to send
158  * via this socket are queued here */
159  struct list_head tx_wait_head;
160 
161 
162  /* Interface index the socket is bound to. Protected by
163  * rtcan_recv_list_lock in all socket structures. */
164  atomic_t ifindex;
165 
166  /* Length of filter list. I.e. how many entries does this socket occupy in
167  * the reception list. 0 if unbound. Protected by
168  * rtcan_recv_list_lock in all socket structures. */
169  int flistlen;
170 
171  uint32_t err_mask;
172 
173  uint32_t rx_buf_full;
174 
175  struct rtcan_filter_list *flist;
176 
177 #ifdef CONFIG_XENO_DRIVERS_CAN_LOOPBACK
178  int loopback;
179 #endif
180 };
181 
182 
183 
184 /*
185  * Get the RTDM context from a struct rtcan_socket
186  *
187  * @param[in] sock Pointer to socket structure
188  *
189  * @return Pointer to a file descriptor of type struct rtdm_fd this socket
190  * belongs to
191  */
192 /* FIXME: to be replaced with container_of */
193 static inline struct rtdm_fd *rtcan_socket_to_fd(struct rtcan_socket *sock)
194 {
195  return rtdm_private_to_fd(sock);
196 }
197 
198 /* Spinlock protecting the ring buffers and the timeouts of all
199  * rtcan_sockets */
200 extern rtdm_lock_t rtcan_socket_lock;
201 extern struct list_head rtcan_socket_list;
202 
203 extern void rtcan_socket_init(struct rtdm_fd *fd);
204 extern void rtcan_socket_cleanup(struct rtdm_fd *fd);
205 
206 
207 #endif /* __RTCAN_SOCKET_H_ */
ipipe_spinlock_t rtdm_lock_t
Lock variable.
Definition: driver.h:551
int64_t nanosecs_rel_t
RTDM type for representing relative intervals.
Definition: rtdm.h:49
Real-Time Driver Model for Xenomai, driver API header.
uint64_t nanosecs_abs_t
RTDM type for representing absolute dates.
Definition: rtdm.h:43
Copyright © 2011 Gilles Chanteperdrix gilles.chanteperdrix@xenomai.org.
Definition: atomic.h:24
Filter for reception of CAN messages.
Definition: can.h:287
static struct rtdm_fd * rtdm_private_to_fd(void *dev_private)
Locate a device file descriptor structure from its driver private area.
Definition: driver.h:174