Hi anybody I declare the folowing stuctures:
typedef struct { ubyte bLength; ubyte bDescriptorType; ubyte bInterfaceNumber; ubyte bAlternateSetting; ubyte bNumEndpoints; ubyte bInterfaceClass; ubyte bInterfaceSubClass; ubyte bInterfaceProtocol; ubyte iInterface; } USB_interface_desc_t; typedef struct { ubyte bLength; ubyte bDescriptorType; uword wTotalLength; ubyte bNumInterfaces; ubyte bConfigurationValue; ubyte iConfiguration; ubyte bmAttributes; ubyte MaxPower; } USB_config_desc_t; typedef struct { ubyte bLength; ubyte bDescriptorType; struct { ubyte address:4; ubyte reserved:3; ubyte direction:1; } bEndpointAddress; ubyte bmAttributes; uword wMaxPacketSize; ubyte bInterval; } USB_endpoint_desc_t; typedef struct { USB_config_desc_t usb_dev_config_desc; USB_interface_desc_t usb_interface_0_alt_0_desc; USB_endpoint_desc_t usb_dev_endpoint_alt_0_desc[2]; } USB_long_config_desc_t;
Does C166 insert "padding" bytes? - check the manual.
If I understood it correctly, there are pad bytes in structures. But still there is a problem. I am trying to establish communication with PC (Windows 98) via USB port, and with this pad bytes I need to know how to do that if the first sizeof(USB_interface_desc_t) returns 0x09, but actually 10 bytes were sent and second sizeof(USB_endpoint_desc_t) in C166 returns 0x08, while on PC side this structure has size of 7 bytes, and standard Windows DDK function for USB can't properly receive Endpoints information. I need help ASAP!!!!!
I am not familiar with Keil's C166 product, but usually if a compiler adds padding within a structure, it also provides a mechanism for controlling the padding. The control is usually in the form of a #pragma. Check the manual for #pragma support. Search the manual for "padding" or "packing".
Take a look at the following knowledgebase articles:
Thanks guys The directive #pragma pack(1) /* byte alignment */ #pragma BYTEALIGN works fine even on C166 version 4.05, witch I have.
" I am trying to establish communication with PC (Windows 98)" Welcome to the world of cross-platform interworking! If you're going to try to use 'C' structures to map language types onto the communications frame/packet format, you are going to have to study the manuals for both platforms very carefully - playing particular attention to data sizes, endianness, packing, alignments, and all the other implementation-specific details. Don't forget that Win98 runs on 32-bit Intel x86 architecture, and there is no guarantee that the data representation will match Keil's implementation on the 16-bit(?) C16x/ST10 - in fact, it's more likely that they won't match! :-(
Rather than try to force your system(s) to work with mis-aligned data - which could well be grossly inefficient - it might be better to have your driver(s) parse the communication packets into sutiable target-friendly structures?
When I work with controllers that "prefer" word alignments, I always make the length of structures even (insert a dummy char at the end if required) <b<and make sure all ints start after an even number of bytes. Even if this were to be transferred to a controller that did not care about alignment, no harm would be done.
7* ubyte ubyte bInterfaceProtocol; ubyte iInterface; ubyte bdummy } USB_interface_desc_t; 6* ubyte ubyte MaxPower; ubyte bdummy } USB_config_desc_t;
"...controllers that "prefer" word alignments..." Don't forget that the PC is a 32-bit architecture these days, so there are alignment issues with both 16- and 32-bit "objects!"
While we're on the topic, I notice there are some bitfield declarations in the structure. Bitfield endianess (that is, whether they are allocated from the LSB first or MSB first) is implementation-specific, and is independent of multi-byte word endianness. Given the fragment
struct { ubyte myBits:4; ubyte myOtherBits:4; } nibble; nibble.myBits = 0xF; nibble.myOtherBits = 0;
2000