Does anybody have a copy of ComediClientServer?
If so, can you send me a copy, please?
Calin Culianu's site (ajvar.org) seems to be done, and judging from an
earlier email on this list, it's been down for a while.
Thanks.
-bwb
Brent Baccala
cos...@freesoft.org
Don't do anything in the kernel. Modify comedilib as follows.
comedi_open() looks at the string passed into it. If it doesn't
contain a colon, proceed as before. If the string contains a colon,
then parse it as "DRIVERNAME:...", and attempts to dynamically load a
library called "comedi_DRIVERNAME". This library should export the
following functions:
- comedi_driver_open
- comedi_driver_close
- comedi_driver_ioctl
- comedi_driver_read
- comedi_driver_write
- comedi_driver_fileno
The comedilib now passes all of its low-level operations for this
device to the dynamic library instead of using system calls.
Some standard drivers we'd like to support:
"rpc:HOSTNAME:FILENAME" - Sun RPC service that connects to a remote
server and a remote COMEDI device
Obviously, we'll have to define the RPC protocol and write a server.
Just transport everything across 1-to-1. Some kind of authentication
will be required. Might want something similar for CORBA, too. This
will provide the functions of ComediClientServer, and in a much
cleaner manner (I hope).
"usb:" - generic USB protocol
(pick first device recognized by USB driver)
"usb:BBB.DDD" - generic USB protocol to bus BBB device DDD
"usb:id=VV.PP[.N]" - generic USB protocol to vendor VV product PP number N
For generic use (where we control the USB device firmware), a USB
protocol should be defined to transport COMEDI requests directly to
the device. Something very similar to the RPC protocol, I would
think, though able to take advantage of the multiple endpoints
available to a USB device. Maybe run the ioctl's on endpoint 0 and
put the reads and writes on two other endpoints.
For devices with USB protocols already defined, the USB driver library
would have to be programmed to handle the protocol. Alternately,
separate driver libraries with separate driver names could be used.
Obviously, mmap just wouldn't work with such a COMEDI device, and
applications should be prepared for this - they might be using a
remote device with no shared memory.
Actually, this leads to what I (currently) see as the biggest problem
with this idea - the undefined behavior of the file descriptor
returned by comedi_driver_fileno. libusb, for example, returns a LIST
of file descriptors that should be polled by the application. There's
probably a lot of code (including my own) that select() on the COMEDI
file descriptor, so the only backwards-compatible way that I see of
handling this would be fire off a thread that sits in a tight little
select() loop on the USB file descriptor list, and writes to a pipe
whenever it's ready to signal the user application, which was returned
the other end of the pipe when it called comedi_driver_fileno() via
comedi_fileno(). Yuck. I don't see any really good way of handling
this, either - libusb wants to select on a fd set, while libcomedi is
built around a single fd, so how do we integrate the two when we're
doing acquisition from a USB device?
I'm more and more convinced, however, that the answer to this last
question is not "put the driver in the kernel".
Here's hoping for your comments...
-bwb
Brent Baccala
cos...@freesoft.org
> I've been thinking more about this (handling USB devices), and here's
> what I'm leaning towards.
>
> Don't do anything in the kernel. Modify comedilib as follows...
I didn't do it that way. I ended up using a preload library instead
to intercept the open and ioctl calls without touching comedilib.
I'm not doing USB right now, instead I'm running "remote COMEDI"
across IP. I'm using TCP for the COMEDI data stream and UDP/RPC to
transport the ioctl calls. A server program interfaces to an existing
/dev/comedi0 device (in my case comedi_test).
It's working pretty well. All the ioctl stuff seems to work fine.
The problem that I've got right now is how to handle error returns on
read(). This happens a lot on comedi; all it seems to take is a
buffer overflow. The way my normal COMEDI code is written, when I
detect an EPIPE on a read, that means more ioctl stuff needs to be
done (i.e, start a new command running) before attempting more reads.
The problem is that I need to handle this in a select() loop in the
server program. I guess what I'm thinking now is to report a read
error using an out-of-band TCP message, then ignore the comedi device
until an ioctl is done. After each ioctl, check the comedi device to
see if it is still returning errors. If so, keep ignoring it. Only
when select/read reports a non-error do we start transferring data
again to the client. Only a single error is reported for this entire
process. If the client tried to read during this time, it would
either block or get EAGAIN.
Does this make sense?
Also, are zero-byte read() returns significant on comedi devices?
Do they need to be reported too, or can they just be ignored?
Thanks. Let us know when it's on the site so the dead link can be updated.
--
-=( Ian Abbott @ MEV Ltd. E-mail: <abb...@mev.co.uk> )=-
-=( Tel: +44 (0)161 477 1898 FAX: +44 (0)161 718 3587 )=-
Thanks, Michele. I've updated the link on the applications page, but
have added an additional link to the original location in case it ever
returns!