Include files for libUSB Linux and Windows.

For issues with communication ports, protocols, etc.
grindstone
Posts: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: Include files for libUSB Linux and Windows.

Post by grindstone »

I have massive problems here with libusb overwriting the memory FB stores its variables in. Couldn't figure out the reason for that behaviour yet. The original C programs seem to run correct.

Very strange. If anyone has a suggestion how to fix it, please let me know.
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Include files for libUSB Linux and Windows.

Post by caseih »

Care to post an example of the C version that works, and the FB version that sees corruption? Memory corruption almost certainly points to some structure that's not translated quite correctly, so pointers get messed up. I think I'd prefer a complete crash to memory corruption. Would be a lot easier to track down.
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: Include files for libUSB Linux and Windows.

Post by Dinosaur »

Hi All

Just as an update.
Turns out that the I/O board is a "Dumb Device" that gets loaded during Linux bootup with the help of a .rules file and a routine called fxload.
Until this "bootstrap" has successfully completed, the device couldn't be mounted, and I could not talk to it.

Once I got all that resolved I wrote some code to check the speed of communicating with it.
Doing 1000 Writes & Reads translated to 190 micro seconds per call (Writing or reading 32 bits of I/O)

Doing the same thing using an FTDI driver to another board takes 12 milli seconds per call.

So, I am officially impressed.
If anyone is interested in the code I will post it.

Regards
Edit: Point of Interest.
The device Vendor:Product is 1605:8018
But until it has been mounted it showed up with lsusb as 1606:0018
Apparently all devices not mounted drop the msb.
grindstone
Posts: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: Include files for libUSB Linux and Windows.

Post by grindstone »

@Dinosaur: You are using Linux, right? And you got no memory corruption? Are you running any For...Next loops in your program? And if so, do they terminate correctly?

This would be a precious hint if I knew that the trouble I ran in here affects only Windows.
grindstone
Posts: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: Include files for libUSB Linux and Windows.

Post by grindstone »

Allright, I found the bug and fixed it. The updated libusb.bi can be downloaded here.

Unlike other dlls libusb differentiates the calling convention depending on the current OS, so for Windows it has to be set it to StdCall instead of Cdecl.

And (@srvaldez) here the FB translation of listdevs.c:

Code: Select all

/'
 * libusb example program to list devices on the bus
 * Copyright © 2007 Daniel Drake <dsd@gentoo.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 '/
 
 'Ported to freeBasic by grindstone 2018

#Include "libusb.bi"

Sub print_devs(devs As libusb_device Ptr Ptr)
	Dim As libusb_device Ptr dev
	Dim As Long i = 0, j = 0
	Dim As UByte path(8) 

	dev = devs[0]
	While dev <> NULL
		Dim As libusb_device_descriptor desc
		Dim As Long r = libusb_get_device_descriptor(dev, @desc)
		
		If r < 0 Then
			Print "failed to get device descriptor"
			Return
		EndIf
		      
		Print Hex(desc.idVendor,4);":";Hex(desc.idProduct,4);" (bus";libusb_get_bus_number(dev); _
		      ", device ";libusb_get_device_address(dev);")";
		
		r = libusb_get_port_numbers(dev, @path(0), UBound(path))
		
		If r > 0 Then
			Print " path: ";path(0);
			For j = 1 To r - 1
				Print ".";path(j);
			Next
		EndIf
		Print
		i += 1
		dev = devs[i]
	Wend
End Sub

Dim As libusb_device Ptr Ptr devs
Dim As Long r
Dim As ssize_t cnt

r = libusb_init(NULL)
If r < 0 Then 
	End r
EndIf

cnt = libusb_get_device_list(NULL, @devs)
If cnt < 0 Then
	End cnt
EndIf

print_devs(devs)
libusb_free_device_list(devs, 1)

libusb_exit(NULL)

? "OK"
Sleep


Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: Include files for libUSB Linux and Windows.

Post by Dinosaur »

Hi All

grindstone , yes I run Linux MInt 18.3 with libusb-1.0.21.
There were a couple of items that I had to modify on the .bi file

I remmed out

Code: Select all

	'#If Not Defined(__CYGWIN__)
	'	#Include "win\winsock.bi"
	'#EndIf
and also changed

Code: Select all

tv As timeval Ptr
to

Code: Select all

tv As Long Ptr
in a number of places as it threw errors of not being declared.

Will try the new .bi file without changes and see if any errors.

Regards
Glad you found the problem.
grindstone
Posts: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: Include files for libUSB Linux and Windows.

Post by grindstone »

Hello Dinosaur!

For I'm only on Windows, I will need some help to make the header file available for Linux. Every hint is welcome.

Umfortunately, the libusb site is down at the moment, so that I can't take a closer look to the meaning of timeval, but AFAIK it's a structure consisting of 2 ULong members (seconds and microseconds).

Try to replace

Code: Select all

#If Defined(__FB_WIN32__) Or Defined(__FB_CYGWIN__)	
		#Include "windows.bi"
	#EndIf
with

Code: Select all

#If Defined(__FB_WIN32__)
		#Include "windows.bi"
	#ElseIf Defined(__FB_LINUX__)
		#Include "crt/sys/socket.bi"
	#EndIf
and delete (or comment)

