Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
Delphi 2007 Professional
|
Record mit variabler Länge
18. Dez 2009, 13:47
Hi Leute!
Da ich nicht weis ob sowas überhaupt möglich ist möchte ich hier das Problem mal vorstellen. Kurz zur Erläuterung. Ich möchte einen Descriptor für ein USBDevice auslesen. Diesen bekomme ich als Zeiger auf ein ByteArray geliefert (mittels DLL Funktion) hier mal die Funktion:
Code:
DWORD (*MPUSBGetDeviceDescriptor)( HANDLE handle, // Input
PVOID pDevDsc, // Output
DWORD dwLen, // Input
PDWORD pLength); // Output
DWORD (*MPUSBGetConfigurationDescriptor)( HANDLE handle, // Input
UCHAR bIndex, // Input
PVOID pDevDsc, // Output
DWORD dwLen, // Input
PDWORD pLength); // Output
Die Deskriptoren werden im Controller (PIC) wie folgt abgelegt:
Code:
/* Device Descriptor */
ROM USB_DEVICE_DESCRIPTOR device_dsc=
{
0x12, // Size of this descriptor in bytes
USB_DESCRIPTOR_DEVICE, // DEVICE descriptor type
0x0200, // USB Spec Release Number in BCD format
0x00, // Class Code
0x00, // Subclass code
0x00, // Protocol code
USB_EP0_BUFF_SIZE, // Max packet size for EP0, see usb_config.h
0x04D8, // Vendor ID: 0x04D8 is Microchip's Vendor ID
0x000c, // Product ID: 0x0053
0x0000, // Device release number in BCD format
0x01, // Manufacturer string index
0x02, // Product string index
0x00, // Device serial number string index
0x01 // Number of possible configurations
};
/* Configuration 1 Descriptor */
ROM BYTE configDescriptor1[]={
/* Configuration Descriptor */
0x09,//sizeof(USB_CFG_DSC), // Size of this descriptor in bytes
USB_DESCRIPTOR_CONFIGURATION, // CONFIGURATION descriptor type
0xD6,0x00, // Total length of data for this cfg changed on 14.12.2009 oki old Value 0x20, 0x00
1, // Number of interfaces in this cfg
1, // Index value of this configuration
0, // Configuration string index
_DEFAULT | _SELF, // Attributes, see usb_device.h
50, // Max power consumption (2X mA)
/* Interface Descriptor */
0x09,//sizeof(USB_INTF_DSC), // Size of this descriptor in bytes
USB_DESCRIPTOR_INTERFACE, // INTERFACE descriptor type
0, // Interface Number
0, // Alternate Setting Number
28, // Number of endpoints in this intf (alle IN und OUT ohne Endpoint 0)
0xFF, // Class code
0xFF, // Subclass code
0xFF, // Protocol code
0, // Interface string index
/* Endpoint Descriptor */
0x07, /*sizeof(USB_EP_DSC)*/
USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
_EP01_OUT, //EndpointAddress
_BULK, //Attributes
USBGEN_EP_SIZE,0x00, //size
4, //Interval
0x07, /*sizeof(USB_EP_DSC)*/
USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
_EP01_IN, //EndpointAddress
_BULK, //Attributes
USBGEN_EP_SIZE,0x00, //size
4, //Interval
// Aditional Endpoints appanded on 14.12.2009 oki
0x07, //sizeof(USB_EP_DSC)
USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
_EP02_OUT, //EndpointAddress
_BULK, //Attributes
USBGEN_EP_SIZE,0x00, //size
4, //Interval
0x07, //sizeof(USB_EP_DSC)
USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
_EP02_IN, //EndpointAddress
_BULK, //Attributes
USBGEN_EP_SIZE,0x00, //size
4, //Interval
....
Die ganze Sache ist so organisiert, dass jeder Configuration-Deskriptor mehrere Interface-Deskriptoren und jeder Interface-Deskribtor mehrere Endpoint-Deskriptoren haben kann. Dies ist in der Struktur wie folgt definiert:
Code:
/* Configuration Descriptor */
0x09,//sizeof(USB_CFG_DSC), // Size of this descriptor in bytes
USB_DESCRIPTOR_CONFIGURATION, // CONFIGURATION descriptor type
0xD6,0x00, // Total length of data for this cfg changed on 14.12.2009 oki old Value 0x20, 0x00
[color=#ff003f]1, // Number of interfaces in this cfg[/color]
1, // Index value of this configuration
0, // Configuration string index
_DEFAULT | _SELF, // Attributes, see usb_device.h
50, // Max power consumption (2X mA)
/* Interface Descriptor */
0x09,//sizeof(USB_INTF_DSC), // Size of this descriptor in bytes
USB_DESCRIPTOR_INTERFACE, // INTERFACE descriptor type
0, // Interface Number
0, // Alternate Setting Number
[color=#ff003f]28, // Number of endpoints in this intf (alle IN und OUT ohne Endpoint 0)[/color]
0xFF, // Class code
0xFF, // Subclass code
0xFF, // Protocol code
0, // Interface string index
Blöd, ich wollte es so schön farbig machen, aber da stehen nur die Tags. Es geht um diese beiden Einträge:
Code:
1, // Number of interfaces in this cfg
...
28, // Number of endpoints in this intf (alle IN und OUT ohne Endpoint 0)
Dort ist jeweils angegeben, wie viele Interfaces und jeweils wie viele Endpoints kommen.
Nun dachte ich mir, nichts leichter als dass, legst du dir die passenden Records an. Gedacht, getan:
Delphi-Quellcode:
TEndPointDescriptor = packed record
Length : Byte; // sollte 0x07 sein
EndpointDescriptor : Byte; // Endpoint Deskriptor (Typangabe)
EndpointAddress : Byte; // Endpoint Address (IN0-IN15 0x80 - 0x8F; OUT0-OUT15 0x00 - 0x0F)
Attributes : TControlTransfer; // _BULK, _INT, _ISO, and _CTRL
BufferSize : Word; // 8, 16, 32 Byte; as Byte Array "64,0"
Intervall : Byte; // Polling Intervall
end;
TInterfaceDescriptor = packed record
Length : Byte; // sollte 0x09 sein
InterfaceDescriptor : Byte; // Interface Deskriptor (Typangabe)
InterfaceNumber : Byte; // Interface Nummer
AlternateSettingNumber : Byte; // Alternate Setting Number
EndpointCount : Byte; // Number of Endpoints (exclude Endpoint 0)
ClassCode : Byte;
SubClassCode : Byte;
ProtokollCode : Byte;
InterfaceStringIndex: Byte;
// EndPoints : Array[EndpointCount] of TEndPointDescriptor;
end;
TConfigurationDescriptor = packed record
Lengt : Byte; // sollte 0x09 sein
ConfigurationDescriptor : Byte; // Typangabe
TotalLength : Word; // Gesamtlänge des Descriptors as Byte Array "xx,0"
InterfaceCount : Byte;
ConfigurationIndex : Byte; // Index of this Configuration
ConfigurationStringIndex : Byte;// Configuration string index
Attributes : Byte; // _DEFAULT, _SELF ...
PowerConsumtion : Byte; // Max power consumption (2X mA)
// IterfaceDescriptors : Array[InterfaceCount] of TInterfaceDescriptor;
end;
Tja, böse Falle. Ihr seht schon meine auskommentierten Zeilen in den Records. Mir war dann eigentlich gleich klar, dass das so nicht geht, hab es aber mal da auskommentiert gelassen, damit ihr seht, wo mein Problem steckt.
Hat jemand eine Idee wie ich das hinbekommen kann? Mein Ziel war es eigentlich einen Zeiger auf eine Recordvariable vom Typ TConfigurationDescriptor zu übergeben und dann schön sauber alles parat zu haben. Natürlich kann ich die auskommentierten Zeilen auch als dynamische Arrays anlegen und mittels Funktion das ByteArray scheibchenweise in die Records gießen und zur Laufzeit die Längen der Arrays setzen.
Aber vielleicht gibt es ja auch eine richtig trickreiche Idee die mir nicht einfällt?
Ich dank euch schon mal für die Mühe,
Gruß oki
[edit] Uppps, noch schnell hinten dran, aktuelle Projekt in Delphi 2010! [/edit]
42
|