[fpc-pascal] USB Human Interface Devices

James Richters james at productionautomation.net
Wed Aug 28 11:03:01 CEST 2019


Thanks for adding the hotplug functions and the sample program.  I will give that a try.   

I have come up with another solution before I saw you added the hotplug functions:

My thinking is that the interrupt read is going to know about the missing device before anything because it will be constantly reading as fast is it can and my main thread will be cycling much slower,  so detecting the failure of the interrupt read would be the fastest way to know the device was not connected anymore.
I noticed that lib_interupt_transfer produces a return code if anything prevents the transfer from being completed.  But this information is only used for optional debug reports, and not returned from the libusbhid_interrupt_write and libusbhid_interrupt_read functions,  they only return the number of bytes transferred.  Since the number of bytes read or sent is irrelevant due to an error, and the error codes seem to always be negative, then there is no ambiguity if we return the error if it is negative or bytes transferred if it is not negative. That way calls to libusbhid_interrupt_write and libusbhid_interrupt_read can quckly get the return code and / or the number of bytes transferred, just by checking if the result is negative or not. Since the interrupt read is happening in a tight loop and running way faster than anything else, it's likely that this will be the fastest way to stop the read thread when the device is unplugged, then I can go back to looking for it in the main program again.  The first read that produces an error will stop the thread.

I have tested this on my test branch. I get one negative return code during normal use... and that is if I get a timeout, I get a -7, perhaps because I asked for 8 bytes maybe? This is also useful information to have in my loop as if I get a -7, I don't need to bother checking the data at all since it was not read, it was just a timeout.  https://github.com/Zaaphod/libusbxhid/tree/Test


James
-----Original Message-----
From: fpc-pascal <fpc-pascal-bounces at lists.freepascal.org> On Behalf Of Stefan V. Pantazi
Sent: Tuesday, August 27, 2019 10:35 PM
To: fpc-pascal at lists.freepascal.org
Subject: Re: [fpc-pascal] USB Human Interface Devices


> 
> libusbhid_interrupt_read. failed! return code: -1
> 0libusb: error [winusbx_submit_bulk_transfer] ReadPipe/WritePipe failed: [2] The system cannot find the file specified.
> 
> But I don't really know how I can detect this and exit the process and signal my other program that the device is no longer present.   My read command:
>        hidReportData[reportIdx].dataLen:=libusbhid_interrupt_read(device_context,$81{endpoint},{out}hidReportData[reportIdx].hid_data,64{report length, varies by device}, {timeout=}50);
> only reports the number of bytes read, and when the device is removed, the result of the libusbhid_interrupt_read seems to be 64.   I’m wondering what the proper way to gracefully detect the device has been disconnected is so I can just exit out of the mode the uses the device and return to normal processing without generating any errors.

You can try to handle the error return code by checking that a device that was present before has actually disappeared for the libusb device list.

It also appears that in newer versions of libusb, there are provisions for registering and unregistering a hotplug callback.

http://libusb.sourceforge.net/api-1.0/hotplug.html

It it easy to add the calls to libusbx but they need to be tested that they actually work as expected.

> 
> Any ideas?
> 
> James
> 
> 
> -----Original Message-----
> From: fpc-pascal <fpc-pascal-bounces at lists.freepascal.org> On Behalf 
> Of Stefan V. Pantazi
> Sent: Friday, August 23, 2019 10:54 AM
> To: fpc-pascal at lists.freepascal.org
> Subject: Re: [fpc-pascal] USB Human Interface Devices
> 
> Thanks for pushing on this. I think any pending timeout/transfer must be explicitly canceled before closing the USB device, so that the thread can end gracefully.
> 
> The only way I see is to use something like
> 
> libusb_handle_events_timeout_completed	
> 
> http://libusb.sourceforge.net/api-1.0/group__poll.html#ga43e52b912a760
> b41a0cf8a4a472fbd5b
> 
> 
> before closing the USB device context.
> 
> That function is not currently part of the libusbx and has a time_t parameter that appears C-specific but for some reason is not included in ctypes unit. But I am sure Pascal equivalents can be defined. I will do some tests to include the libusb_handle_events_timeout_completed in libusbx and libusbhid and let you know.
> 
> 
> 
> On 8/23/19 7:07 AM, James Richters wrote:
>> Stefan ,
>> Do you get the following errors when you exit your program?   Is there some way I should shut down the read thread so I don't get this error?  I've been using a timeout of 0
>>
>>
>> libusb: error [do_close] Device handle closed while transfer was 
>> still being processed, but the device is still connected as far as we 
>> know
>> libusb: error [do_close] A cancellation hasn't even been scheduled on 
>> the transfer for which the device is closing
>> libusb: warning [libusb_exit] some libusb_devices were leaked 
>> Assertion failed!
>>
>> Program: i:\programming\gcode\libusbxhid\whb04b-4_test.exe
>> File: os/poll_windows.c, Line 145
>>
>> Expression: fd != NULL
>> Heap dump by heaptrc unit of
>> i:\programming\gcode\libusbxhid\whb04b-4_test.exe
>> 50 memory blocks allocated : 1782/1968
>> 50 memory blocks freed     : 1782/1968
>> 0 unfreed memory blocks : 0
>> True heap size : 131072 (160 used in System startup) True free heap :
>> 130912 _______________________________________________
>> fpc-pascal maillist  -  fpc-pascal at lists.freepascal.org 
>> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
>>
> 
> --
> _______________________________________________________
> _______________________________________________
> fpc-pascal maillist  -  fpc-pascal at lists.freepascal.org 
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
> _______________________________________________
> fpc-pascal maillist  -  fpc-pascal at lists.freepascal.org 
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
> 

--
_______________________________________________________
_______________________________________________
fpc-pascal maillist  -  fpc-pascal at lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


More information about the fpc-pascal mailing list