Einzelnen Beitrag anzeigen

oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#1

Record mit variabler Länge

  Alt 18. Dez 2009, 12: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
  Mit Zitat antworten Zitat