【问题标题】:Union and structure for USB driver implementationUSB驱动实现的联合和结构
【发布时间】:2014-02-21 06:02:52
【问题描述】:

我正在尝试使用 PIC32mx 系列为打印机设备创建主机 USB 驱动程序。 我正在使用 Microchip 库应用示例。 其中我看到为了发送 BDT,使用了下面提到的结构。 现在 BDT 应该在应用笔记中记录的所有 8 个字节中, 但是当我检查 BD_ENTRY 联合变量的大小时,我发现它是不同的——12 个字节。如果我是对的,它应该是 8 个字节。 我尝试使用 Mikroc 编译同一代码的这个特定部分,并使用 proteus 对其进行模拟,我发现字节长度 (sizeof) 为 8 个字节。

我有点困惑,我也是指针、结构和联合领域的新手。

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;

【问题讨论】:

  • 结构填充让你感到困惑,所以击球手将其移除。
  • 我原以为你会得到 16 作为 BDT_ENTRY 的大小。 WORD、DWORD 和 QWORD 各有多少字节?
  • 我检查了 QWORD sizeoff 它是 8 个字节,我还通过删除 -attrib 和打包的东西来检查.. 但是它们应该删除填充,可能是我使用的是免费版本的 mplab c32编译器,它不提供优化代码..只是猜测。
  • 当我删除打包的属性时,BDT_ENTRY 的大小为 16 字节,打包后的属性为 10 字节。

标签: c


【解决方案1】:

给所有这些匿名结构名称(临时),以便您可以使用sizeof 检查它们。我在位域中看到的一个问题是,一些编译器(包括 gcc,至少有一次它咬我的时候)受到位域基本类型的过度影响。因此,那些与BD_STAT 中的Byte 联合的unsigned bit:1 位域可能会将它们的位从4 字节unsigned 中分割出来,从而导致BD_STAT 太大。如果您使用sizeof 验证这一点,请尝试将基本类型更改为Byte,看看它是否更小。

【讨论】:

    【解决方案2】:

    BD_STAT 中使用unsigned char 而不是unsigned。 位字段始终具有基础类型的大小,而不是它们大小的总和。所以BD_STAT 的长度是 4 个字节。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-21
      相关资源
      最近更新 更多