Code: Select all

#If Not Defined(__FB_CYGWIN__)
		#Include "win\winsock.bi"
	#EndIf
This should solve the timeval issue.
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: Include files for libUSB Linux and Windows.

Post by Dinosaur »

Hi All

grindstone, thanks for the update, however the timeval Ptr must be defined in other Windows only files.
So for the moment the only solution is to convert it to "tv as Long Ptr"

I have completed all my testing for the AccesIO board and preparing the project for posting on their site
under the FreeBasic sample sessions.

There is only one area where I am confused and that is to do with Dim Sharing the Types in the libusb.bi file.
So before I post the code I need someone to tell me WHY I need to add the lines as per below.

Code: Select all

Type libusb_device_handle As libusb_device_handle
has a line added

Code: Select all

Dim Shared libusb_device_handle as libusb_device_handle Ptr
So I am modifying your .bi file by adding these statements.
Is the conversion from .h to .bi missing something here ?

So far I have only added two, but I am sure that if I were to call a number of others the same would apply.

Regards
grindstone
Posts: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: Include files for libUSB Linux and Windows.

Post by grindstone »

Code: Select all

Type libusb_device_handle As libusb_device_handle
is the conversion of

Code: Select all

struct libusb_device_handle;
Seems not to be necessary for FB, but it doesn't hurt, so I left it in.

Code: Select all

Dim Shared libusb_device_handle as libusb_device_handle Ptr
Have a look at the latest update, there's no (longer) such line in the code.

Converting timeval Ptr to Long Ptr may cause trouble. Better replace

Code: Select all

#If Defined(__FB_LINUX__ ) Or Defined(__FB_CYGWIN__)
		#Include Once "crt\time.bi"
	#EndIf
with

Code: Select all

#If Defined(__FB_LINUX__ ) Or Defined(__FB_CYGWIN__)
		Type timeval
			tv_sec As Long
			tv_usec As Long
		End Type
	#EndIf
As far as I know this Type is the only reason to include the time.bi. Please tell me if it works on Linux. If so, I will update my code.
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: Include files for libUSB Linux and Windows.

Post by Dinosaur »

Hi All

Grindstone , I have to find a way to open 2 usb devices that have the same Vendor & Product code.
From all my browsing it seems that there is no easy way to do this.

I have to use
libusb_get_device_list and loop through all the devices to identify the one I wish to open.

The first obstacle is the definition of libusb_get_device_list in the .bi file
Declare Function libusb_get_device_list(ctx As libusb_context Ptr, list As libusb_device Ptr Ptr Ptr) As ssize_t

Have you used this function and can you shed some light on this ?

Regards
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: Include files for libUSB Linux and Windows.

Post by Dinosaur »

Hi All

After browsing the previous posts in this thread I found the answer to my previous question.

I then proceeded to use the code from above and tried to use it to open a device with Libusb_open
I cant use libusb_open_device_with_vid_pid(0, &H0a07, &H0046) because I have two devices with the same Vendor but different serial numbers.

Code: Select all

#include once "libusb-1.0.bi"

Sub print_devs(devs As libusb_device Ptr Ptr)
   Dim dev_handle As libusb_device_handle Ptr
   Dim As libusb_device Ptr dev
   Dim As Long i = 0, j = 0
   Dim As UByte path(8)

   dev = devs[0]
   While dev <> NULL
      Dim As libusb_device_descriptor desc
      Dim As Long r = libusb_get_device_descriptor(dev, @desc)
      
      If r < 0 Then
         Print "failed to get device descriptor"
         Return
      EndIf
           
      Print Hex(desc.idVendor,4);":";Hex(desc.idProduct,4);" (bus";libusb_get_bus_number(dev); _
            ", device ";libusb_get_device_address(dev);")";
            If Hex(desc.idVendor,4) = "0A07" And Hex(desc.idProduct,4) = "0046" then
                Print "Found one ;";dev			
                r = libusb_open(dev,dev_handle)
                Print "Error Detail ;";r
                Print *(libusb_error_name(r))
                Print "dev_handle ;"; dev_handle
            EndIf
      
      r = libusb_get_port_numbers(dev, @path(0), UBound(path))
      
      If r > 0 Then
         Print " path: ";path(0);
         For j = 1 To r - 1
            Print ".";path(j);
         Next
      EndIf
      Print
      i += 1
      dev = devs[i]
   Wend
End Sub

Dim As libusb_device Ptr Ptr devs
Dim As Long r
Dim As ssize_t cnt

r = libusb_init(NULL)
If r < 0 Then
   End r
EndIf

cnt = libusb_get_device_list(NULL, @devs)
If cnt < 0 Then
   End cnt
EndIf

print_devs(devs)
libusb_free_device_list(devs, 1)

libusb_exit(NULL)

? "OK"
Sleep


It returns an error code of -3.
I simply can't find what I am doing wrong with the ret = libusb_open(dev,dev_handle)
The dev_handle returned is 0(zero)

I thought perhaps the permissions were the reason and added a line to the .rules
SUBSYSTEMS=="usb",ATTRS{idVendor}=="0a07",ATTRS{idProduct}=="0046",SYMLINK+="Ontrak1",MODE="0666"
Can someone please point me in the right direction.

Regards
Post Reply