4

I am trying to create host usb drivers for a printer device using the PIC32mx series . I am using the Microchip Library Application sample example . Wherein iI see that in order to send the BDT, the below mentioned structure is used. Now the BDT should be in all 8 bytes as documented in the Application note , But when I check the size of the BD_ENTRY union variable I see that it is different- 12 bytes. It should be 8 bytes if i am right. I tried to compile this particular part of the same code using Mikroc and simulated it using proteus and I find the byte length (sizeof) to be 8 bytes.

I am a bit confused, also I am new to the world of pointers, structures and unions.

typedef union _BD_STAT {
    BYTE Val;
    struct {
        //If the CPU owns the buffer then these are the values
        unsigned BC8:1;         //bit 8 of the byte count
        unsigned BC9:1;         //bit 9 of the byte count
        unsigned BSTALL:1;      //Buffer Stall Enable
        unsigned DTSEN:1;       //Data Toggle Synch Enable
        unsigned INCDIS:1;      //Address Increment Disable
        unsigned KEN:1;         //BD Keep Enable
        unsigned DTS:1;         //Data Toggle Synch Value
        unsigned UOWN:1;        //USB Ownership
    };

    struct {
        //if the USB module owns the buffer then these are
        // the values
        unsigned :2;
        unsigned PID0:1;        //Packet Identifier
        unsigned PID1:1;
        unsigned PID2:1;
        unsigned PID3:1;
        unsigned :1;
    };

    struct {
        unsigned :2;
        unsigned PID:4;         //Packet Identifier
        unsigned :2;
    };
} BD_STAT;    

typedef union __attribute__ ((packed))__BDT {
    //typedef union __BDT{
    struct __attribute__ ((packed)) {
        //struct   
        BD_STAT     STAT;
        WORD        CNT:10;
        WORD        ADR;                      
        WORD        ADRH;                   
    };
    struct __attribute__ ((packed)) {
        //struct   
        DWORD       res  :16;
        DWORD       count:10;
    };

    DWORD           w[2];
    WORD            v[4];
    QWORD           Val;
} BDT_ENTRY;
ajay
  • 9,402
  • 8
  • 44
  • 71
Deepworks
  • 371
  • 2
  • 4
  • 13
  • http://stackoverflow.com/questions/11770451/what-is-the-meaning-of-attribute-packed-aligned4/11772340#11772340 – Jeyaram Feb 21 '14 at 06:05
  • structure padding confuse you so batter to remove it. – Jayesh Bhoi Feb 21 '14 at 06:17
  • I would have thought you'd get 16 as the size of BDT_ENTRY. How many bytes are there in a WORD, DWORD and QWORD? – cup Feb 21 '14 at 06:19
  • I checked QWORD sizeoff it is 8 bytes , i also checked by removing the -attrib and packed things .. but they are supposed to remove the padding , could it be that i am useing free version of mplab c32 compiler , it does not provide optimize code .. just guessing . – Deepworks Feb 21 '14 at 06:49
  • When i remove attrib packed it comes to 16 bytes size of BDT_ENTRY and with the packed attrib it comes to 10 bytes . – Deepworks Feb 21 '14 at 07:05

2 Answers2

0

Give all of those anonymous structures names (temporarily) so that you can check them with sizeof. One issue I've seen with bitfields is that some compilers (including gcc, at least one time when it bit me) are overly influenced by the base type of a bitfield. So those unsigned bit:1 bitfields that are unioned with a Byte in BD_STAT might be slicing their bits out of a 4-byte unsigned causing BD_STAT to be too large. If you verify that with sizeof try changing the base type to Byte and see if it packs smaller.

Ben Jackson
  • 90,079
  • 9
  • 98
  • 150
0

In BD_STAT use unsigned char instead of unsigned. Bit fields always have the size of the underlying type and not the sum of their sizes. So BD_STAT is 4 bytes long.

Tomek Szpakowicz
  • 14,063
  • 3
  • 33
  • 55