libftdi Archives

Subject: Re: libftdi and ftdi_sio

From: Ryan Tennill <rtennill@xxxxxxxxxxxxxxxx>
To: libftdi@xxxxxxxxxxxxxxxxxxxxxxx
Date: Sun, 23 Aug 2015 09:18:23 -0500
On 8/22/2015 8:16 PM, Shashank Chintalagiri wrote:
I'm 'using' libftdi. Assume for he purpose of this discussion that I only care about posix systems, and if necessary than can be restricted to modern desktop linuxes. While the actual code I'm running is python code using pylibftdi [1], an approach from the C and libftdi perspective is fine.


I notice the following (expected) behaviour :

* Using libftdi causes ftdi_sio to be unloaded (detached). Any ftdi_sio provided /dev/ttyUSBx disappear. * All /dev/ttyUSBx disappear, regardless of how many FTDI devices are connected and how many of those have libftdi drivers attached. * 'Creating' a pylibftdi Device (which effectively translates to an ftdi_usb_open_* call) makes libftdi active.
 * 'Closing' a pylibftdi Device does not seem to reload ftdi_sio.


What I'm having some trouble with is the following :

* Is it possible to use libftdi on some (or one) FTDI devices, but continue using ftdi_sio on others? If so, how.

* After I'm done using libftdi, I'd like to have the /dev/ttyUSBx back. I know I can do this by manually running insmod, but I'm hoping that it can be achieved without manual intervention. Since libftdi is able to (effectively) run rmmod, I would expect it to be able to reverse it's actions either at an algorithmically determined point or at the user's explicit request.

* The creation of the pylibftdi Device instance includes a call to libusb's libusb_set_auto_detach_kernel_driver(), which should, according to the documentation, reload the kernel when the device is released. This does not work. Is there something I'm missing here? Is there a libftdi specific way / function which can reload ftdi_sio - either on device close or by an explicit function call by my code, assuming that I take responsibility for any unintended side effects of doing so.

* If you have, say, 3 FTDI devices, of which 2 use libftdi. If only one of those two are closed, then reloading ftdi_sio at that point is likely not a good idea. If there is an attach_kernel_driver() or similar function within libftdi, what rationale does it use? Similarly, if libusb's libusb_set_auto_detach_kernel_driver() was to work or a call to libusb_attach_kernel_driver() was made, how would libusb handle this and how would libftdi react to this?


I found a small patch [2] on the mailing list which seemingly addressed this issue. The OP there didn't seem to want to see it through, and that line of code didn't make it into libftdi. Would that piece of code have worked? Is / was there something inherently wrong with that approach? More immediately, would it be possible to use that approach from outside libftdi? Specifically, the proposed patch involved calling libusb_attach_kernel_driver() after libusb_release_interface() and before ftdi_usb_close_internal() in ftdi_usb_close(). However, if I'd like to be able to do this with vanilla libftdi, the libusb_attach_kernel_driver() call would have to come either before or after ftdi_usb_close(). Is there any chance for this to work?



For reference, here is the relevant portion of the code that I'd like to be able to use :

driver = pylibftdi.Driver()
devices = driver.list_devices()
serials = [x[2] for x in devices]

# If I exit at this point, /dev/ttyUSBx is still available.

with pylibftdi.Device(device_id="some serial number") as device:

# This 'with' ... is a contextmanager in python. At the end of this code # block, device.close() is called automatically. Within pylibftdi, this
    # is implemented as a call to libftdi's ftdi_usb_close and then
    # ftdi_usb_deinit

    chipid = c_uint()
    device.ftdi_fn.ftdi_read_chipid(byref(chipid))

# /dev/ttyUSBx is gone, but at this point I want it back.


And here is the route I think may work (though I haven't had a chance to try it yet for lack of a device on hand) :

def close(self):
    """
    close our connection, free resources
    """
    if self._opened:
ctx_p = cast(byref(self.ctx), POINTER(ftdi_context_partial)).contents
        self.fdll.ftdi_usb_close(byref(self.ctx))
        if self.auto_detach:
            dev = ctx_p.libusb_device_handle
            if dev:
self.driver._libusb.libusb_attach_kernel_driver(dev, 1)
        self.fdll.ftdi_deinit(byref(self.ctx))
        del self.ctx
    self._opened = False


[1] http://pylibftdi.readthedocs.org/en/latest/pylibftdi.html
[2] http://developer.intra2net.com/mailarchive/html/libftdi/2014/msg00123.html


Thanks,
Chintalagiri Shashank

I have done this in C using the libusb call that referenced and then closing the device using libusb_close(). Using this method, I am able to collect serial data from 59 devices with libftdi and use minicom on one or more other devices at the same time. When I'm done with the ttyUSBx I can then recapture it with libftdi.

I don't use libusb_set_auto_detach_kernel_driver() myself, not sure if that happens in the lib someplace though.

Ryan

--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx
Current Thread