Voor USB communicatie tussen een PIC en de PC, gebruik ik de DLL libusb0.dll.
De PC progjes maak in in Delphi.
Nu wil ik ook een Visual Basic versie maken.
Heeft iemand ervaring met Visual Basic samen met libusb0.dll ?
Mod's: Even voor de duidelijkheid, dit gaat inderdaad over software. Maar dit is specifiek voor een PIC bedoeld !
Martijn v
KIS!!: Keep It Simple
'k heb het driverproject gedownload, maar sjit dat is een hoop.., ik heb wel een bestand gevonden.
Zipfile/Docs/Function.sgml, daar staat een lang verhaal over welke functie's erzijn.
dit is de eerste die je moet aanroepen:
usb_init
er staat idd niet bij hoe de code dan zou moeten zijn.
maar ik denk, dat je best dit kunt proberen:
Public Declare sub mms_USB_Init Lib "LIBusb0.dll" Alias "usb_init"
of
Public Declare Function mms_USB_Init Lib "LIBusb0.dll" Alias "usb_init" () As Long
das dan de declaratie van de API, en dan moet je natuurlijk nog het commando zelf geven.
mms_Usb_init
Martijn v
KIS!!: Keep It Simple
'k wil het best mailen, maar je hebt het toch al?
en trouwens, kwenie zo goed waarvoor het is, maar als je BV zon USB setje van VOTI aan het spelen bent, dat zijn chips van FTDI, die hebben ook een DLL, met veel goede voorbeelden.
http://www.ftdichip.com/Projects/CodeExamples/VB.htm
k wil het best mailen, maar je hebt het toch al?
Als je dit bedoeld, dan weet ik niet wat ik hermee moet: Zipfile/Docs/Function.sgml
Public Declare sub mms_USB_Init Lib "LIBusb0.dll" Alias "usb_init"
of
Public Declare Function mms_USB_Init Lib "LIBusb0.dll" Alias "usb_init" () As Long
Kan je/iemand hier iets meer over vertellen, ik krijg alleen maar fout meldingen ?
[Bericht gewijzigd door MMSoft op ]
free_electron
Silicon Member
Professioneel ElectronenTemmer - siliconvalleygarage.com - De voltooid verleden tijd van 'halfgeleider' is 'zand' ... US 8,032,693 / US 7,714,746 / US 7,355,303 / US 7,098,557 / US 6,762,632 / EP 1804159 - Real programmers write Hex into ROM
is dat de libusb van sourceforge ? ( mensen wat een draak is me dat geworden zeg. vroeger was het simpel klikkerdeklik om iets te downloaden daar. nu ben je 1) verblind door alle toeters en bellen , alle reclame die rond je oren zoeft , en moet je ene half uur lezen om te vinden waar je nu juist moet klikken om iets te krijgen... )
kzal sebiet ne keer kijken om de calls te porteren naar VB.
ik was net ook aant zien om iets te doen met libusb ... en kheb het zelf toch ook nodig.
der is een leuek tool die je kan downloaden (gratis) bij microsoft om in DLL's te neuzen om te kijken welke functies ze exporteren..
dat ding noemt Dependency Walker.
het analyseert eender welke DLL of EXe en toont de lijst van ge-exporteerde calls en ook welke andere libraries die file nodig heeft enzovoort.
hee leuk om te zien welke files een programma allemaal nodig heeft....
[Bericht gewijzigd door free_electron op ]
Martijn v
KIS!!: Keep It Simple
Op 28 december 2006 17:11:19 schreef free_electron:
is dat de libusb van sourceforge ? vroeger was het simpel klikkerdeklik om iets te downloaden daar. nu ben je 1) verblind door alle toeters en bellen , alle reclame die rond je oren zoeft , en moet je ene half uur lezen om te vinden waar je nu juist moet klikken om iets te krijgen... )
Dependency Walker.
ja dus, libusb.dll versie x.1.12
'k heb ook een versie x.1.17 gevonden, maar om een *.exe te draaien met dat soort rotzooi, nee dankje
Dependency Walker zit standaard bij de enterprise edition van VB6 
- wat voor USB gebruik TS, en heeft die fabriekant geen code voorbeelden?
- het werkt al wel in delphi ?, laat die code zien dan 
@ henry: 'k heb geen vieuwer voor *.sgml, maar als je *.html van maakt wordt het dus dit.
free_electron
Silicon Member
Professioneel ElectronenTemmer - siliconvalleygarage.com - De voltooid verleden tijd van 'halfgeleider' is 'zand' ... US 8,032,693 / US 7,714,746 / US 7,355,303 / US 7,098,557 / US 6,762,632 / EP 1804159 - Real programmers write Hex into ROM
dit heb ik al
' twee woorden uitleg
' shortint in C is een Integer in VB
' Char is een byte in VB
'Device and/or Interface Class codes
Const USB_CLASS_PER_INTERFACE = 0
Const USB_CLASS_AUDIO = 1
Const USB_CLASS_COMM = 2
Const USB_CLASS_HID = 3
Const USB_CLASS_PRINTER = 7
Const USB_CLASS_MASS_STORAGE = 8
Const USB_CLASS_HUB = 9
Const USB_CLASS_DATA = 10
Const USB_CLASS_VENDOR_SPEC = &HFF
'Descriptor types
Const USB_DT_DEVICE = &H1
Const USB_DT_CONFIG = &H2
Const USB_DT_STRING = &H3
Const USB_DT_INTERFACE = &H4
Const USB_DT_ENDPOINT = &H5
Const USB_DT_HID = &H21
Const USB_DT_REPORT = &H22
Const USB_DT_PHYSICAL = &H23
Const USB_DT_HUB = &H29
'Descriptor sizes per descriptor type
Const USB_DT_DEVICE_SIZE = 18
Const USB_DT_CONFIG_SIZE = 9
Const USB_DT_INTERFACE_SIZE = 9
Const USB_DT_ENDPOINT_SIZE = 7
Const USB_DT_ENDPOINT_AUDIO_SIZE = 9
Const USB_DT_HUB_NONVAR_SIZE = 7
'Enpoint Descriptors...
Const USB_MAXENDPOINTS = 32
Const USB_ENDPOINT_ADDRESS_MASK = &HF
Const USB_ENDPOINT_DIR_MASK = &H80
Const USB_ENDPOINT_TYPE_MASK = &H3
Const USB_ENDPOINT_TYPE_CONTROL = 0
Const USB_ENDPOINT_TYPE_ISOCHRONOUS = 1
Const USB_ENDPOINT_TYPE_BULK = 2
Const USB_ENDPOINT_TYPE_INTERRUPT = 3
'Diverse
Const USB_MAXINTERFACES = 32
Const USB_MAXALTSETTING = 128
Const USB_MAXCONFIG = 8
'Standard requests
Const USB_REQ_GET_STATUS = &H0
Const USB_REQ_CLEAR_FEATURE = &H1
Const USB_REQ_SET_FEATURE = &H3
Const USB_REQ_SET_ADDRESS = &H5
Const USB_REQ_GET_DESCRIPTOR = &H6
Const USB_REQ_SET_DESCRIPTOR = &H7
Const USB_REQ_GET_CONFIGURATION = &H8
Const USB_REQ_SET_CONFIGURATION = &H9
Const USB_REQ_GET_INTERFACE = &HA
Const USB_REQ_SET_INTERFACE = &HB
Const USB_REQ_SYNCH_FRAME = &HC
Const USB_TYPE_STANDARD = 0
Const USB_TYPE_CLASS = &H20 ' (0x01 << 5) waarschijnlijk shift left ...
Const USB_TYPE_VENDOR = &H40 ' (0x02 << 5) dus ik heb de boel al geshift
Const USB_TYPE_RESERVED = &H60 '(0x03 << 5) hier
Const USB_RECIP_DEVICE = &H0
Const USB_RECIP_INTERFACE = &H1
Const USB_RECIP_ENDPOINT = &H2
Const USB_RECIP_OTHER = &H3
Const LIBUSB_PATH_MAX = 512
Const USB_ENDPOINT_IN = &H80
Const USB_ENDPOINT_OUT = &H0
Const USB_ERROR_BEGIN = 500000
' Data structures
Type USB_Descriptor_Header
bLength As Byte
bDescriptorType As Byte
End Type
Type USB_String_descriptor
bLength As Byte
bDescriptorType As Byte
wdata As Integer
End Type
Type USB_Hid_Descriptor
bLength As Byte
bDescriptorType As Byte
bcdHID As Integer
bCountrycode As Byte
bNumdescriptors As Byte
End Type
Type USB_Endpoint_Descriptor
bLength As Byte
bDescriptorType As Byte
bEndpointaddress As Byte
bmAttributes As Byte
wMaxPacketSize As Integer
bInterval As Byte
bRefresh As Byte
bSynchAddress As Byte
' hier zit een klotepointer naar een andere struct : *extra as Byte
extralen As Integer
End Type
Type USB_Device
filename(LIBUSB_PATH_MAX) As Byte
Bus As Byte ' USB_Bus
Descriptor As Byte ' dit is een geforwarde struct : USB_Device_Descriptor
Config As Byte ' dit is een geforwarde struct : USB_Config_Descriptor
End Type
Type USB_Bus
DirName(LIBUSB_PATH_MAX) As Byte
Devices As Byte ' geforwarde struct: USB_Device
Location As Single
End Type
Type USB_Device_Descriptor
bLength As Byte
bDescriptorType As Byte
bcdUSB As Long ' short
bDeviceClass As Byte
bDeviceSubClass As Byte
bDeviceProtocol As Byte
bMaxPacketSize0 As Byte
idVendor As Integer
idProduct As Integer
bcdDevice As Integer
iManufacturer As Byte
iProduct As Byte
iSerialNumber As Byte
bNumConfigurations As Byte
End Type
Type USB_Config_Descriptor
bLength As Byte
bDescriptorType As Byte
wTotalLength As Integer
bNumInterfaces As Byte
bConfigurationValue As Byte
iConfiguration As Byte
bmAttributes As Byte
MaxPower As Byte
Interface As Byte ' geforwarde struct USB_Interface
Extra As Byte
extralen As Long
End Type
Type USB_Interface
AltSetting As Byte 'geforwarde struct USB_Interface_Descriptor
Num_AltSetting As Integer
End Type
Type USB_Interface_Descriptor
bLength As Byte
bDescriptorType As Byte
bInterfaceNumber As Byte
bAlternateSetting As Byte
bNumEndpoints As Byte
bInterfaceClass As Byte
bInterfaceSubClass As Byte
bInterfaceProtocol As Byte
iInterface As Byte
EndPoint As Byte 'geforwarde struct USB_EndPoint_Descriptor
Extra As Byte
extralen As Integer
End Type
Type USB_dev_handle
zever As Byte ' efkese zever gedclareerd omdat ik hier de definieite niet van terugvind in de .h file
End Type
' procedures
Declare Sub USB_Init Lib "libusb0.dll" ()
Declare Function USB_Find_Busses Lib "libusb0.dll" () As Integer
Declare Function USB_Find_Devices Lib "libusb0.dll" () As Integer
Declare Function USB_Get_Busses Lib "libusb0.dll" () As USB_Bus
Declare Function USB_Open Lib "libusb0.dll" _
(ByRef Device As USB_Device) As USB_dev_handle
Declare Function USB_Close Lib "libusb0.dll" _
(ByRef Device As USB_dev_handle) As Integer
Declare Function USB_Set_Configuration Lib "libusb0.dll" _
(ByRef Device As USB_dev_handle, _
ByVal Configuration As Integer) As Integer
Declare Function USB_Set_AltInterface Lib "libusb0.dll" _
(ByRef Device As USB_dev_handle, _
ByVal Alternate As Integer) As Integer
Declare Function USB_ResetEp Lib "libusb0.dll" _
(ByRef Device As USB_dev_handle, _
ByVal EndPoint As Long) As Integer
Declare Function USB_Clear_Halt Lib "libusb0.dll" _
(ByRef Device As USB_dev_handle, _
ByVal EndPoint As Long) As Integer
Declare Function USB_Reset Lib "libusb0.dll" _
(ByRef Device As USB_dev_handle) As Integer
Declare Function USB_Claim_Interface Lib "libusb0.dll" _
(ByRef Device As USB_dev_handle, _
ByVal Interface As Integer) As Integer
Declare Function USB_Release_Interface Lib "libusb0.dll" _
(ByRef Device As USB_dev_handle, _
ByVal Interface As Integer) As Integer
Declare Function USB_Control_Msg Lib "libusb0.dll" _
(ByRef Device As USB_dev_handle, _
ByVal RequestType As Integer, _
ByVal Request As Integer, _
ByVal Value As Integer, _
ByVal Index As Integer, _
ByRef Bytes As String, _
ByVal Size As Integer, _
ByVal TimeOut As Integer) As Integer
Declare Function USB_Get_String Lib "libusb0.dll" _
(ByRef Device As USB_dev_handle, _
ByVal Index As Integer, _
ByVal LangId As Integer, _
ByRef Buf As String, _
ByVal BufLen As Long) As Integer
Declare Function USB_Get_String_Simple Lib "libusb0.dll" _
(ByRef Device As USB_dev_handle, _
ByVal Index As Integer, _
ByRef Buf As String, _
ByVal BufLen As Long) As Integer
Declare Function USB_Get_Descriptor Lib "libusb0.dll" _
(ByRef Device As USB_dev_handle, _
ByVal sType As String, _
ByVal Index As String, _
ByRef Buf, _
ByVal Size As Integer) As Integer
Declare Function USB_Get_Descriptor_By_EndPoint Lib "libusb0.dll" _
(ByRef Device As USB_dev_handle, _
ByVal EndPoint As Integer, _
ByVal sType As String, _
ByVal Index As String, _
ByRef Buf, _
ByVal Size As Integer) As Integer
Declare Function USB_Bulk_Write Lib "libusb0.dll" _
(ByRef Device As USB_dev_handle, _
ByVal EndPoint As Integer, _
ByRef Bytes As String, _
ByVal Size As Integer, _
ByVal TimeOut As Integer) As Integer
Declare Function USB_Bulk_Read Lib "libusb0.dll" _
(ByRef Device As USB_dev_handle, _
ByVal EndPoint As Integer, _
ByRef Bytes As Byte, _
ByVal Size As Integer, _
ByVal TimeOut As Integer) As Integer
Declare Function USB_Interrupt_Write Lib "libusb0.dll" _
(ByRef Device As USB_dev_handle, _
ByVal EndPoint As Integer, _
ByRef Bytes As Byte, _
ByVal Size As Integer, _
ByVal TimeOut As Integer) As Integer
Declare Function USB_Interrupt_Read Lib "libusb0.dll" _
(ByRef Device As USB_dev_handle, _
ByVal EndPoint As Integer, _
ByRef Bytes As Byte, _
ByVal Size As Integer, _
ByVal TimeOut As Integer) As Integer
free_electron
Silicon Member
Professioneel ElectronenTemmer - siliconvalleygarage.com - De voltooid verleden tijd van 'halfgeleider' is 'zand' ... US 8,032,693 / US 7,714,746 / US 7,355,303 / US 7,098,557 / US 6,762,632 / EP 1804159 - Real programmers write Hex into ROM
das inderdaad waar ik bang voor was ....
er wordt weer gebruik gemaakt van bizarre dingen (lees : vuiligheid) die gewoonweg niet te porteren vallen.
dit ding retourneert een soort 'linked list' ...
en dit is ook al helemaal onnozel :
struct usb_device {
struct usb_device *next, *prev;
char filename[LIBUSB_PATH_MAX];
struct usb_bus *bus;
struct usb_device_descriptor descriptor;
struct usb_config_descriptor *config;
void *dev; /* Darwin support */
unsigned char devnum;
unsigned char num_children;
struct usb_device **children;
};
struct usb_bus {
struct usb_bus *next, *prev;
char dirname[LIBUSB_PATH_MAX];
struct usb_device *devices;
unsigned long location;
struct usb_device *root_dev;
};
dit begrijp ik niet :
struct usb_device {
struct usb_device *next, *prev;
hoe kan een structuur nu een referentie naar zijn eigen bevatten ?
en hoe kan de ene struct een referentie naar een andere bevatten die dan weer naar de eerste wijst ...
das om onnozel van te worden...
dat placeholder mechanisme snap ik maar dat kan nooit 1 char zijn. elke pointer is een 32 bit getal..... dus dat kan niks anders dan een long zijn.
tis een miserieding tot en met. ik heb ook al de source van de dll proberen te bestuderen. daar staat nergens geen lijn commentaar in wat het doet , hoe het werkt ... tis triestig. ik dacht dat de bedoleing van copen source was dat iederen kon zien hoe het werkte. maar zoals het nu is kan je telkens het warmm water ( ik zou eerder durven spreken van 'water op kamertemperatuur' terug uitvinden.
ik begin er stillekesaan genoeg van te krijgen.
nog iets waar ik niet aan uit kan:
struct usb_device {
struct usb_device *next, *prev;
char filename[LIBUSB_PATH_MAX];
struct usb_bus *bus;
struct usb_device_descriptor descriptor;
struct usb_config_descriptor *config;
waarom is de voorlaatste lijn geen pointer ?
[Bericht gewijzigd door free_electron op ]
Ik heb een tijdje terug de vertaling gemaakt van C naar delphi, dit is ook de code die mmsoft een aantal posts naar boven heeft staan.
In delphi is het, net als in VB, ook niet mogelijk om binnen een structure (record in delphi) een pointer naar een structure van hetzelfde type aan te maken. Vandaar de enigzins "dirty" oplossing, gewoon een untyped pointer. Voor de DLL maakt dat helemaal niets uit.
Er zijn vast wel dergelijke truucjes te bedenken voor VB dacht ik zo?
Om even een simpel voorbeeldje te geven in delphi:
Tusb_dev_handle = pointer;
Pusb_dev_handle = ^Tusb_dev_handle;
Tusb_device = Record
next : pointer;
prev : pointer;
filename : array [0..511] of char;
bus : pointer;
descriptor : Tusb_device_descriptor;
config : pointer;
dev : pointer;// void *dev; /* Darwin support */
devnum : char;
num_children : char;
children : pointer;
end;
Pusb_device = ^Tusb_device;
Tusb_bus = Record
next : pointer;
prev : pointer;
dirname : array [0..511] of char;
devices : pointer;
location : longint;
root_dev : pointer;
end;
Pusb_bus = ^Tusb_bus;
function usb_find_busses : integer; stdcall; external 'libusb0.dll';
function usb_find_devices : integer; stdcall; external 'libusb0.dll';
function usb_get_busses : Pusb_bus; stdcall; external 'libusb0.dll';
function usb_open (dev : Pusb_device): Pusb_dev_handle; stdcall; external 'libusb0.dll';
function TUSB_Device.OpenDevice(vendorID, productID : word): Pusb_dev_handle;
var
bus : Pusb_bus;
dev : Pusb_device;
found : boolean;
udev : Pusb_dev_handle;
begin
found := false;
usb_find_busses;
usb_find_devices;
bus := usb_get_busses;
while bus <> NIL do
begin
dev := bus.devices;
while dev <> NIL do
begin
if (dev.descriptor.idVendor = vendorID) and (dev.descriptor.idProduct = productID) then
begin
found := true;
udev := usb_open(dev);
end;
dev := dev.next;
end;
bus := bus.next;
end;
if found then
result := udev
else
result := NIL;
end;
free_electron
Silicon Member
Professioneel ElectronenTemmer - siliconvalleygarage.com - De voltooid verleden tijd van 'halfgeleider' is 'zand' ... US 8,032,693 / US 7,714,746 / US 7,355,303 / US 7,098,557 / US 6,762,632 / EP 1804159 - Real programmers write Hex into ROM
Op 4 januari 2007 00:16:52 schreef KillerB the Supreme:
Ik heb een tijdje terug de vertaling gemaakt van C naar delphi, dit is ook de code die mmsoft een aantal posts naar boven heeft staan.Er zijn vast wel dergelijke truucjes te bedenken voor VB dacht ik zo?
de vraag is dan : als je daar gewoon een pointer doorgeeft : waar staat de data dan ? ( met andere woorden : wordt er genoeg memory gealloceeerd om de boel te stockeren ? ) das immers de reden dat je een pointer naar een structuur doorgeeft : je zorgt daar dat er genoeg memory is om de boel te stockeren. gans die boel is een linked list die groeit en krimpt in functie van het aantal devices wat ingeplugd is.
het blijft een vreemde manier om dingen door te geven.
veel simpeler was geweest om al die miserie af te handelen IN de dll.
er is ook geen 'pointer' datatype in vb. je moet door middel van copymame en varptr de boel achterhalen en moven naar waar je wilt ( copymem is ene windows api call )
dit betekent dat er een klets glue code moet gemaakt worden in vb om die data te retrieven.
het is veel simpeler (denk ik) om in ene tussen dll een nieuwe API te definieren die de boel platklopt
api :
usb_init
usb_finddevices ( retourneert een integer die aangeeft hoeveel er gevonden zijn , bijvoorbeel 3 geeft aan dat er 4 devices zijn ( 0 tot en met 3 ))
usb_info(device nummer,datablock) device nummer zit dan tussen 0 en de waarde die je bekomen hebt uit usb_finddevices
usb_info (device nummer,datablock)
stockeert in 'datablock' een fixed size string met daarin comma delimited data (of desnoods fixed size velden) : gans die usb descriptor zit daar in.
als het device ondertussen unplugged is komt er een lege string terug.
usb_open(device ) opnieuw een nummer uit de lijst. . retourneert 0 of 1 ( 1=success ) ( 0 = failed )
en dan heb je gewoon send en receive. die je het device nummer, het aantal bytes en een pointer naar het datablok
usb_send(device_nummer,endpoint,aantalbytes,datablock)
usb_close(device)
tis properder en veel simpeler om te gebruiken , en het pint je niet vast op vuile 'c' constructies die niet porteerbaar zijn naar andere talen.
ik ben bang voor memory leak problems als die geneste lists niet proper kunnen gepasseerd worden.
nog een vraag :
wat betekent die ^ in de volgende code :
Tusb_dev_handle = pointer;
Pusb_dev_handle = ^Tusb_dev_handle;
[Bericht gewijzigd door free_electron op ]
Op 4 januari 2007 02:45:27 schreef free_electron:
de vraag is dan : als je daar gewoon een pointer doorgeeft : waar staat de data dan ? ( met andere woorden : wordt er genoeg memory gealloceeerd om de boel te stockeren ? ) das immers de reden dat je een pointer naar een structuur doorgeeft : je zorgt daar dat er genoeg memory is om de boel te stockeren. gans die boel is een linked list die groeit en krimpt in functie van het aantal devices wat ingeplugd is.
het blijft een vreemde manier om dingen door te geven.
veel simpeler was geweest om al die miserie af te handelen IN de dll.
Het wordt ook juist allemaal afgehandeld in de DLL. Dat is het hele idee erachter. De pointers verwijzen naar geheugen dat gealloceerd is in de DLL. Je hoeft zelf dus helemaal niets te alloceren, alleen de pointers naar de betreffende structures.
Op 4 januari 2007 02:45:27 schreef free_electron:
nog een vraag :
wat betekent die ^ in de volgende code :Tusb_dev_handle = pointer; Pusb_dev_handle = ^Tusb_dev_handle;
^ wil zeggen dat Pusb_dev_handle een pointer is naar een structure van het type Tusb_dev_handle. De eerste typedeclaratie van Tusb_dev_handle is wat verwarrend, het is eigenlijk een handle, ipv een pointer (maar dat komt op het zelfde neer, 4 bytes). Anders gezegd, Pusb_dev_handle is dus een pointer naar een devicehandle.
Delphi is best makkelijk in pointers, het symbool ^ "wijst" ergens heen, dit is sneller te begrijpen als de * van C. In C wordt de * ook gebruikt voor dereferencing, erg verwarrend. Delphi heeft daarvoor het @ symbool. Als je @ al vertaald naar "at" (en niet ape-staartje
) dan snap je direct dat er gedereferenced wordt.
free_electron
Silicon Member
Professioneel ElectronenTemmer - siliconvalleygarage.com - De voltooid verleden tijd van 'halfgeleider' is 'zand' ... US 8,032,693 / US 7,714,746 / US 7,355,303 / US 7,098,557 / US 6,762,632 / EP 1804159 - Real programmers write Hex into ROM
kzal vandaag nog ne keer ene poging wagen om het in VB te doen.
die dephi code is tenminste een stuk leesbaarder dan usb.h ...
kheb ondertussen bij Intel wat code gehaald in zuivere VB geschreven om ook USB te doen ZONDER externe DLL.
blijkt dat je dat kan via API calls naar windows zelf .....
free_electron
Silicon Member
Professioneel ElectronenTemmer - siliconvalleygarage.com - De voltooid verleden tijd van 'halfgeleider' is 'zand' ... US 8,032,693 / US 7,714,746 / US 7,355,303 / US 7,098,557 / US 6,762,632 / EP 1804159 - Real programmers write Hex into ROM
bon we zijn een stuk verder.
ik heb een paar support routines geschreven om in het memory te kunnen rondkoteren. zo kan ik 'kijken' wat er echt terugkeert en dat te mappen op mijn structuren.
Option Explicit
' twee woorden uitleg :
' shortint in C is een Integer in VB
' Char is een byte in VB
' pointers komen ALTIJD terug als long !
' functienamen in DLL's zijn CASE sensitive !!
' de enige manier om dit te forceren is het gebruik van ALIAS in de
' functiedeclaratie. dit zorgt er voor dat niet accidenteel een naam
' van case verandert door een user typo...
' VB strings zijn ALTIJD unicode !!! let daar geweldig mee op.
Const LIBUSB_PATH_MAX = 512
'Device and/or Interface Class codes
Const USB_CLASS_PER_INTERFACE = 0
Const USB_CLASS_AUDIO = 1
Const USB_CLASS_COMM = 2
Const USB_CLASS_HID = 3
Const USB_CLASS_PRINTER = 7
Const USB_CLASS_MASS_STORAGE = 8
Const USB_CLASS_HUB = 9
Const USB_CLASS_DATA = 10
Const USB_CLASS_VENDOR_SPEC = &HFF
'Descriptor types
Const USB_DT_DEVICE = &H1
Const USB_DT_CONFIG = &H2
Const USB_DT_STRING = &H3
Const USB_DT_INTERFACE = &H4
Const USB_DT_ENDPOINT = &H5
Const USB_DT_HID = &H21
Const USB_DT_REPORT = &H22
Const USB_DT_PHYSICAL = &H23
Const USB_DT_HUB = &H29
'Descriptor sizes per descriptor type
Const USB_DT_DEVICE_SIZE = 18
Const USB_DT_CONFIG_SIZE = 9
Const USB_DT_INTERFACE_SIZE = 9
Const USB_DT_ENDPOINT_SIZE = 7
Const USB_DT_ENDPOINT_AUDIO_SIZE = 9
Const USB_DT_HUB_NONVAR_SIZE = 7
'Enpoint Descriptors...
Const USB_MAXENDPOINTS = 32
Const USB_ENDPOINT_ADDRESS_MASK = &HF
Const USB_ENDPOINT_DIR_MASK = &H80
Const USB_ENDPOINT_TYPE_MASK = &H3
Const USB_ENDPOINT_TYPE_CONTROL = 0
Const USB_ENDPOINT_TYPE_ISOCHRONOUS = 1
Const USB_ENDPOINT_TYPE_BULK = 2
Const USB_ENDPOINT_TYPE_INTERRUPT = 3
'Diverse
Const USB_MAXINTERFACES = 32
Const USB_MAXALTSETTING = 128
Const USB_MAXCONFIG = 8
'Standard requests
Const USB_REQ_GET_STATUS = &H0
Const USB_REQ_CLEAR_FEATURE = &H1
Const USB_REQ_SET_FEATURE = &H3
Const USB_REQ_SET_ADDRESS = &H5
Const USB_REQ_GET_DESCRIPTOR = &H6
Const USB_REQ_SET_DESCRIPTOR = &H7
Const USB_REQ_GET_CONFIGURATION = &H8
Const USB_REQ_SET_CONFIGURATION = &H9
Const USB_REQ_GET_INTERFACE = &HA
Const USB_REQ_SET_INTERFACE = &HB
Const USB_REQ_SYNCH_FRAME = &HC
Const USB_TYPE_STANDARD = 0
Const USB_TYPE_CLASS = &H20 ' (0x01 << 5) waarschijnlijk shift left ...
Const USB_TYPE_VENDOR = &H40 ' (0x02 << 5) dus ik heb de boel al geshift
Const USB_TYPE_RESERVED = &H60 '(0x03 << 5) hier
Const USB_RECIP_DEVICE = &H0
Const USB_RECIP_INTERFACE = &H1
Const USB_RECIP_ENDPOINT = &H2
Const USB_RECIP_OTHER = &H3
Const USB_ENDPOINT_IN = &H80
Const USB_ENDPOINT_OUT = &H0
Const USB_ERROR_BEGIN = 500000
' Data structures
Type USB_Descriptor_Header
bLength As Byte
bDescriptorType As Byte
End Type
Type USB_String_descriptor
bLength As Byte
bDescriptorType As Byte
wdata As Integer ' dit wordt gebruikt als plaeholder voor de array . is eigenlijk ene pointer
End Type
Type USB_Hid_Descriptor
bLength As Byte
bDescriptorType As Byte
bcdHID As Integer
bCountrycode As Byte
bNumdescriptors As Byte
End Type
Type USB_Endpoint_Descriptor
bLength As Byte
bDescriptorType As Byte
bEndpointaddress As Byte
bmAttributes As Byte
wMaxPacketSize As Integer
bInterval As Byte
bRefresh As Byte
bSynchAddress As Byte
extra As Byte ' Dit is ene placeholder. is eigenlijk een pointer naar de data ararray
extralen As Integer
End Type
Type USB_Interface_Descriptor
bLength As Byte
bDescriptorType As Byte
bInterfaceNumber As Byte
bAlternateSetting As Byte
bNumEndpoints As Byte
bInterfaceClass As Byte
bInterfaceSubClass As Byte
bInterfaceProtocol As Byte
iInterface As Byte
EndPoint As Long 'dit is ene pointer naar een type : USB_EndPoint_Descriptor
extra As Byte
extralen As Integer
End Type
Type USB_Interface
AltSetting As Long 'dit is een pointer naar een type : USB_Interface_Descriptor
Num_AltSetting As Integer
End Type
Type USB_Config_Descriptor
bLength As Byte
bDescriptorType As Byte
wTotalLength As Integer
bNumInterfaces As Byte
bConfigurationValue As Byte
iConfiguration As Byte
bmAttributes As Byte
MaxPower As Byte
Interface As Long ' pointer naar een type : USB_Interface
extra As Byte ' pointer naar extra descriptors
extralen As Long
End Type
Type USB_Device_Descriptor
bLength As Byte
bDescriptorType As Byte
bcdUSB As Integer
bDeviceClass As Byte
bDeviceSubClass As Byte
bDeviceProtocol As Byte
bMaxPacketSize0 As Byte
idVendor As Integer
idProduct As Integer
bcdDevice As Integer
iManufacturer As Byte
iProduct As Byte
iSerialNumber As Byte
bNumConfigurations As Byte
End Type
Type USB_Ctrl_Setup
bRequestType As Byte
bRequest As Byte
wValue As Integer
wIndex As Integer
wLength As Integer
End Type
Type USB_Device
next_dev As Long ' pointer naar een type : USB_device
prev_dev As Long ' pointer naar een type : USB_device
filename(LIBUSB_PATH_MAX) As Byte
Bus As Long ' pointer naar een type : USB_Bus
Descriptor As USB_Device_Descriptor ' dit is een geforwarde struct : USB_Device_Descriptor
Config As USB_Config_Descriptor ' dit is een geforwarde struct : USB_Config_Descriptor
dummy As Long ' dummy pointer voor darwin support
devnum As Byte
num_children As Byte
children As Long ' dit is een pointer naar een array van types : usb_device . het aantal zit in 'num_children
End Type
Type USB_Bus
next_dev As Long ' pointers naar een zelfde type : usb_bus
prev_dev As Long ' pointers naar een zelfde type : usb_bus
DirName(LIBUSB_PATH_MAX) As Byte
Devices As Long ' pointer naar een type : USB_Device
Location As Single
root_device As Long ' pointer naar het root device type : usb_device
End Type
Type usb_dll
major As Long
minor As Long
micro As Long
nano As Long
End Type
Type usb_driver
major As Long
minor As Long
micro As Long
nano As Long
End Type
Type usb_version
dll As usb_dll
driver As usb_driver
End Type
Type USB_dev_handle
pointer As Long ' dit is een pointer naar interne data in libusb.dll
End Type
' procedures
' opgelet ! de functinamen MOETEN lowercase zijn !!! ik heb aliassen gebruikt om de boel te forceren
Declare Sub USB_Init Lib "libusb0.dll" Alias "usb_init" ()
Declare Function USB_Find_Busses Lib "libusb0.dll" Alias "usb_find_busses" () As Integer
Declare Function USB_Find_Devices Lib "libusb0.dll" Alias "usb_find_devices" () As Integer
Declare Function USB_get_busses Lib "libusb0.dll" Alias "usb_get_busses" () As Long ' dit geeft een pointer naar USB_Bus
Declare Function USB_open Lib "libusb0.dll" Alias "usb_open" _
(ByRef Device As USB_Device) As Long ' pointer naar een USB_dev_handle
Declare Function USB_close Lib "libusb0.dll" Alias "usb_close" _
(ByRef Device As USB_dev_handle) As Integer
Declare Function USB_set_configuration Lib "libusb0.dll" Alias "usb_set_configuration" _
(ByRef Device As USB_dev_handle, _
ByVal Configuration As Integer) As Integer
Declare Function USB_set_altinterface Lib "libusb0.dll" Alias "usb_set_altinterface" _
(ByRef Device As USB_dev_handle, _
ByVal Alternate As Integer) As Integer
Declare Function USB_resetep Lib "libusb0.dll" Alias "usb_resetep" _
(ByRef Device As USB_dev_handle, _
ByVal EndPoint As Long) As Integer
Declare Function USB_clear_Halt Lib "libusb0.dll" Alias "usb_clear_Halt" _
(ByRef Device As USB_dev_handle, _
ByVal EndPoint As Long) As Integer
Declare Function USB_reset Lib "libusb0.dll" Alias "usb_reset" _
(ByRef Device As USB_dev_handle) As Integer
Declare Function USB_Claim_Interface Lib "libusb0.dll" Alias "usb_claim_interface" _
(ByRef Device As USB_dev_handle, _
ByVal Interface As Integer) As Integer
Declare Function USB_release_Interface Lib "libusb0.dll" Alias "usb_release_Interface" _
(ByRef Device As USB_dev_handle, _
ByVal Interface As Integer) As Integer
Declare Function USB_control_Msg Lib "libusb0.dll" Alias "usb_control_msg" _
(ByRef Device As USB_dev_handle, _
ByVal RequestType As Integer, _
ByVal Request As Integer, _
ByVal Value As Integer, _
ByVal Index As Integer, _
ByRef Bytes As String, _
ByVal Size As Integer, _
ByVal TimeOut As Integer) As Integer
Declare Function USB_get_string Lib "libusb0.dll" Alias "usb_get_string" _
(ByRef Device As USB_dev_handle, _
ByVal Index As Integer, _
ByVal LangId As Integer, _
ByRef Buf As String, _
ByVal BufLen As Long) As Integer
Declare Function USB_get_string_simple Lib "libusb0.dll" Alias "usb_get_string_simple" _
(ByRef Device As USB_dev_handle, _
ByVal Index As Integer, _
ByRef Buf As String, _
ByVal BufLen As Long) As Integer
Declare Function USB_get_descriptor Lib "libusb0.dll" Alias "usb_get_descriptor" _
(ByRef Device As USB_dev_handle, _
ByVal sType As String, _
ByVal Index As String, _
ByRef Buf, _
ByVal Size As Integer) As Integer
Declare Function USB_get_descriptor_by_endPoint Lib "libusb0.dll" Alias "usb_get_descriptor_by_endPoint" _
(ByRef Device As USB_dev_handle, _
ByVal EndPoint As Integer, _
ByVal sType As String, _
ByVal Index As String, _
ByRef Buf, _
ByVal Size As Integer) As Integer
Declare Function USB_Bulk_Write Lib "libusb0.dll" Alias "usb_bulk_write" _
(ByRef Device As USB_dev_handle, _
ByVal EndPoint As Integer, _
ByRef Bytes As String, _
ByVal Size As Integer, _
ByVal TimeOut As Integer) As Integer
Declare Function USB_Bulk_Read Lib "libusb0.dll" Alias "usb_bulk_read" _
(ByRef Device As USB_dev_handle, _
ByVal EndPoint As Integer, _
ByRef Bytes As Byte, _
ByVal Size As Integer, _
ByVal TimeOut As Integer) As Integer
Declare Function USB_Interrupt_Write Lib "libusb0.dll" Alias "usb_interrupt_write" _
(ByRef Device As USB_dev_handle, _
ByVal EndPoint As Integer, _
ByRef Bytes As Byte, _
ByVal Size As Integer, _
ByVal TimeOut As Integer) As Integer
Declare Function USB_Interrupt_Read Lib "libusb0.dll" Alias "usb_interrupt_read" _
(ByRef Device As USB_dev_handle, _
ByVal EndPoint As Integer, _
ByRef Bytes As Byte, _
ByVal Size As Integer, _
ByVal TimeOut As Integer) As Integer
'-----------------------------------------------------------------------------------------------
' Hieronder staan routines die mij toestaan in het geheugen rond te 'koteren'
' Dump is een routine die memory dumpt . kwestie van te zien wat er werkelijk terugkeert ...
' copymemeory is een kernel call die mij toestaat om vanaf een gegeven address ( de pointer )
' een klets geheugen te kopieren naar ergenst anders
' bijvoorbeeld ik krijg ene pointer terug naar een of andere structuur die 10 byte lang is
' ik maak iets gelijkaardig in visual basic aan.
' laat ons zeggen x is de geretrouneerde pointer
' type my_type
' a1 as long ' 4 byte
' a2 as long ' 4 byte
' a3 as integer ' 2 byte
' end type
' dim y as my_type
' copymemory(y,x,10) ' kopieer 10 bytes vanaf pointer 'x' naar 'y'
' ' aangezien variableen altijd via pointer toorgegeven worden in vb gebeurt dit.
' de structuur wordt dus mooi overgekopieerd
' en ik kan gewoon a2 opvragen .... dat geeft mij dan byte 4 tot en met 7 uit de 10 byte array
Private Declare Function lstrlenA Lib "kernel32" (ByVal lpString As Long) As Long
Private Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(pTo As Any, _
uFrom As Any, _
ByVal lSize As Long)
' dump is een routine die memory dumpt . kwestie van te zien wat er werkelijk terugkeert ...
Public Function Dump(ByVal Buffer As Long, ByVal Block_Size As Long) As String
Dim Internal_Buffer() As Byte ' make internal storage space
Dim Internal_Block_Size
Dim Result As String ' this holds the 'dump' in user readable form
Dim i As Long, j As Long
ReDim Internal_Buffer(0 To Block_Size - 1) As Byte
Call CopyMemory(Internal_Buffer(0), ByVal Buffer, Block_Size)
Result = String(81, "=") & vbCrLf & "Buffer Address = 0x" & Hex$(Buffer) & _
" : Block_Size = 0x" & Hex$(Block_Size) & " (" & Block_Size & ")d"
If Block_Size Mod 16 = 0 Then ' boundary needs to be correct
Internal_Block_Size = Block_Size
Else
Internal_Block_Size = ((Block_Size \ 16) + 1) * 16
End If
For i = 0 To (Internal_Block_Size - 1)
If (i Mod 16) = 0 Then Result = Result & vbCrLf & Right$("00000000" & Hex$(Buffer + i), 8) _
& " " & Right$("0000" & Hex$(i), 4) & " "
If i < Block_Size Then
Result = Result & Right$("0" & Hex(Internal_Buffer(i)), 2)
Else
Result = Result & " "
End If
If (i Mod 16) = 15 Then
Result = Result & " "
For j = (i - 15) To i
If j < Block_Size Then
If Internal_Buffer(j) >= 32 And Internal_Buffer(j) <= 126 Then
Result = Result & Chr$(Internal_Buffer(j))
Else
Result = Result & "."
End If
End If
Next j
ElseIf (i Mod 8) = 7 Then ' Insert '-'
Result = Result & "-"
Else ' Insert space
Result = Result & " "
End If
Next i
Dump = Result & vbCrLf & String(81, "=") & vbCrLf
End Function
Public Function PointerToStringA(ByVal lpStringA As Long) As String
Dim Buffer() As Byte
Dim nLen As Long
If lpStringA Then
nLen = lstrlenA(ByVal lpStringA)
If nLen Then
ReDim Buffer(0 To (nLen - 1)) As Byte
CopyMemory Buffer(0), ByVal lpStringA, nLen
PointerToStringA = StrConv(Buffer, vbUnicode)
End If
End If
End Function
Public Function PointerToStringW(ByVal lpStringW As Long) As String
Dim Buffer() As Byte
Dim nLen As Long
If lpStringW Then
nLen = lstrlenW(lpStringW) * 2
If nLen Then
ReDim Buffer(0 To (nLen - 1)) As Byte
CopyMemory Buffer(0), ByVal lpStringW, nLen
PointerToStringW = Buffer
End If
End If
End Function
Public Function PointerToDWord(ByVal lpDWord As Long) As Long
Dim nRet As Long
If lpDWord Then
CopyMemory nRet, ByVal lpDWord, 4
PointerToDWord = nRet
End If
End Function
maak een formpje aan met 4 command buttons
(command1 tot en met command4) en een label ( dat label noem je usrmsg
Private Sub Command1_Click()
USB_Init
End Sub
Private Sub Command2_Click()
Dim x As Long
x = USB_Find_Busses()
msg "USB_find_busses returned : " & x
End Sub
Private Sub Command3_Click()
Dim x As Long
x = USB_Find_Devices()
msg "USB_find_devices returned : " & x
End Sub
Private Sub Command4_Click()
Dim x As Long
Dim my_usb_bus As USB_Bus ' maak een variabele aan van het type usb_bus
x = USB_get_busses() ' x bevat nu een pointer naar een array van type USB_Bus
msg "pointer returned " & x ' toon het addresss
Debug.Print Dump(x, &H2FF) ' kijk eens wat er in zit ....
End Sub
Sub msg(txt$)
usrmsg.Caption = txt$
End Sub
Private Sub Command5_Click()
usb_get_devices
End Sub
Private Sub Form_Load()
usrmsg.Width = Me.Width
End Sub
dat staat je to om al de bus te proben en het aantal devices te retrieven.
nu de rest nog ...
der moet wat 'glue' code gemaakt worden om door middel van copymemory de boel te kunnen 'afwandelen'.
das voor de komende uren... eerst eten 
Martijn v
KIS!!: Keep It Simple
Op 4 januari 2007 17:10:24 schreef free_electron:
kheb ondertussen bij Intel wat code gehaald in zuivere VB geschreven om ook USB te doen ZONDER externe DLL.
blijkt dat je dat kan via API calls naar windows zelf .....
'k wordt ook nieuwsgieurig?
linkie?
free_electron
Silicon Member
Professioneel ElectronenTemmer - siliconvalleygarage.com - De voltooid verleden tijd van 'halfgeleider' is 'zand' ... US 8,032,693 / US 7,714,746 / US 7,355,303 / US 7,098,557 / US 6,762,632 / EP 1804159 - Real programmers write Hex into ROM
een update
' Define some local variables
Dim my_bus As USB_Bus
Dim my_usb_device As USB_Device
Dim x As Long
Dim bus_name, device_name
Dim manstring As String * 20
Dim ret As Integer
Private Sub Command1_Click()
Dim device As Long
Dim ptr_device As USB_Device
Dim handle As USB_dev_handle
USB_Init
msg "Called USB_init"
x = USB_Find_Busses()
msg "Calling USB_find_busses returned : " & x
x = USB_Find_Devices()
msg "Calling USB_find_Devices returned : " & x
my_bus = my_USB_get_busses
msg "Bus name = " & my_bus.DirName & vbCrLf
msg vbCrLf & "The address of the first devices is " & Hex$(my_bus.Devices)
device = my_bus.Devices
While device <> 0
Call CopyMemory(my_usb_device, ByVal device, &H230)
' 230 hex (560 bytes) is the exact size of the information held in a
' USB_device datablock. so that is how many need to be retrieved from the
' memory pointed at by 'device'
msg "This device is called " & my_usb_device.filename & vbCrLf
msg "-- Length : " & Hex$(my_usb_device.Descriptor.bLength)
msg "-- Descriptortype : " & Hex$(my_usb_device.Descriptor.bDescriptorType)
msg "-- bcdUSB : " & Hex$(my_usb_device.Descriptor.bcdUSB)
msg "-- Device class : " & Hex$(my_usb_device.Descriptor.bDeviceClass)
msg "-- Device Subclass : " & Hex$(my_usb_device.Descriptor.bDeviceSubClass)
msg "-- Device Protocol : " & Hex$(my_usb_device.Descriptor.bDeviceClass)
msg "-- Max Packetsize : " & Hex$(my_usb_device.Descriptor.bDeviceClass)
msg "-- Vendor ID : " & Hex$(my_usb_device.Descriptor.idVendor)
msg "-- Product ID : " & Hex$(my_usb_device.Descriptor.idProduct)
msg "-- bcdDevice : " & Hex$(my_usb_device.Descriptor.bcdDevice)
msg "-- iManufacturer : " & Hex$(my_usb_device.Descriptor.iManufacturer)
msg "-- iProduct : " & Hex$(my_usb_device.Descriptor.iProduct)
msg "-- iSerialnumber : " & Hex$(my_usb_device.Descriptor.iSerialNumber)
msg "-- bNumConfigurations : " & Hex$(my_usb_device.Descriptor.bNumConfigurations)
' handle = USB_open(my_usb_device) ' <<< hier zit ik vast
' msg "----- Device Opened : Handle " & Hex$(handle.pointer)
' ret = USB_get_string_simple(handle, my_usb_device.Descriptor.iManufacturer, manstring, 20)
' msg "----- Manufacturer name : " & manstring
' ret = USB_close(handle)
msg vbCrLf & "The next device sits at address " & Hex$(my_usb_device.next_dev)
device = my_usb_device.next_dev
Wend
Debug.Print "stop"
End Sub
Sub msg(txt$)
Text1.Text = Text1.Text & txt$ & vbCrLf
Debug.Print txt$
End Sub
ik zit vast bij het openen. ik krijg steeds ' bad dll calling convention. ik krijg nog kop nog staart aan wat die usb_open routine daar precies verwacht ...
my_usb_device is van het type usb_device. net wat die usb_open verwacht ... en toch lukt het niet ...
free_electron
Silicon Member
Professioneel ElectronenTemmer - siliconvalleygarage.com - De voltooid verleden tijd van 'halfgeleider' is 'zand' ... US 8,032,693 / US 7,714,746 / US 7,355,303 / US 7,098,557 / US 6,762,632 / EP 1804159 - Real programmers write Hex into ROM
ok . probleem is al voor 90 % opgelost nu.
het blijkt dat de calls die in libusb0 zitten geen
STDcalls zijn zoals windows die wil hebben , maar C-calls. ( cdecl calls ) vandaar ook mijn 'bad dll calling cinvention probleem' en das niet oplosbaar.
windows staat je toe om cdecl te gebruiken maar dat werkt enkel en alleen met programmas die in c geschreven zijn. ( onderandere die ganse miserie met pointers en linked lists )
er is een oplossing. Stefan ( die kerel die libusb gemaakt heeft ) heeft een library die WEL stdcalls gebruikt. dit is een wrapper rond libusb0 die de translatie doet. ( je kan met visual studio C dergelijke wrappers semi-automatisch aanmaken ).
ik heb ondertussen de dll en de code.
enig probleem is dat er 2 functies zijn die NIET porteerbaar zijn naar STDcalls en dat zijn net die functies die je toelaten om de device paramters te lezen.
goed nieuws : der wordt aan gewerkt nu 
van zodra ik ene klets werkende code heb post ik die.
He das raar, ik heb daar ook problemen mee gehad, maar ik moest juist stdcall toevoegen aan de dll declaratie onder delphi. cdecl, safecall, pascal en register werkte allemaal niet.
Misschien een opmerking Free, ik stuur een pointer naar de structure mee bij het open commando, dus niet de structure zelf (hoewel dat in principe ook een pointer is maargoed). Ik weet niet hoe je dat nu precies in VB doet.
free_electron
Silicon Member
Professioneel ElectronenTemmer - siliconvalleygarage.com - De voltooid verleden tijd van 'halfgeleider' is 'zand' ... US 8,032,693 / US 7,714,746 / US 7,355,303 / US 7,098,557 / US 6,762,632 / EP 1804159 - Real programmers write Hex into ROM
je kan vb die pointer mooi aanmaken maar die staat ergens op de stack van het vb programma. intern in libusb kan je daar niet aan ( dat blok is locked omdat het niet tot het libusb0 process behoort. daarvoor dient die stdcall : dat is een grensoverschrijdend mechanisme.
je hebt een interne pointer nodig in libusb. tijdens de passing gebeurt er translatie omdat vb ALTIJD van een STDcall uit gaat. ( je kan niet anders . er is gene manier om cdecl te passeren omdat dat 'not the microsoft way' is. microsoft heeft daar ene appnote over : alle shared libraries , met andere woorden libraries die je wilt delen ( niet alle dll's zijn shared. je kan perfect dll maken voor je eigen gebruik. dan trek je je daar niks van aan. ) ) moeten die stdcall exporteren.
bijkomend voordeel : stdcalls zijn thread safe. cdecl calls niet !
ter verduidleijking. ik kan die call doen , maar de parameter passing lukt niet. VB doet daar ene translatie omdat hij van stdcall uit gaat.
enfin we wijken af.
ik pruts vandaag wel verder.
ik ga 3 files maken
1) een .bas die de interfacing doet op de 'normale manier en ook een wrapper heeft zoals ik die zou willen daarrond. ( met ene interne structuur die alle informatie bevat over de usb bus zodat je niet telkens moet modderen. )
usbstart : dit start usb en probed de bus. alle gevonden informatie wordt in een type gegooid
type t_usb
vid,vip,maxpower,manufacturere(string), product(string),packetsize,numberofendpoints
etcetera etcetera etcetera
end type
dim usb as t_usb
een usb_device class die bulk_read , bulkwrite en alle transacties bevat die je wilt doen
dan wordt het heeel eenvoudig om usb te doen:
dim my_device as usb_device
dim blokje_data(128) as integer
for x = lbound(usb) to ubound(usb)
if usb(x).vid = my_vid then
if isb(x).vip = my_vip then
found = x
end if
end if
next x
my_device.target = found
my_device.endpoint = 2
my_device.bulkwrite (blokje_data,128)
als je my_device niet meer nodig hebt :
set my_device = vbnull
de class handelt dan al de zever van openen , claimen en sluiten mooi af.
en het wordt heel eenvoudig om met 37 of meer device tegelijkertijd bezig te zijn.
ik geef een voorbeeld.
stle je hebt 4 van die usb naar serial convertors aan je pc hangen ( ftdi chip ) al die dingen hebben allemaal dezelfde vid en vip alleen heb je zelf de product string aangepast. je hebt ene die aan je scoop hangt , ene aan je multimeter etc. de string in dat spul is ook 'scoop' of 'multimeter'
de boel wordt dan heeel simpel
dim my_dmm as usb_device
dim my_scope as usb_device
for x = lbound(usb) to ubound(usb)
if usb(x).vid = my_vid then
if usb(x).vip = my_vip then
if usb(x).productstring = "scoop" then scope =x
if usb(x).productstring = "multimeter" then dmm=x
end if
end if
next x
my_dmm=dmm
my_scope=scope
hop en we zijn weg. de poorten zijn geclaimed ,staan open en we kunnen transport doen.
in princiepe moet het mogelijk zijn om tegen die ftdi te praten. ik meen mij te herinneren dat tx en rx een apart endpoint zijn ( dus niet het control endpoint )
dus in het geval van een ftdi245 is dat gewoon bytes prammen van en anaar het juiste endpoint. van het control endpoint trek je je niks aan. ( das al geinitialiseerd door hun driver )
ditto voor pic en andere processoren met een usb aan boor.d
van het control endpoint trek je je niks aa. gewoon bulk transport naar de interne fifo's.
als mijn opzet slaagt wordt usb dan zelfs simpeler om te gebruiken dan een seriele poort.
-edit- ik heb hier en daar opgekuist.. nu ik op een andere computer zit me ene kleiner scherm (minder horizontale pixels.. ipv 1680 maar 1280 ... ) zag ik dat de boel wel heel erg breed was
)
Op 6 januari 2007 17:43:18 schreef free_electron:
[...] daarvoor dient die stdcall : dat is een grensoverschrijdend mechanisme.bijkomend voordeel : stdcalls zijn thread safe. cdecl calls niet !
Hier heeft stdcall allemaal niets mee te maken hoor. Het is net als cdecl een calling convention, oftewel een standaard om functies aan te roepen. Beiden pushen paramerers op de stack om aan een functie mee te geven. Bij stdcall ruimt de functie zelf deze parameters weer op, bij C is dit de taak van de code die de functie aanroept.
Dat is het enige verschil, het heeft niets met grenzen of thread safe te maken. Het is puur de manier van aanroepen.
De C calling convention heeft als voordeel dat je een variabel aantal parameters kunt meegeven. Bij stdcall kan dit niet (makkelijk). Er is zelfs een windows API die de C calling convetion gebruikt, wsprintf namelijk. De rest is stdcall, gewoon omdat dat als standaard is gekozen (het heet niet voor niets standard calling convention).
Het probleem is gewoon dat VB alleen stdcall ondersteund, maar daar is technisch gezien geen reden voor.
Een wrapper DLL zou prima moeten werken, er is geen verschil in hoe parameters behandeld worden tussen C of stdcall convention, alleen hoe ze opgeruimd worden. Als de wrapper de functies aanroept en de stack opruimt erna heb je de functies als stdcall.
Op 6 januari 2007 20:34:41 schreef free_electron:
wat ik mij laten vertellen heb door een van onze locale c-guru's is dat windows op de hoogte is van stdcalls en die 'opkuis' niet laat onderbreken ( der gebeurt daar een en ander onder de motorkap. )bij cdecl is de user zelf verantwoordelijk . als er een switch optreed net voor de opkuis en de aanroepende doet iets verkeerd is het hommeles ... bij de terugkeer.
Ik heb nog nooit van zoiets gehoord en het lijkt me ook heel sterk. Windows kan niet zien wanneer je een 'stdcall' doet omdat het niet een speciaal iets is wat afgevangen kan worden. Het is gewoon een call instructie naar een bepaald adres, of het nou stdcall of C is. Het kan net zo goed een functie call zijn binnen het programma. Windows kan ook aan een DLL niet zien of een functie stdcall of C is. De 'opkuis' is 1 instructie (add esp, x ; x aan de stack pointer toevoegen) en 1 instructie kan niet onderbroken worden. Een context switch zou geen probleem moeten zijn, ik weet niet precies hoe windows dit regelt maar de stack blijft altijd intact, ook al zou windows tussendoor dingen op de stack zetten. De stack pointer wijst altijd na de data die erop staat. Zelfs al zou het opruimen van de stack onderbroken worden, context switches zouden altijd transparant moeten zijn voor applicaties.
Waar loopt ie dan precies vast? Ik kan kijken wat er in delphi gebeurt met een bepaalde dll call, misschien kunnen we achterhalen wat er misgaat.
free_electron
Silicon Member
Professioneel ElectronenTemmer - siliconvalleygarage.com - De voltooid verleden tijd van 'halfgeleider' is 'zand' ... US 8,032,693 / US 7,714,746 / US 7,355,303 / US 7,098,557 / US 6,762,632 / EP 1804159 - Real programmers write Hex into ROM
ik gebruik libusb dll inderdaad.
rechtstreeks onder windows kan je alleen hid calls doen of calls naar device die ene driver hebben.... dus die 'intel' code is eigenlijk alleen bruikbaar als je ene driver hebt ... en das net wat ik wil omzielen. drivers schrijven... brrrrrr....
voor driverloze lukt dat niet blijkbaar. je kan daar vanuit 'user space' niet komen.
Libusb lost dat op door libusb.sys. Dat is een kernel mode driver die een doorgeefluik naar de user mode wereld bevat.
als alles goed gaat is de boel tegen eind vanavond klaar
( ik ben de documentatie aant schrijven. ) en dan post ik het.
er zijn 3 dingen klaar
een .bas file (met commentaar) dat de interfacing doet.
een voorbeeldprogramma nagenoeg identiek aan test_usb.exe wat de ganse bus 'probed' en alle parameters ophaalt en toont.
een .cls ( een class ) die al het werk doet .
Methods:
my_device.start (index,vid,pid)
my_device.bulkwrite (endpoint,buffer,size)
my_device.bulkread (endpoint,buffer,count)
... ... ....
my_device.release
Properties :
my_device.vendor (read only property)
my_device.product (read only property)
my_device.serial (read only property)
my_device.error_string ( read only property )
Events :
my_device.error
een voorbeeldje
dim my_device as new usb_device
index=0
no_more=0
do
if my_device.start (index,&h341,&hcd00) =1 then
my_device.release
debug.print my_device.serial
index=index+1
else
no_more=1
end if
loop until no_more =1
bovenstaande code 'wandelt' door alle device met een zelfde VID en PID. stel je hebt 5 van die dingen aangesloten ( 5 dezelfde memorysticks bijvoorbeeld )
de bovenstaande code zal ze een voor een openen en hun serie nummers afprinten.
stel dat je totaal niks weet van wat er aangesloten is:
dan geef je gewoon geen vid en vip mee. ( die parameters zijn optional )
dim my_device as new usb_device
dim index
index=0
while my_device.start(index) =1
debug.print "------ Device " & index & " -----------
debug.print "VID : " & my_device.vid
debug.print "PID : " & my_device.pid
debug.print "Vendor : " & my_device.vendor
debug.print "Product: " & my_device.product
debug.print "Serial : " & my_device.serial
index=index+1
my_device.release
wend
zo simpel ist ( nu dan toch
)