On various threads we've been discussing problems caused by the PACKED data structures in the StarterWare USB package. (These packed structures occur in the file usblib.h. If there are others, hidden within other files somewhere, then that might blow a hole in my solution.)
I discovered a possible solution that does not require a special compiler. I want your opinion.
Here is the solution:
- Examine each data structure defined in usblib.h.
- Identify the longest data type in the data structure (The longest is either short or int)
- When you declare that data structure, align it to that data type.
- (Or, the lazy way is to simply align them all to int.)
- With the TI C compiler, that is done like this:
#pragma DATA_ALIGN ( my_structure, 4 ) // This aligns to a 4 byte boundary
It so happens that, (by chance, or was it by somone's design?...) -- for the many particular structures defined in usblib.h -- this simple alignment procedure will avoid all unaligned data accesses. The processor can access each member of each structure with one simple access (rather than two or more accesses). No special compiler required.
Two data structures in usblib.h require a slightly special handling: tConfigHeader and tUSBBuffer. These must be padded by three bytes ahead of the data structure, and aligned to an int. Then once again, there are no unaligned data accesses.
Here is a simplified example of why it works.
typedef struct
{
char
char
short
char
char
char
char
short
short
short
char
char
char
char
}
PACKED tDeviceDescriptor;
It so happens that each short is preceeded by an EVEN NUMBER of chars. Therefore, if the structure is aligned to a short, then each short will likewise be aligned for easy access.
==================================================================
I'm puzzled why some structures were declared as "PACKED" when they are comprised of nothing but chars, and therefore automatically have no unaligned accesses. Examples:
tDescriptorHeader
tInterfaceDescriptor
tStringDescriptor
Likewise I'm puzzled why the two problematic structures -- tConfigHeader and tUSBBuffer -- were NOT declared as packed.
???