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
we beginnen ergens te komen
hier een screendump van mijn 'gekoter' in de memory
debug.Print dump (&h32b2ab0,&h40)
=================================================================================
Buffer Address = 0x32B2AB0 : Block_Size = 0x40 (64)d
032B2AB0 0000 38 2D 2B 03 00 00 00 00-5C 5C 2E 5C 6C 69 62 75 8-+.....\\.\libu
032B2AC0 0010 73 62 30 2D 30 30 30 31-2D 2D 30 78 30 34 36 31 sb0-0001--0x0461
032B2AD0 0020 2D 30 78 34 64 30 39 00-00 00 00 00 00 00 00 00 -0x4d09.........
032B2AE0 0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
=================================================================================
debug.Print dump (&h32b2d38,&h40)
=================================================================================
Buffer Address = 0x32B2D38 : Block_Size = 0x40 (64)d
032B2D38 0000 08 24 2B 03 B0 2A 2B 03-5C 5C 2E 5C 6C 69 62 75 .$+..*+.\\.\libu
032B2D48 0010 73 62 30 2D 30 30 30 32-2D 2D 30 78 34 31 33 63 sb0-0002--0x413c
032B2D58 0020 2D 30 78 31 30 30 33 00-00 00 00 00 00 00 00 00 -0x1003.........
032B2D68 0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
=================================================================================
debug.Print dump (&h32b2408,&h40)
=================================================================================
Buffer Address = 0x32B2408 : Block_Size = 0x40 (64)d
032B2408 0000 30 09 2B 03 38 2D 2B 03-5C 5C 2E 5C 6C 69 62 75 0.+.8-+.\\.\libu
032B2418 0010 73 62 30 2D 30 30 30 33-2D 2D 30 78 34 31 33 63 sb0-0003--0x413c
032B2428 0020 2D 30 78 32 30 31 30 00-00 00 00 00 00 00 00 00 -0x2010.........
032B2438 0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
=================================================================================
debug.Print dump (&h32b0930,&h40)
=================================================================================
Buffer Address = 0x32B0930 : Block_Size = 0x40 (64)d
032B0930 0000 00 00 00 00 08 24 2B 03-5C 5C 2E 5C 6C 69 62 75 .....$+.\\.\libu
032B0940 0010 73 62 30 2D 30 30 30 34-2D 2D 30 78 30 34 62 34 sb0-0004--0x04b4
032B0950 0020 2D 30 78 36 38 33 30 00-00 00 00 00 00 00 00 00 -0x6830.........
032B0960 0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
=================================================================================
dit is een dump van de linked list USB_device
de structuur zit als volgt in elkaar :
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 ' pointer naar struct : USB_Device_Descriptor
enzovoort
eerste dump : vanaf address 32b2ab0
032B2AB0 0000 38 2D 2B 03 00 00 00 00-5C 5C 2E 5C 6C 69 62 75 8-+.....\\.\libu
032B2AC0 0010 73 62 30 2D 30 30 30 31-2D 2D 30 78 30 34 36 31 sb0-0001--0x0461
de eerste 4 bytes : 38 2D 2B 03 zijn het address ( de pointer naar ) van het VOLGENDE blok
de volgende 4 bytes :00 00 00 00 zijn het address ( de pointer naar ) het vorige. aangezien dat allemaal nullen zijn is er geen vorig blok.
dus als we het memory op 38 2D 2B 03 dumpen ( intel architectuur gebruikt little endian : draait dat om : byte order swappen 38 2D 2B 03 wordt dus 03 2b 2d 38 ) dan zien we daar inderdaad het volgende blok zitten
wanner we nu opniew de eerste 4 byte van dat nieuwe blok nemen en als address gebruiken kunnen we het volgende lezen.
je kan de boel zo 'afwandelen'.
komt er nu op aan om de juiste 'type ' te declareren zodat we dat rechtstreeks in VB kunnen zwikken.
theeft een beetje tijd gekost om dat dump commando in elkaar te froetsjelen maar tis verrekte handig. je kan eender waar koteren.
ik gebruik het gewoon in het immediate window ( probramma in break zetten en dan ctrl-G.
in dat venster kan je dan gewoon debug.print dump tralalala en je kan overal rondkoteren...
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 23:27:54 schreef Captnoord:
@free_electron: lekker bezig, met VB hehe. Je moet lol hebben op een bepaalde manier.....
Waarom deze vertaling naar VB, omdat het de bedoeling is om het multi language te maken?
Waarom VB.... viese taal[edit] trouwens die next en prev pointer kunnen ook een void pointer zijn. Die kan je later weer typecaste (als dat kan in vb) naar het goeie type.
omdat ik dat wil gebruiken vanuit vb !.
ik heb geen goesting om al mijn haar te verliezen met buikkramp opwekkende talen zoals C en delphi ( delphi gaat nog in een reden. ). En omdat ik het schijt heb aan vuile, ongedocumenteerde 'open source' ( der is niks 'open' aan libusb. ja,je hebt de source, maar je hebt ook 2 maand nodig om half te snappen wat het doet en hoe het werkt).
dat passeren van linked-lists is NOT-DONE in de windows wereld. der is geen enkel API call die dat doet. gewoon omdat het niet porteerbaar is naar alle talen. der is veel meer dan C alleen in de wereld.
En potverdikke om te bewijzen dat het kan vanuit VB ook !.
als je VB kent heb je geen programmeurs nodig. die gasten kunnen allemaal gaan doppen...
[Bericht gewijzigd door free_electron op ]
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
http://www.intel.com/intelpress/usb/
daar kan je de voorbeelden downloaden.
ze zijn voor ene oudere versie van VB en er is wat puzzelwerk aan maar het draait. ik zal de gemodde versies beschikbaar stellen als zip file.
je krijgt je host poorten te zien en je krijgt netjes de descriptors eruit.
ik heb nog niet geprobeerd om datatransport te doen.
ondertussen ben ik ene stuk verder met libusb ook.
onderstaand stukje code vastkleven aan een knop.
Dim x As Long
Dim y As Long
Dim my_usb_bus As USB_Bus ' maak een variabele aan van het type usb_bus
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
x = USB_get_busses() ' x bevat nu een pointer naar een array van type USB_Bus
msg "USB_get_busses dumped its information at address " & Hex$(x) ' toon het addresss
Debug.Print Dump(x, &H210) ' kijk eens wat er in zit ....
y = extract_long(x + &H208) ' haal de locatie van USB_devices op
' dat nummer &h208 is de positie namelijk 4+4+512 .
' de USB_bus is namelijk ene long+long+512(byte) en dan staat de long die we moeten hebben
Debug.Print "The address of USB_devices = " & Hex$(y)
Debug.Print Dump(y, &H40)
y = extract_long(y) ' haal de locatie van de volgende usb_device op
While y <> 0
Debug.Print "The Addres of the next USB device is : " & Hex$(y)
Debug.Print Dump(y, &H40)
y = extract_long(y)
Wend
Debug.Print "stop"
dit is de extract_long functie :
extract_long staat je toe om direct vanuit een kledder geheugen een long ( 4 byte) variabele te stelen. )
je geeft het address op van waar het moet komen en de functie retourneert het.
Public Function extract_long(ByVal ptr As Long) As Long
Dim Internal_Buffer(0 To 3) As Byte
Dim x As Long ' maak een long aan
Call CopyMemory(x, ByVal ptr, 4)
' copier 4 byte naar x
' opgelet : je moet die pointer absoluut als BYVAL doorgeven !!!!
' anders prop je daar de inhoud van de variabele PTR in ,
' in plaats van de inhoud waar PTR naar wijst !!!!
' per default gebeurt alles byref in VB ! en das net wat we NIET willen in dit geval
extract_long = x ' geef de inhoud van x terug
End Function
ik krijg daar mooi volgende dump uit :
Dim y As Long
Dim my_usb_bus As USB_Bus ' maak een variabele aan van het type usb_bus
stop
USB_get_busses dumped its information at address 32A0048
=================================================================================
Buffer Address = 0x32A0048 : Block_Size = 0x210 (528)d
032A0048 0000 00 00 00 00 00 00 00 00-62 75 73 2D 30 00 00 00 ........bus-0...
032A0058 0010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A0068 0020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A0078 0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A0088 0040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A0098 0050 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A00A8 0060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A00B8 0070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A00C8 0080 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A00D8 0090 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A00E8 00A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A00F8 00B0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A0108 00C0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A0118 00D0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A0128 00E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A0138 00F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A0148 0100 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A0158 0110 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A0168 0120 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A0178 0130 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A0188 0140 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A0198 0150 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A01A8 0160 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A01B8 0170 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A01C8 0180 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A01D8 0190 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A01E8 01A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A01F8 01B0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A0208 01C0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A0218 01D0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A0228 01E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A0238 01F0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
032A0248 0200 00 00 00 00 00 00 00 00-A0 04 2A 03 00 00 00 00 ..........*.....
=================================================================================
The address of USB_devices = 32A04A0
=================================================================================
Buffer Address = 0x32A04A0 : Block_Size = 0x40 (64)d
032A04A0 0000 D8 06 2A 03 00 00 00 00-5C 5C 2E 5C 6C 69 62 75 ..*.....\\.\libu
032A04B0 0010 73 62 30 2D 30 30 30 31-2D 2D 30 78 30 34 36 31 sb0-0001--0x0461
032A04C0 0020 2D 30 78 34 64 30 39 00-00 00 00 00 00 00 00 00 -0x4d09.........
032A04D0 0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
=================================================================================
The Addres of the next USB device is : 32A06D8
=================================================================================
Buffer Address = 0x32A06D8 : Block_Size = 0x40 (64)d
032A06D8 0000 10 09 2A 03 A0 04 2A 03-5C 5C 2E 5C 6C 69 62 75 ..*...*.\\.\libu
032A06E8 0010 73 62 30 2D 30 30 30 32-2D 2D 30 78 34 31 33 63 sb0-0002--0x413c
032A06F8 0020 2D 30 78 31 30 30 33 00-00 00 00 00 00 00 00 00 -0x1003.........
032A0708 0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
=================================================================================
The Addres of the next USB device is : 32A0910
=================================================================================
Buffer Address = 0x32A0910 : Block_Size = 0x40 (64)d
032A0910 0000 48 0B 2A 03 D8 06 2A 03-5C 5C 2E 5C 6C 69 62 75 H.*...*.\\.\libu
032A0920 0010 73 62 30 2D 30 30 30 33-2D 2D 30 78 34 31 33 63 sb0-0003--0x413c
032A0930 0020 2D 30 78 32 30 31 30 00-00 00 00 00 00 00 00 00 -0x2010.........
032A0940 0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
=================================================================================
The Addres of the next USB device is : 32A0B48
=================================================================================
Buffer Address = 0x32A0B48 : Block_Size = 0x40 (64)d
032A0B48 0000 00 00 00 00 10 09 2A 03-5C 5C 2E 5C 6C 69 62 75 ......*.\\.\libu
032A0B58 0010 73 62 30 2D 30 30 30 34-2D 2D 30 78 30 34 62 34 sb0-0004--0x04b4
032A0B68 0020 2D 30 78 36 38 33 30 00-00 00 00 00 00 00 00 00 -0x6830.........
032A0B78 0030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
=================================================================================
je moet wel verschrikkelijk opletten met rondkoteren in geheugen.... als je ergens komt waar je niet mag zijn krijg je zelfs geen 'blue screen of death' tis ogenblikkelijk een zwart scherm en de computer begint te checken hoeveel ram hij heeft ... ( zo met dat 'energy star logotje rechtsboven
)
lezen is gene probleem. maar probeer niks te copieren naar een null pointer .... das dodelijk
[Bericht gewijzigd door free_electron 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
bon . ik ben weer een stukje verder.
ik heb ondertussen de memcopy ook in orde.
memcopy werkt op boundaries.
der is ergens een max_directory name die op 512 staat. in vb moet die op 511 staan. ( 0 tot 511 is 512 elementen )
omdat ik dat over het hoofd gezien had stonden de boundaries niet juist en landden de pointers niet waar ze moesten.
dus das ook gefixt.
ik kan nu de lijst van voor naar achter wandelen.
de volgende stap is er alle andere informatie uit halen.
maar nu ga ik naar huis. tis genoeg geweest voor vandaag
Goed bezig 'free_electron', het gaat langzaam aan boven mijn pet. Dus ik wacht maar even af...
Als er iets getest kan worden, dan stuur maar !
Captnoord
mov eax, 0x666
Op 5 januari 2007 00:13:04 schreef free_electron:
[...]omdat ik dat wil gebruiken vanuit vb !.
ik heb geen goesting om al mijn haar te verliezen met buikkramp opwekkende talen zoals C en delphi ( delphi gaat nog in een reden. ). En omdat ik het schijt heb aan vuile, ongedocumenteerde 'open source' ( der is niks 'open' aan libusb. ja,je hebt de source, maar je hebt ook 2 maand nodig om half te snappen wat het doet en hoe het werkt).dat passeren van linked-lists is NOT-DONE in de windows wereld. der is geen enkel API call die dat doet. gewoon omdat het niet porteerbaar is naar alle talen. der is veel meer dan C alleen in de wereld.
En potverdikke om te bewijzen dat het kan vanuit VB ook !.
als je VB kent heb je geen programmeurs nodig. die gasten kunnen allemaal gaan doppen...
Dude relax, ik vindt het gewoon verwonderlijk, maar goed ik geef je wel gelijk. Er zijn gewoon met C te veel "Trukjes" waardoor de code waardeloos te lezen is. Maar goed ik vindt het gewoon verwonderlijk. Ik wens je echt veel succes.
Op 5 januari 2007 01:43:56 schreef free_electron:
je moet wel verschrikkelijk opletten met rondkoteren in geheugen.... als je ergens komt waar je niet mag zijn krijg je zelfs geen 'blue screen of death' tis ogenblikkelijk een zwart scherm en de computer begint te checken hoeveel ram hij heeft ... ( zo met dat 'energy star logotje rechtsboven)
Dan wordt die data zeker direct door een driver gebruikt, BSOD/resets krijg je niet door geheugen te wijzigen in windows op user level (tenminste ik ga er vanuit dat je geen win9x gebruikt, daar is het makkelijk). Al verbaasd het me niets hoor met die open source, die driver zou nooit je PC mogen crashen wat voor data uit een applicatie die ook krijgt. Ik zie al allerlei security leaks voor me.
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
@captnoord. met mijn 'relaxing' is niks mis hoor 
tis alleen frustrerend om telkens met dezelfde problemen geconfronteerd te worden : warrige code en zero documentatie.
If it was hard to write , it should be hard to understand is nog teveel het motto...
@madwizard: klopt die arrays worden rechtstreeks in de usb controller gepletst ( dat is echt een 'packet' wat daar verstuurd wordt in sommige gevallen met direct het endpoint erin ) als dat 'in limbo' landt is het gedaan met de fun.
libusb interfaced met een sys driver die in ring 0 draait... een verkeerde pas en gans dat kaartenhuis stort in.
ik heb ondertussen ook al gezien dat die libusb0 lekt gelijk een zeef ...
bij een crash ( nonfatal welteverstaan ) de-alloceert hij niet noodzakelijk het geheugen. ik heb de boel nu omzeidl door rtlmovememory te gebruiken ipv rtlcopymemory.
bij copymemory heb ik de copij maar het origineel wordt niet gereleased ...
bij movemem heb ik controle over dat blok geheugen. en als libusb het niet released doe ik het ( ik heb een 'grotere hamer' door het feit dat ik de boel aan vbNull kan toewijzen ...
)
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 ...
Misschien heb je hier wat aan:
http://support.microsoft.com/kb/153586
Waarschijnlijk is het een C lib en zijn de functies niet stdcall (zoals de windows API bijvoorbeeld). Weet niet of er een simpelere oplossing is dan bovenstaande, het is jaren geleden dat ik ooit nog iets met VB heb gedaan.
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.
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
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.
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.
Captnoord
mov eax, 0x666
tis alleen frustrerend om telkens met dezelfde problemen geconfronteerd te worden : warrige code en zero documentatie.
dat klinkt als een bekend probleem. Ach gelukkig heb ik mezelf aangeleerd doc's te schrijven van alles wat ik schrijf. Scheelt de programeurs die het willen lezen een hoop geklooi. Maar nog krijg ik code onder ogen waarvan ik het idee heb dat de comments niet kloppen. Ik vind dit hele gepruts wel interesant, omdat USB allemaal moeilijker lijkt dan dat het is. "Ik moet er nog eens invliegen" is iets wat ik nog met usb moet doen, nog geen tijd voor gehad. Ik volg dit op de voet 
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
tis om tschijt van te krijgen ...
ik krijg de basis aan de praat.
devicelists opvragen . de parameters opvragen etc lukt allemaal.
totdat ik probeer de vendorstrings te lezen. niks anders dan crashen. der is iets met de handles waar ik niet aan uit kan.
een van de interne pointers in de terugkerende structuur staat trouwens verkeerd .... als je die accesst krijg je een bsod aan je broek ...
ik heb ook al die gasten aangeschreven die die library 'geporteerd hebben'..... nuja geporteerd ... ik heb de indruk dat al wat ze gedaan hebben niet meer is dan de cr van unix aangepast naar crlf voor windows ....
is er documentatie : neen
hoe werkt het ?: weten we ook niet ..
zucht. open source my ass ! ongedocumenteerde vuiligheid ja !
maar we geven het niet op ...
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
tis al opgelost. theeft flink wat geduld gekost maar tis bijna rond. wat terugkwam blijkt ene relatieve pointer te zijn.
Ik kan nu mooi alle devices overlopen die aangekoppeld zijn . de VID,VIP en de bijbehorende strings opvragen ( als die er zijn tenminste. niet elk device heeft die.
ook het serienummer kan ik opvragen ( opnieuw : als dat er is .. )
Ik kan ook de ganse descriptor analyseren. hoeveel endpoints , max datasize enzovoort.
ben nu nog aant werken om de poweroncsumption en de rset er ook nog uit te peuteren.
Met andere woorden ik ben het VB equivalent aant schrijven van dat test programma wat bij libusb zit.
Je kan devices openen door vid en vip op te geven. In geval dat er meer dan 1 device is met die vid/vip kan je een index passeren.
kheb al ene paar keer iets naar mij muis geschreven ( met als resultaat dat ik ze kan unpluggen en terug inpluggen
)
volgende stap is een bordje met een ub controller erop en daar wat rommel naartoe blazen.
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
)
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
en we zijn weer een grote stap verder.
Ik heb nu bijna dagelijks contact met van de mensen die libusb gemaakt heeft en die ook weet hoe het werkt !
Nu is er een exact duplicaat van het C testprogramma.
Libusb is nu ook aangepast om de STDcalls te kunnen doen.
Er zijn ook een aantal 'helper' functies bijgekomen om het pointer-gemanipuleer op te lossen. De DLL resolved dat nu naar simpeler structuren ( geen linked lists meer )
Dit maakt dat ook voor andere programmeertalen ( waaronder ook C ) het een flink stuk eenvoudiger geworden is.
Ik heb nog flink wat documentatiewerk maar we komen er uit.
De class draait nu ook al properkers met errorhandling en alles. af en toe kwam er nog een crash omdat de DLL geen assumpties maakt. een foute parameter is 'mort subite' ...
de VB class lost die problemen op.
stukje code :
dim my_usbdevice as new USB_device
Private Sub Command1_Click()
Dim index
index = 0
UsbInit
textbox.Text = ""
While my_usbdevice.Start(index) <> 0
msg " Device : " & index
msg " Product ID : (" & Hex$(my_usbdevice.PID) & ") : " & my_usbdevice.ProductID
msg " Vendor ID : (" & Hex$(my_usbdevice.VID) & ") : " & my_usbdevice.VendorID
msg " Serial nr : " & my_usbdevice.Serial
my_usbdevice.Release
index = index + 1
Wend
End Sub
sub Msg (txt)
text1.text=text1.text & txt$ & vbcrlf
end Msg
je kan nu openen zonder vid en vip te kennen
openen met alleen een vid , of openen met vid en vip
de strings en alle descriptors kan je zo aan
en rollen er mooi uit. je kan de ganse usb structuur bewandelen.
nu nog de andere kant ....
initialisatiecode voor een nest processoren.
ik mik op PIC , 8051 ( atmel )
met voorbeeldekes in assembler en picbasic en eventueel c ...
juist genoeg code om de usb structuur op te zetten en endpoints aan te maken . de rest doe je dan zelf.
( usb is dan echt een 'pijp' aan de pc kant : vind dit device , en blaas zoveel bytes naar dat endpoint , of haal zoveel bytes van dat endpoint op.
en langs de nadere kant krijg je een interrupt als er iets toekomt of opgehaald wordt. en tstaat in een buffer.
als er andere targets zijn ... laat maar weten
hopelijk kunnen we hierna al die seriele poorten in de vuilbak smijten, en wordt het maken van usb devices even simpel als een weerstandje aan een ledje hangen...
Martijn v
KIS!!: Keep It Simple
mooi werk F_E! nog hulp in VB nodig?
je hebt die gasten gewoon gemaild, "Hey doet eens ff helpen?!!" 
USB is ook wel iets meer van de tijd he? mooi man.
De code is wel iets uitgebreider dan rs232. (natuurlijk heeft vb MScomm.ocx)