STM32参考代码中Setup0_Process中为什么需要对wValue和wIndex进行byteswap

转自网易博客,博主:drifer

提纲:

²  第一步从具体数据的总体变化过程来演示原代码是正确的。

²  第二步解释为什么原代码这么变扭

²  第三步是我觉得怎么改才是最合理的

 

n  第一步

1. USB主端第一次发送Get_Descriptor命令为例,其数据构成是"80 06 00 01 00 00 40 00"

2. Setup0_Process()中将收到的数据赋值给DEVICE_INFO的前五个子项,赋值结果如下:

USBbmRequestType = 0x80      //pBuf.b单字节获取,无需解释

USBbRequest = 0x06            //pBuf.b单字节获取,无须解释

USBwValues = 0x0001           //pBuf.w获取2个字节,因为是小端模式,*pBuf.w的值是0x0100,byteswap后是0x0001

USBwIndexs = 0x0000           // 过程和USBwValue一样,只是变来变去都是0x0000

USBwLengths = 0x0040          //pBuf.w获取2个字节,因为是小端模式,*pBuf.w的值是0x0040

3. 后进入Data_Setup0(),这里使用到了USBwValues的值,源码“uint8_t wValue1 = pInformation->USBwValue1;”

这里需要了解USBwValue1的定义,定义为“#define USBwValue1 USBwValues.bw.bb1”,在usb_core.h里面。而USBwValues的声明如下: uint16_t_uint8_t USBwValues;         /* wValue */

这时候又牵涉到uint16_t_uint8_t的定义了,该定义如下:

typedef union

{

    uint16_tw;

    structBW

  {

        uint8_tbb1;

        uint8_tbb0;

    }

    bw;

} uint16_t_uint8_t;

 

从上面的定义可以看到USBValue1就是USBwValues的低字节,而USBValue0USBwValues的高字节(重点,变扭的根源!)

所以赋值语句“uint8_t wValue1 = pInformation->USBwValue1”执行后wValue1的值是0x01,从“usb complete 4th”这本书的第155页可以了解到

这个取值是正确的,0x01原书的截图如下:




 

4.Data_Setup0()中还使用了USBwlengths,使用语句是“__IO uint32_t wLength = pInformation->USBwLength;”  wLength被赋值后的值是0x40,也是对的。

 

n  第二步,为什么代码这么变扭

1.变扭的根源就是下面这个定义:

typedef union

{

  uint16_tw;

  structBW

  {

   uint8_t bb1;

   uint8_t bb0;

  }

  bw;

} uint16_t_uint8_t;

在小端模式下,低字节存储的地址小,高字节存储的地址大。而上面这个struct的定义时,将bb1作为低字节,将bb0作为高字节,实在是有违常识。这个定义从而导致USBwValue0是高字节,USBwValue1是低字节。

#define USBwValue0 USBwValues.bw.bb0

#define USBwValue1 USBwValues.bw.bb1

所以wValue需要用byteswap操作一下后,仍旧用USBwValue1来获取高字节。也就是说负负得正。

 

n  第三步,怎么改不变扭,这个简单,如下:

这个要反一下:

typedef union

{

  uint16_tw;

  structBW

  {

        uint8_tbb0;

    uint8_tbb1;

  }

    bw;

} uint16_t_uint8_t;

这个不变:

#define USBwValue0 USBwValues.bw.bb0

#define USBwValue1 USBwValues.bw.bb1

然后那个byteswap就不需要了,如下:

 

  if(pInformation->ControlState != PAUSE)

  {

// 获取SETUP包的8个字节数据,该数据构成信息详见<usb complete 4th>的第144page

   pInformation->USBbmRequestType = *pBuf.b++; /* bmRequestType */

   pInformation->USBbRequest = *pBuf.b++; /* bRequest */

    pBuf.w += offset;  /* word not accessed because of 32 bits addressing*/

   pInformation->USBwValue = *pBuf.w++; /* wValue*/

   pBuf.w += offset;  /* word not accessedbecause of 32 bits addressing */

   pInformation->USBwIndex  = *pBuf.w++; /* wIndex */

   pBuf.w += offset;  /* word not accessedbecause of 32 bits addressing */

   pInformation->USBwLength = *pBuf.w; /* wLength */    // zhoulz,这个为什么不需要byteswap?

  }

 

实际调用不变,如下:

   if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))

   {

     uint8_t wValue1 = pInformation->USBwValue1;  

     if (wValue1 == DEVICE_DESCRIPTOR)

     {

       CopyRoutine = pProperty->GetDeviceDescriptor;

     }

     else if (wValue1 == CONFIG_DESCRIPTOR)

     {

       CopyRoutine = pProperty->GetConfigDescriptor;

     }

     else if (wValue1 == STRING_DESCRIPTOR)

     {

       CopyRoutine = pProperty->GetStringDescriptor;

     }  /* End of GET_DESCRIPTOR */

   }


  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值