1 |
27 |
unneback |
|
2 |
|
|
|
3 |
|
|
|
4 |
|
|
|
5 |
|
|
|
6 |
|
|
|
7 |
|
|
|
8 |
|
|
|
9 |
|
|
|
10 |
|
|
|
11 |
|
|
|
12 |
|
|
|
13 |
|
|
|
14 |
|
|
|
15 |
|
|
|
16 |
|
|
|
17 |
|
|
|
18 |
|
|
|
19 |
|
|
|
20 |
|
|
|
21 |
|
|
|
22 |
|
|
|
23 |
|
|
|
24 |
|
|
|
25 |
|
|
|
26 |
|
|
|
27 |
|
|
|
28 |
|
|
|
29 |
|
|
|
30 |
|
|
|
31 |
|
|
|
32 |
|
|
|
33 |
|
|
|
34 |
|
|
|
35 |
|
|
|
36 |
|
|
|
37 |
|
|
|
38 |
|
|
|
39 |
|
|
|
40 |
|
|
|
41 |
|
|
eCos Support for Developing USB-ethernet Peripherals
|
42 |
|
|
|
43 |
|
|
|
44 |
|
|
|
45 |
|
|
|
46 |
|
|
|
47 |
|
|
Introduction
|
48 |
|
|
|
49 |
|
|
|
50 |
|
|
Introduction
|
51 |
|
|
eCos support for developing USB ethernet peripherals
|
52 |
|
|
|
53 |
|
|
|
54 |
|
|
Introduction
|
55 |
|
|
|
56 |
|
|
The eCos USB-ethernet package provides additional support for USB
|
57 |
|
|
peripherals that involve some sort of ethernet-style network. This can
|
58 |
|
|
be a traditional ethernet, or it can involve some other networking
|
59 |
|
|
technology that uses ethernet frames as a unit of transfer. It
|
60 |
|
|
provides functions to transfer ethernet frames over the USB bus,
|
61 |
|
|
handles certain control messages from the host, and optionally it can
|
62 |
|
|
provide a network device driver for use by the eCos TCP/IP stack.
|
63 |
|
|
The package comes with an example host-side device driver.
|
64 |
|
|
|
65 |
|
|
|
66 |
|
|
The USB-ethernet package is not tied to any specific hardware. It
|
67 |
|
|
requires the presence of USB hardware and a suitable device driver,
|
68 |
|
|
but not all USB peripherals involve ethernet communications. Hence the
|
69 |
|
|
configuration system cannot load the package automatically for
|
70 |
|
|
specific targets, in the way that a USB device driver or an ethernet
|
71 |
|
|
driver can be loaded automatically. Instead, the package has to be
|
72 |
|
|
added explicitly. When using the command line tools this will involve
|
73 |
|
|
an operation like the following:
|
74 |
|
|
|
75 |
|
|
|
76 |
|
|
$ ecosconfig add usbs_eth
|
77 |
|
|
|
78 |
|
|
|
79 |
|
|
Typically, this will automatically cause the USB device driver to
|
80 |
|
|
become active. Loading the USB-ethernet package automatically provides
|
81 |
|
|
functionality for initialization,
|
82 |
|
|
data transfer, and the handling of
|
83 |
|
|
control messages and state
|
84 |
|
|
changes. If the current configuration includes the eCos TCP/IP stack
|
85 |
|
|
then the network device driver
|
86 |
|
|
support will be enabled as well by default, allowing the stack to
|
87 |
|
|
exchange ethernet frames over the USB bus.
|
88 |
|
|
|
89 |
|
|
|
90 |
|
|
There is a USB standard for a class of communication devices including
|
91 |
|
|
ethernet. The package does not implement this standard, due to
|
92 |
|
|
limitations in the hardware for which the package was first developed.
|
93 |
|
|
Instead, the package uses its own
|
94 |
|
|
linkend="usbseth-protocol">protocol between USB
|
95 |
|
|
host device driver and the
|
96 |
|
|
peripheral.
|
97 |
|
|
|
98 |
|
|
|
99 |
|
|
|
100 |
|
|
Usage Scenarios
|
101 |
|
|
|
102 |
|
|
The USB-ethernet package can be used several different scenarios. In
|
103 |
|
|
a simple scenario, the peripheral serves only to connect the USB host
|
104 |
|
|
to a suitable network:
|
105 |
|
|
|
106 |
|
|
|
107 |
|
|
|
108 |
|
|
|
109 |
|
|
|
110 |
|
|
|
111 |
|
|
|
112 |
|
|
|
113 |
|
|
|
114 |
|
|
After initialization, and once the USB connection between host and
|
115 |
|
|
peripheral has been established, higher-level code needs to detect
|
116 |
|
|
packets that are intended for the host, and to forward these. This can
|
117 |
|
|
be achieved by the low-level usbs_eth_start_tx
|
118 |
|
|
function. Similarly, higher-level code needs to detect packets coming
|
119 |
|
|
from the host, using usbs_eth_start_rx, and to
|
120 |
|
|
forward these using the real network. As far as the host is concerned
|
121 |
|
|
it is connected directly to the network. In this scenario there is no
|
122 |
|
|
confusion about addresses: there is a single MAC address for the
|
123 |
|
|
host/peripheral combination, corresponding to the connection to the
|
124 |
|
|
real network, and it is this address which should be supplied during
|
125 |
|
|
initialization.
|
126 |
|
|
|
127 |
|
|
|
128 |
|
|
In a more complicated scenario, there is a TCP/IP stack running inside
|
129 |
|
|
the peripheral.
|
130 |
|
|
|
131 |
|
|
|
132 |
|
|
|
133 |
|
|
|
134 |
|
|
|
135 |
|
|
|
136 |
|
|
|
137 |
|
|
|
138 |
|
|
|
139 |
|
|
This involves the USB-ethernet package providing a service both to the
|
140 |
|
|
host and to the eCos TCP/IP stack. It achieves the latter by acting as
|
141 |
|
|
an eCos network device. Typically, the TCP/IP stack will be configured
|
142 |
|
|
to act as a network bridge. The USB peripheral needs to examine the
|
143 |
|
|
packets arriving over the real network. Some of these packets will be
|
144 |
|
|
intended for the host, while others will be intended for the
|
145 |
|
|
peripheral itself. To distinguish between these two scenarios, two
|
146 |
|
|
distinct MAC addresses are needed: one for the host, and one for the
|
147 |
|
|
peripheral. Similarly, packets sent by the host may have to be
|
148 |
|
|
forwarded via the real network, or they may be intended for the TCP/IP
|
149 |
|
|
stack inside the peripheral. Packets generated inside the peripheral's
|
150 |
|
|
TCP/IP stack may need to be sent via the real network or over the USB
|
151 |
|
|
bus. The network bridge software will have to take care of all these
|
152 |
|
|
possibilities. Unusually for a network bridge, one of the network
|
153 |
|
|
segments being bridged will only ever have one machine attached.
|
154 |
|
|
|
155 |
|
|
|
156 |
|
|
There are other possible usage scenarios. For example, the peripheral
|
157 |
|
|
might not be attached to a real network at all. Instead it could be
|
158 |
|
|
the USB host that acts as a network bridge, allowing a TCP/IP stack
|
159 |
|
|
inside the peripheral to communicate with the outside world. The
|
160 |
|
|
various details will depend on the exact type of peripheral being
|
161 |
|
|
developed.
|
162 |
|
|
|
163 |
|
|
|
164 |
|
|
|
165 |
|
|
|
166 |
|
|
|
167 |
|
|
|
168 |
|
|
|
169 |
|
|
|
170 |
|
|
|
171 |
|
|
Initializing the USB-ethernet Package
|
172 |
|
|
|
173 |
|
|
|
174 |
|
|
usbs_eth_init
|
175 |
|
|
Initializing the USB-ethernet Package
|
176 |
|
|
|
177 |
|
|
|
178 |
|
|
|
179 |
|
|
|
180 |
|
|
|
181 |
|
|
#include <cyg/io/usb/usbs_eth.h>
|
182 |
|
|
|
183 |
|
|
|
184 |
|
|
void usbs_eth_init
|
185 |
|
|
usbs_eth* usbeth
|
186 |
|
|
usbs_control_endpoint* ep0
|
187 |
|
|
usbs_rx_endpoint* ep1
|
188 |
|
|
usbs_tx_endpoint* ep2
|
189 |
|
|
unsigned char* mac_address
|
190 |
|
|
|
191 |
|
|
|
192 |
|
|
|
193 |
|
|
|
194 |
|
|
Description
|
195 |
|
|
|
196 |
|
|
The USB-ethernet package is not tied to any specific hardware. It
|
197 |
|
|
requires certain functionality: there must be USB-slave hardware
|
198 |
|
|
supported by a device driver; there must also be two endpoints for
|
199 |
|
|
bulk transfers between host and peripheral, one for each direction;
|
200 |
|
|
there must also be a control endpoint, although of course that is
|
201 |
|
|
implicit with any USB hardware.
|
202 |
|
|
|
203 |
|
|
|
204 |
|
|
However, USB-slave hardware may well provide more endpoints than the
|
205 |
|
|
minimum required for ethernet support. Some of those endpoints might
|
206 |
|
|
be used by other packages, while other endpoints might be used
|
207 |
|
|
directly by the application, or might not be needed for the peripheral
|
208 |
|
|
being built. There is also the possibility of a USB peripheral that
|
209 |
|
|
supports multiple configurations, with the ethernet support active in
|
210 |
|
|
only some of those configurations. The USB-ethernet package has no
|
211 |
|
|
knowledge about any of this, so it relies on higher-level code to tell
|
212 |
|
|
it which endpoints should be used and other information. This is the
|
213 |
|
|
purpose of the usbs_eth_init function.
|
214 |
|
|
|
215 |
|
|
|
216 |
|
|
The first argument identifies the specific
|
217 |
|
|
usbs_eth data structure that is affected. It
|
218 |
|
|
is expected that the vast majority of affected applications will only
|
219 |
|
|
provide a single USB-ethernet device to a single host, and the package
|
220 |
|
|
automatically provides a suitable data structure
|
221 |
|
|
usbs_eth0 to support this. If multiple
|
222 |
|
|
usbs_eth structures are needed for some
|
223 |
|
|
reason then these need to be instantiated by other code, and each one
|
224 |
|
|
needs to be initialised by a call to
|
225 |
|
|
usbs_eth_init().
|
226 |
|
|
|
227 |
|
|
|
228 |
|
|
The next three arguments identify the endpoints that should be used
|
229 |
|
|
for USB communications: a control endpoint, a receive endpoint for
|
230 |
|
|
ethernet packets coming from the host to the peripheral, and a
|
231 |
|
|
transmit endpoint for ethernet packets going in the other direction.
|
232 |
|
|
Obviously all three endpoints should be provided by the same USB
|
233 |
|
|
hardware. The USB-ethernet package assumes that it has sole access to
|
234 |
|
|
the receive and transmit endpoints, subject to the use of
|
235 |
|
|
usbs_eth_disable and
|
236 |
|
|
usbs_eth_enable control functions. The package
|
237 |
|
|
also assumes that no other code is interested in USB state changes or
|
238 |
|
|
class control messages: it installs handlers
|
239 |
|
|
usbs_eth_state_change_handler
|
240 |
|
|
and
|
241 |
|
|
usbs_eth_class_control_handler
|
242 |
|
|
in the control endpoint. If any other code does need to handle USB
|
243 |
|
|
state changes or class control messages then replacement handlers
|
244 |
|
|
should be installed after the call to
|
245 |
|
|
usbs_eth_init, and those replacements should
|
246 |
|
|
invoke the USB-ethernet ones when appropriate.
|
247 |
|
|
|
248 |
|
|
|
249 |
|
|
The final argument to usbs_eth_init specifies
|
250 |
|
|
the MAC address (or Ethernet Station Address) that should be provided
|
251 |
|
|
to the host-side device driver. Since the USB-ethernet package does not
|
252 |
|
|
interact directly with a real ethernet device it cannot obtain the MAC
|
253 |
|
|
address from any hardware. Instead, it must be supplied by higher-level
|
254 |
|
|
code. The details depend on the
|
255 |
|
|
linkend="usbseth-intro-scenarios">scenario in which the
|
256 |
|
|
USB-ethernet package is being used.
|
257 |
|
|
|
258 |
|
|
|
259 |
|
|
The call to usbs_eth_init should normally happen
|
260 |
|
|
after the enumeration data has been provided but before the underlying
|
261 |
|
|
USB device driver has been started. If the USB device were to be
|
262 |
|
|
started first then a connection between host and peripheral could be
|
263 |
|
|
established immediately, and the host-side device driver would attempt
|
264 |
|
|
to contact the USB-ethernet package for information such as the MAC
|
265 |
|
|
address.
|
266 |
|
|
|
267 |
|
|
|
268 |
|
|
int
|
269 |
|
|
main(int argc, char** argv)
|
270 |
|
|
{
|
271 |
|
|
unsigned char host_MAC[6] = { 0x40, 0x5d, 0x90, 0xa9, 0xbc, 0x02 };
|
272 |
|
|
|
273 |
|
|
usbs_sa11x0_ep0.enumeration_data = &usb_enum_data;
|
274 |
|
|
…
|
275 |
|
|
usbs_eth_init(&usbs_eth0, &usbs_sa11x0_ep0, &usbs_sa11x0_ep1, &usbs_sa11x0_ep2, host_MAC);
|
276 |
|
|
…
|
277 |
|
|
usbs_start(&usbs_sa11x0_ep0);
|
278 |
|
|
…
|
279 |
|
|
}
|
280 |
|
|
|
281 |
|
|
|
282 |
|
|
|
283 |
|
|
|
284 |
|
|
|
285 |
|
|
|
286 |
|
|
|
287 |
|
|
|
288 |
|
|
|
289 |
|
|
|
290 |
|
|
USB-ethernet Data Transfers
|
291 |
|
|
|
292 |
|
|
|
293 |
|
|
USB-ethernet Data Transfers
|
294 |
|
|
Exchanging ethernet packets with the USB host
|
295 |
|
|
|
296 |
|
|
|
297 |
|
|
|
298 |
|
|
|
299 |
|
|
|
300 |
|
|
#include <cyg/io/usb/usbs_eth.h>
|
301 |
|
|
|
302 |
|
|
|
303 |
|
|
|
304 |
|
|
void usbs_eth_start_rx
|
305 |
|
|
usbs_eth* usbseth
|
306 |
|
|
unsigned char* buffer
|
307 |
|
|
void (*)(usbs_eth*, void*, int) complete_fn
|
308 |
|
|
void* complete_data
|
309 |
|
|
|
310 |
|
|
|
311 |
|
|
|
312 |
|
|
void usbs_eth_start_tx
|
313 |
|
|
usbs_eth* usbseth
|
314 |
|
|
unsigned char* buffer
|
315 |
|
|
void (*)(usbs_eth*, void*, int) complete_fn
|
316 |
|
|
void* complete_data
|
317 |
|
|
|
318 |
|
|
|
319 |
|
|
|
320 |
|
|
|
321 |
|
|
|
322 |
|
|
Description
|
323 |
|
|
|
324 |
|
|
The USB-ethernet package provides two main modes of operation. In the
|
325 |
|
|
first mode it provides a network device
|
326 |
|
|
driver for use by a TCP/IP stack running inside the USB
|
327 |
|
|
peripheral. All incoming ethernet packages should be passed up the
|
328 |
|
|
TCP/IP stack, and only the stack will generate outgoing packets. Apart
|
329 |
|
|
from initialization and possibly
|
330 |
|
|
certain control operations,
|
331 |
|
|
higher-level code will not interact with the USB-ethernet package
|
332 |
|
|
directly.
|
333 |
|
|
|
334 |
|
|
|
335 |
|
|
In the second mode there is no TCP/IP stack running inside the USB
|
336 |
|
|
peripheral. For example, a simple USB-ethernet converter has an
|
337 |
|
|
ethernet chip and a USB port: ethernet packets received by the
|
338 |
|
|
ethernet chip need to be forwarded to the USB host, and ethernet
|
339 |
|
|
packets sent by the USB host need to be sent out of the ethernet chip.
|
340 |
|
|
usbs_eth_start_rx and
|
341 |
|
|
usbs_eth_start_tx allow for this lower-level
|
342 |
|
|
access to the USB-ethernet package.
|
343 |
|
|
|
344 |
|
|
|
345 |
|
|
The two modes of operation are mutually exclusive. If the network
|
346 |
|
|
device driver mode is enabled then application code should communicate
|
347 |
|
|
at the TCP/IP level, and not by using the lower-level functions.
|
348 |
|
|
Instead, it is the network device driver that will make use of these
|
349 |
|
|
functions, and it assumes that it has exclusive access. The package
|
350 |
|
|
does not perform any locking.
|
351 |
|
|
|
352 |
|
|
|
353 |
|
|
The transmit and receive functions work in much the same way. The
|
354 |
|
|
first argument identifies the usbs_eth
|
355 |
|
|
structure that should be used. For the majority of applications this
|
356 |
|
|
will be usbs_eth0. The second argument specifies
|
357 |
|
|
the location of the ethernet packet; outgoing for
|
358 |
|
|
usbs_eth_start_tx and incoming for
|
359 |
|
|
usbs_eth_start_rx. This buffer should correspond
|
360 |
|
|
to the protocol:
|
361 |
|
|
|
362 |
|
|
|
363 |
|
|
|
364 |
|
|
|
365 |
|
|
Outgoing packets can consist of up to 1516 bytes, consisting of a
|
366 |
|
|
two-byte header specific to USB-ethernet followed by a standard
|
367 |
|
|
ethernet frame (a header with 6-byte destination address, 6-byte
|
368 |
|
|
source address and a further two bytes, followed by a payload of
|
369 |
|
|
up to 1500 bytes). The two-byte USB-ethernet header consists simply of
|
370 |
|
|
the size of the ethernet frame, i.e. the size of the rest of the
|
371 |
|
|
packet not including the USB-ethernet header, with the least
|
372 |
|
|
significant byte first.
|
373 |
|
|
|
374 |
|
|
|
375 |
|
|
|
376 |
|
|
|
377 |
|
|
For incoming packets the supplied buffer should usually be at least
|
378 |
|
|
1516 bytes. There may be special circumstances in which a smaller
|
379 |
|
|
buffer might be safe; for example, if the host-side device driver is
|
380 |
|
|
modified to support only smaller packets. Once the packet has been
|
381 |
|
|
received the buffer will contain a two-byte header specific to
|
382 |
|
|
USB-ethernet, followed by a normal ethernet frame. The header
|
383 |
|
|
gives the size of the ethernet frame, excluding the header, with the
|
384 |
|
|
least significant byte first.
|
385 |
|
|
|
386 |
|
|
|
387 |
|
|
|
388 |
|
|
|
389 |
|
|
Both usbs_eth_start_tx and
|
390 |
|
|
usbs_eth_start_rx are asynchronous: the transfer
|
391 |
|
|
is started and, some time later, a completion function will be invoked.
|
392 |
|
|
The third and fourth arguments to both
|
393 |
|
|
usbs_eth_start_tx and
|
394 |
|
|
usbs_eth_start_rx supply the completion function
|
395 |
|
|
and an argument to that function respectively. The completion function
|
396 |
|
|
will be invoked with three arguments: a pointer to the
|
397 |
|
|
usbs_eth data structure, usually
|
398 |
|
|
usbs_eth0; the supplied completion data ; and a
|
399 |
|
|
return code field. A negative value indicates that an error occurred,
|
400 |
|
|
for example -EPIPE if the connection between USB
|
401 |
|
|
host and peripheral has been broken, or -EAGAIN if
|
402 |
|
|
an endpoint has been halted. A positive value indicates the total size
|
403 |
|
|
of the transfer, which should correspond to the size in the
|
404 |
|
|
USB-ethernet header plus an additional two bytes for the header
|
405 |
|
|
itself.
|
406 |
|
|
|
407 |
|
|
|
408 |
|
|
If the data transfer is succesful then the completion function will
|
409 |
|
|
typically be invoked in DSR context rather than in thread context,
|
410 |
|
|
although this depends on the implementation of the underlying USB
|
411 |
|
|
device driver. Therefore the completion function is restricted in what
|
412 |
|
|
it can do; in particular, it must not make any calls that will or may
|
413 |
|
|
block such as locking a mutex or allocating memory. The kernel
|
414 |
|
|
documentation should be consulted for more details of DSR's and
|
415 |
|
|
interrupt handling generally. Note that if the transfer finishes
|
416 |
|
|
quickly then the completion function may be invoked before
|
417 |
|
|
usbs_eth_start_rx or
|
418 |
|
|
usbs_eth_start_tx returns. This is especially
|
419 |
|
|
likely to happen if the current thread is descheduled after starting
|
420 |
|
|
the data transfer but before returning from these functions.
|
421 |
|
|
|
422 |
|
|
|
423 |
|
|
For transmit operations, it is possible for
|
424 |
|
|
usbs_eth_start_tx to invoke the completion
|
425 |
|
|
function immediately. If there is no current connection between host
|
426 |
|
|
and target then the transmit will fail immediately with
|
427 |
|
|
-EPIPE. In addition the USB-ethernet package will
|
428 |
|
|
check the destination MAC address and make sure that the ethernet
|
429 |
|
|
frame really is intended for the host: either it must be for the
|
430 |
|
|
address specified in the initialization call
|
431 |
|
|
linkend="usbseth-init">usbs_eth_init, or
|
432 |
|
|
it must be a broadcast packet, or the host must have enabled
|
433 |
|
|
promiscuous mode.
|
434 |
|
|
|
435 |
|
|
|
436 |
|
|
|
437 |
|
|
|
438 |
|
|
|
439 |
|
|
|
440 |
|
|
|
441 |
|
|
|
442 |
|
|
|
443 |
|
|
|
444 |
|
|
USB-ethernet State Handling
|
445 |
|
|
|
446 |
|
|
|
447 |
|
|
USB-ethernet State Handling
|
448 |
|
|
Maintaining the USB-ethernet connection with the host
|
449 |
|
|
|
450 |
|
|
|
451 |
|
|
|
452 |
|
|
|
453 |
|
|
|
454 |
|
|
#include <cyg/io/usb/usbs_eth.h>
|
455 |
|
|
|
456 |
|
|
|
457 |
|
|
|
458 |
|
|
usbs_control_return usbs_eth_class_control_handler
|
459 |
|
|
usbs_control_endpoint* ep0
|
460 |
|
|
void* callback_data
|
461 |
|
|
|
462 |
|
|
|
463 |
|
|
|
464 |
|
|
void usbs_eth_state_change_handler
|
465 |
|
|
usbs_control_endpoint* ep0
|
466 |
|
|
void* callback_data
|
467 |
|
|
usbs_state_change change
|
468 |
|
|
int old_state
|
469 |
|
|
|
470 |
|
|
|
471 |
|
|
|
472 |
|
|
void usbs_eth_disable
|
473 |
|
|
usbs_eth* usbseth>
|
474 |
|
|
|
475 |
|
|
|
476 |
|
|
void usbs_eth_enable
|
477 |
|
|
usbs_eth* usbseth>
|
478 |
|
|
|
479 |
|
|
|
480 |
|
|
|
481 |
|
|
|
482 |
|
|
|
483 |
|
|
Description
|
484 |
|
|
|
485 |
|
|
When the USB-ethernet package is initialized by a call to
|
486 |
|
|
linkend="usbseth-init">usbs_eth_init it
|
487 |
|
|
installs usbs_eth_state_change_handler to handle
|
488 |
|
|
USB state changes. This allows the package to detect when the
|
489 |
|
|
connection between the host and the peripheral is established or
|
490 |
|
|
broken, resulting in internal calls to
|
491 |
|
|
usbs_eth_enable and
|
492 |
|
|
usbs_eth_disable respectively. This is
|
493 |
|
|
appropriate if no other code needs to access the USB device. However,
|
494 |
|
|
if there is other code, either other USB-related packages or the
|
495 |
|
|
application itself, that needs to perform I/O over the USB bus, then
|
496 |
|
|
typically the USB-ethernet package should not have exclusive access to
|
497 |
|
|
state change events. Instead, the assumption is that higher-level
|
498 |
|
|
code, typically provided by the application, will install an
|
499 |
|
|
alternative state change handler in the control endpoint data
|
500 |
|
|
structure after the call to usbs_eth_init. This
|
501 |
|
|
alternative handler will either chain into
|
502 |
|
|
usbs_eth_state_change_handler when appropriate,
|
503 |
|
|
or else it will invoke usbs_eth_enable and
|
504 |
|
|
usbs_eth_disable directly. For further details of
|
505 |
|
|
state change handlers and control endpoints generally, see the
|
506 |
|
|
documentation for the common USB-slave package.
|
507 |
|
|
|
508 |
|
|
|
509 |
|
|
Similarly, usbs_eth_init will install
|
510 |
|
|
usbs_eth_class_control_handler in the control
|
511 |
|
|
endpoint data structure as the appropriate handler for class-specific
|
512 |
|
|
USB control messages. This code will handle the ethernet-specific
|
513 |
|
|
control messages , for example
|
514 |
|
|
requests by the host to enable or disable promiscuous mode or to
|
515 |
|
|
obtain the MAC address. If the USB device is not shared with any other
|
516 |
|
|
code then this is both necessary and sufficient. However, if other code
|
517 |
|
|
is involved and if that code also needs to process certain control
|
518 |
|
|
messages, higher-level code should install its own handler and chain
|
519 |
|
|
to the USB-ethernet one when appropriate. It should be noted that the
|
520 |
|
|
request code is encoded in just a single byte, so there is a real
|
521 |
|
|
possibility that exactly the same number will be used by different
|
522 |
|
|
protocols for different requests. Any such problems will have to be
|
523 |
|
|
identified and resolved by application developers, and may involve
|
524 |
|
|
modifying the source code for the USB-ethernet package.
|
525 |
|
|
|
526 |
|
|
|
527 |
|
|
As an alternative to chaining the state change handler, higher-level
|
528 |
|
|
code can instead call usbs_eth_disable and
|
529 |
|
|
usbs_eth_enable directly. These functions may
|
530 |
|
|
also be called if the USB-ethernet package should become inactive for
|
531 |
|
|
reasons not related directly to events on the USB bus. The main effect
|
532 |
|
|
of usbs_eth_enable is to restart receive
|
533 |
|
|
operations and to allow transmits. The main effect of
|
534 |
|
|
usbs_eth_disable is to block further transmits:
|
535 |
|
|
any current receive operations need to be aborted at the USB level,
|
536 |
|
|
for example by halting the appropriate endpoint.
|
537 |
|
|
|
538 |
|
|
|
539 |
|
|
|
540 |
|
|
|
541 |
|
|
|
542 |
|
|
|
543 |
|
|
|
544 |
|
|
|
545 |
|
|
|
546 |
|
|
|
547 |
|
|
Network Device for the eCos TCP/IP Stack
|
548 |
|
|
|
549 |
|
|
|
550 |
|
|
Network Device
|
551 |
|
|
USB-ethernet support for the eCos TCP/IP Stack
|
552 |
|
|
|
553 |
|
|
|
554 |
|
|
Description
|
555 |
|
|
|
556 |
|
|
If the USB peripheral involves running the eCos TCP/IP stack and that
|
557 |
|
|
stack needs to use USB-ethernet as a transport layer (or as one of the
|
558 |
|
|
transports), then the USB-ethernet package can provide a suitable
|
559 |
|
|
network device driver. It is still necessary for higher-level code to
|
560 |
|
|
perform appropriate initialization by calling
|
561 |
|
|
linkend="usbseth-init">usbs_eth_init, but
|
562 |
|
|
after that it will be the TCP/IP stack rather than application code
|
563 |
|
|
that transmits or receives ethernet frames.
|
564 |
|
|
|
565 |
|
|
|
566 |
|
|
Not all peripherals involving the USB-ethernet package will require a
|
567 |
|
|
TCP/IP stack. Hence the provision of the network device is controlled
|
568 |
|
|
by a configuration option CYGPKG_USBS_ETHDRV. By
|
569 |
|
|
default this will be enabled if the TCP/IP package
|
570 |
|
|
CYGPKG_NET is loaded, and disabled otherwise.
|
571 |
|
|
|
572 |
|
|
|
573 |
|
|
There are a number of other configuration options related to the
|
574 |
|
|
network device. CYGFUN_USBS_ETHDRV_STATISTICS
|
575 |
|
|
determines whether or not the package will maintain statistics, mainly
|
576 |
|
|
intended for SNMP: by default this will be enabled if the SNMP support
|
577 |
|
|
package CYGPKG_SNMPAGENT is loaded, and disabled
|
578 |
|
|
otherwise. The name of the ethernet device is controlled by
|
579 |
|
|
CYGDATA_USBS_ETHDRV_NAME, and has a default value
|
580 |
|
|
of either eth0 or eth1
|
581 |
|
|
depending on whether or not there is another network device driver
|
582 |
|
|
present in the configuration.
|
583 |
|
|
|
584 |
|
|
|
585 |
|
|
Usually eCos network device drivers default to using DHCP for
|
586 |
|
|
obtaining necessary information such as IP addresses. This is not
|
587 |
|
|
appropriate for USB-ethernet devices. On the host-side the
|
588 |
|
|
USB-ethernet network device will not exist until the USB peripheral
|
589 |
|
|
has been plugged in and communication has been established. Therefore
|
590 |
|
|
any DHCP daemon on the host would not be listening on that network
|
591 |
|
|
device at the point that eCos requests its IP and other information. A
|
592 |
|
|
related issue is that the use of DHCP would imply the presence of a
|
593 |
|
|
DHCP daemon on every affected host machine, as opposed to a single
|
594 |
|
|
daemon (plus backups) for the network as a whole. For these reasons
|
595 |
|
|
the USB-ethernet package precludes the use of DHCP as a way of setting
|
596 |
|
|
the IP address, instead requiring alternatives such as manual
|
597 |
|
|
configuration.
|
598 |
|
|
|
599 |
|
|
|
600 |
|
|
|
601 |
|
|
|
602 |
|
|
|
603 |
|
|
|
604 |
|
|
|
605 |
|
|
|
606 |
|
|
|
607 |
|
|
|
608 |
|
|
Example Host-side Device Driver
|
609 |
|
|
|
610 |
|
|
|
611 |
|
|
Example Host-side Device Driver
|
612 |
|
|
Provide host-side support for the eCos USB-ethernet package
|
613 |
|
|
|
614 |
|
|
|
615 |
|
|
Description
|
616 |
|
|
|
617 |
|
|
The USB-ethernet package is supplied with a single host-side device
|
618 |
|
|
driver. This driver has been developed against the Linux kernel
|
619 |
|
|
2.2.16-22, as shipped with Red Hat 7. The driver is provided as is and
|
620 |
|
|
should not be considered production quality: for example it only
|
621 |
|
|
checks for a bogus vendor id 0x4242 rather than an
|
622 |
|
|
official vendor id supplied by the
|
623 |
|
|
url="http://www.usb.org/">USB Implementers Forum. Also, if the
|
624 |
|
|
peripheral involves multiple configurations or multiple interfaces, it
|
625 |
|
|
will fail to detect this. However, the driver can be used for simple
|
626 |
|
|
testing and as the basis of a full device driver. Details of the
|
627 |
|
|
protocol used between host and peripheral can be found in the
|
628 |
|
|
linkend="usbseth-protocol">Communication Protocol section.
|
629 |
|
|
|
630 |
|
|
|
631 |
|
|
The host-side device driver can be found in the
|
632 |
|
|
class="directory">host subdirectory of the USB-ethernet
|
633 |
|
|
package, specifically the file ecos_usbeth.c, and
|
634 |
|
|
comes with a Makefile. Both files may need
|
635 |
|
|
to be modified for specific applications. For example, the vendor id
|
636 |
|
|
table ecos_usbeth_implementations may need to be
|
637 |
|
|
updated for the specific USB peripheral being built. The
|
638 |
|
|
Makefile assumes that the Linux kernel sources
|
639 |
|
|
reside in /usr/src/linux, and
|
640 |
|
|
that the kernel has already been configured and built. Assuming this
|
641 |
|
|
is the case, the device driver can be built simply by invoking
|
642 |
|
|
make with no additional arguments. This will result
|
643 |
|
|
in a dynamically loadable kernel module,
|
644 |
|
|
ecos_usbeth.o, in the current directory.
|
645 |
|
|
|
646 |
|
|
|
647 |
|
|
|
648 |
|
|
As normal for Linux kernel builds, the generated files such as
|
649 |
|
|
ecos_usbeth.o live in the same directory as the
|
650 |
|
|
source tree. This is very different from eCos where the source tree
|
651 |
|
|
(or component repository) is kept separate from any builds. There may
|
652 |
|
|
be problems if the component repository is kept read-only or if it is
|
653 |
|
|
put under source code control. Any such problems can be avoided by
|
654 |
|
|
making a copy of the host
|
655 |
|
|
subdirectory and building that copy.
|
656 |
|
|
|
657 |
|
|
|
658 |
|
|
|
659 |
|
|
Loading the kernel module into the current system requires root
|
660 |
|
|
privileges. If the generic USB support is also a loadable module and
|
661 |
|
|
has not been loaded already, this must happen first:
|
662 |
|
|
|
663 |
|
|
|
664 |
|
|
# insmod usb-uhci
|
665 |
|
|
Using /lib/modules/2.2.16-22/usb/usb-uhci.o
|
666 |
|
|
|
667 |
|
|
|
668 |
|
|
Depending on the host hardware, the uhci or
|
669 |
|
|
usb-ohci modules may be more appropriate. Loading
|
670 |
|
|
the generic USB module will typically result in a number of messages
|
671 |
|
|
to the logfile /var/log/messages, giving details
|
672 |
|
|
of the specific host-side hardware that has been detected plus any
|
673 |
|
|
hubs. The next step is to load the USB-ethernet module:
|
674 |
|
|
|
675 |
|
|
|
676 |
|
|
# insmod ecos_usbeth.o
|
677 |
|
|
|
678 |
|
|
|
679 |
|
|
This should result in a number of additional diagnostics in the
|
680 |
|
|
logfile:
|
681 |
|
|
|
682 |
|
|
|
683 |
|
|
Apr 1 18:01:08 grumpy kernel: eCos USB-ethernet device driver
|
684 |
|
|
Apr 1 18:01:08 grumpy kernel: usb.c: registered new driver ecos_usbeth
|
685 |
|
|
|
686 |
|
|
|
687 |
|
|
If a suitable USB peripheral is now connected the host will detect
|
688 |
|
|
this, assign an address in the local USB network, obtain enumeration
|
689 |
|
|
data, and find a suitable device driver. Assuming the peripheral and
|
690 |
|
|
device driver agree on the supported vendor ids, the
|
691 |
|
|
ecos_usbeth.o module will be selected and this
|
692 |
|
|
will be reported in the system log:
|
693 |
|
|
|
694 |
|
|
|
695 |
|
|
Apr 1 18:04:12 grumpy kernel: usb.c: USB new device connect, assigned device number 3
|
696 |
|
|
Apr 1 18:04:12 grumpy kernel: eCos-based USB ethernet peripheral active at eth1
|
697 |
|
|
|
698 |
|
|
|
699 |
|
|
What can happen next depends very much on the software that is running
|
700 |
|
|
on top of the USB-ethernet package inside the peripheral. For example,
|
701 |
|
|
if there is a TCP/IP stack then it should be possible to bring up a
|
702 |
|
|
network connection between host and peripheral using
|
703 |
|
|
ifconfig.
|
704 |
|
|
|
705 |
|
|
|
706 |
|
|
|
707 |
|
|
|
708 |
|
|
|
709 |
|
|
|
710 |
|
|
|
711 |
|
|
|
712 |
|
|
|
713 |
|
|
|
714 |
|
|
Communication Protocol
|
715 |
|
|
|
716 |
|
|
|
717 |
|
|
Communication Protocol
|
718 |
|
|
Protocol used between the host-side device driver and the eCos
|
719 |
|
|
USB-ethernet package
|
720 |
|
|
|
721 |
|
|
|
722 |
|
|
Description
|
723 |
|
|
|
724 |
|
|
There is a USB standard for the protocol to be used between the host
|
725 |
|
|
and a class of communication devices, including ethernet. However, the
|
726 |
|
|
eCos USB-ethernet package does not implement this protocol: the target
|
727 |
|
|
hardware for which the package was first developed had certain
|
728 |
|
|
limitations, and could not implement the standard. Instead, the package
|
729 |
|
|
implements a simple new protocol.
|
730 |
|
|
|
731 |
|
|
|
732 |
|
|
A USB-ethernet peripheral involves bulk transfers on two endpoints:
|
733 |
|
|
one endpoint will be used for packets from host to peripheral and the
|
734 |
|
|
other will be used for the opposite direction. Transfers in both
|
735 |
|
|
directions are variable length, with a lower limit of 16 bytes and an
|
736 |
|
|
upper limit of 1516 bytes. The first two bytes of each transfer
|
737 |
|
|
constitute a header specific to USB-ethernet. The next 14 bytes form
|
738 |
|
|
the normal header for an ethernet frame: destination MAC address,
|
739 |
|
|
source MAC address, and a protocol field. The remaining data, up to
|
740 |
|
|
1500 bytes, are the payload. The first two bytes give the size of the
|
741 |
|
|
ethernet frame, least significant byte first, with a value between 14
|
742 |
|
|
and 1514.
|
743 |
|
|
|
744 |
|
|
|
745 |
|
|
For example an ARP request from host to peripheral involves an
|
746 |
|
|
ethernet frame of 42 bytes (0x002A), with the usual 14-byte header and
|
747 |
|
|
a 28-byte payload. The destination is the broadcast address
|
748 |
|
|
0xFFFFFFFFFFFF. The source depends on the MAC address specified for
|
749 |
|
|
the host in the call to
|
750 |
|
|
linkend="usbseth-init">usbs_eth_init, e.g.
|
751 |
|
|
0x405D90A9BC02. The remaining data is as specified by the appropriate
|
752 |
|
|
IETF RFC's. The actual bulk
|
753 |
|
|
USB transfer involves the following sequence of 44 bytes:
|
754 |
|
|
|
755 |
|
|
|
756 |
|
|
2a 00 ff ff ff ff ff ff 40 5d 90 a9 bc 02 08 06
|
757 |
|
|
00 01 08 00 06 04 00 01 40 5d 90 a9 bc 02 0a 00
|
758 |
|
|
00 01 00 00 00 00 00 00 0a 00 00 02
|
759 |
|
|
|
760 |
|
|
|
761 |
|
|
In addition there are two control messages. These will be sent by the
|
762 |
|
|
host to endpoint 0, the control endpoint, and by default they will
|
763 |
|
|
be handled by
|
764 |
|
|
usbs_eth_class_control_handler. If class-specific
|
765 |
|
|
control messages are intercepted by other code then it is the
|
766 |
|
|
responsibility of that code to invoke the USB-ethernet handler when
|
767 |
|
|
appropriate.
|
768 |
|
|
|
769 |
|
|
|
770 |
|
|
The first control message can be used by the host to obtain a MAC
|
771 |
|
|
address:
|
772 |
|
|
|
773 |
|
|
|
774 |
|
|
#define ECOS_USBETH_CONTROL_GET_MAC_ADDRESS 0x01
|
775 |
|
|
|
776 |
|
|
|
777 |
|
|
The control message's type field should specify IN as the direction.
|
778 |
|
|
The request field should be 0x01. The length fields
|
779 |
|
|
should specify a size of 6 bytes. The remaining fields of the control
|
780 |
|
|
message will be ignored by the USB-ethernet package. The response
|
781 |
|
|
consists of the 6-byte MAC address supplied by the initialization call
|
782 |
|
|
|
783 |
|
|
linkend="usbseth-init">usbs_eth_init.
|
784 |
|
|
|
785 |
|
|
|
786 |
|
|
The second control message can be used by the host to enable or
|
787 |
|
|
disable promiscuous mode.
|
788 |
|
|
|
789 |
|
|
|
790 |
|
|
#define ECOS_USBETH_CONTROL_SET_PROMISCUOUS_MODE 0x02
|
791 |
|
|
|
792 |
|
|
|
793 |
|
|
This control message involves no further data so the length field
|
794 |
|
|
should be set to 0. The value field should be non-zero to enable
|
795 |
|
|
promiscuous mode, zero to disable it. The request field should be
|
796 |
|
|
0x02. The remaining fields in the control message
|
797 |
|
|
will be ignored. It is the responsibility of the host-side device
|
798 |
|
|
driver to keep track of whether or not promiscuous mode is currently
|
799 |
|
|
enabled. It will be disabled when the peripheral changes to
|
800 |
|
|
Configured state, typically at the point where the host-side device
|
801 |
|
|
driver has been activated.
|
802 |
|
|
|
803 |
|
|
|
804 |
|
|
|
805 |
|
|
|
806 |
|
|
|
807 |
|
|
|
808 |
|
|
|
809 |
|
|
|
810 |
|
|
|