你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

USB复合设备 HID + CDC串口问题

[复制链接]
tony_xy 提问时间:2024-1-27 22:49 / 未解决
分别写了CustomHID的键鼠代码、CDC代码测试均无问题,整合到一起后,插上电脑有时识别串口,有时识别HID,最终过不了几秒HID的设备挂掉报代码10,虽然串口显示设备正常运行,但使用CoolTerm(连串口工具)无法读到对应串口信息,等于CDC、HID均失败,请社区内高人帮我看下是什么问题导致的,万分感谢!我附上我整合部分代码

首先,usbd_decs.c的设备描述符

```
/** USB standard device descriptor. */
__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =
{
  0x12,                       /*bLength */
  USB_DESC_TYPE_DEVICE,       /*bDescriptorType 1*/
  0x00,                       /*bcdUSB */
  0x02,
  0xEF,                       /*bDeviceClass*/
  0x02,                       /*bDeviceSubClass*/
  0x01,                       /*bDeviceProtocol*/
  USB_MAX_EP0_SIZE,           /*bMaxPacketSize 64*/
  LOBYTE(USBD_VID),           /*idVendor*/
  HIBYTE(USBD_VID),           /*idVendor*/
  LOBYTE(USBD_PID_FS),        /*idProduct*/
  HIBYTE(USBD_PID_FS),        /*idProduct*/
  0x00,                       /*bcdDevice rel. 2.00*/
  0x02,
  USBD_IDX_MFC_STR,           /*Index of manufacturer  string 1*/
  USBD_IDX_PRODUCT_STR,       /*Index of product string 2*/
  USBD_IDX_SERIAL_STR,        /*Index of serial number string 3*/
  USBD_MAX_NUM_CONFIGURATION  /*bNumConfigurations 1*/
};
```
然后是我使用的composite.c的配置、IAD、接口、端点描述符
```
/* USB COMPOSITE device Configuration Descriptor */
static uint8_t USBD_COMPOSITE_CfgDesc[USB_COMPOSITE_CONFIG_DESC_SIZ] =
{
  0x09, /* bLength: Configuration Descriptor size */
  USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration*/
  USB_COMPOSITE_CONFIG_DESC_SIZ,
  /* wTotalLength: Bytes returned  107*/
  0x00,
  USBD_INTERFACE_NUM,         /*bNumInterfaces: 3 interface*/
  0x01,         /*bConfigurationValue: Configuration value*/
  0x00,         /*iConfiguration: Index of string descriptor describing
  the configuration*/
  0xC0,         /*bmAttributes: bus powered and Support Remote Wake-up */
  0x32,         /*MaxPower 100 mA: this current is used for detecting Vbus*/
  /* 09 */

  /*---------------------------------------------------------------------------*/
  /* CUSTOM HID 32*/
  #if 1
//        /* HID IAD 8*/
//        /* Interface Association Descriptor */
//        USBD_IAD_BLENGTH,        /*bLength*/
//        USB_DESC_TYPE_INTERFACE_ASSOCIATION, /*bDescriptorType*/
//        USBD_INTERFACE_HID,/*bFirstInterface */
//        0x01,/*bInterfaceCount */
//        0x03,/*bFunctionClass */
//        0x00,/*bFunctionSubClass */
//        0x01,/*bFunctionProtocol */
//        0x00,/*iFunction */
  /* CUSTOM HID 32*/
  /************** Descriptor of CUSTOM HID interface ****************/
  0x09,         /*bLength: Interface Descriptor size*/
  USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/
  USBD_INTERFACE_HID,         /*bInterfaceNumber: Number of Interface=0*/
  0x00,         /*bAlternateSetting: Alternate setting*/
  0x02,         /*bNumEndpoints*/
  0x03,         /*bInterfaceClass: CUSTOM_HID*/
  0x00,         /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
  0x01,         /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
  0,            /*iInterface: Index of string descriptor*/
  /******************** Descriptor of CUSTOM_HID *************************/
  0x09,         /*bLength: CUSTOM_HID Descriptor size*/
  CUSTOM_HID_DESCRIPTOR_TYPE, /*bDescriptorType: CUSTOM_HID*/
  0x11,         /*bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number*/
  0x01,
  0x00,         /*bCountryCode: Hardware target country*/
  0x01,         /*bNumDescriptors: Number of CUSTOM_HID class descriptors to follow*/
  0x22,         /*bDescriptorType*/
  USBD_CUSTOM_HID_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor = 117U*/
  0x00,
  /******************** Descriptor of Custom HID endpoints ********************/
  0x07,          /*bLength: Endpoint Descriptor size*/
  USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/

  CUSTOM_HID_EPIN_ADDR,     /*bEndpointAddress: Endpoint Address (IN)*/
  0x03,          /*bmAttributes: Interrupt endpoint*/
  CUSTOM_HID_EPIN_SIZE, /*wMaxPacketSize: 32 Byte max */
  0x00,
  CUSTOM_HID_FS_BINTERVAL,          /*bInterval: Polling Interval */

  0x07,          /* bLength: Endpoint Descriptor size */
  USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */
  CUSTOM_HID_EPOUT_ADDR,  /*bEndpointAddress: Endpoint Address (OUT)*/
  0x03, /* bmAttributes: Interrupt endpoint */
  CUSTOM_HID_EPOUT_SIZE,  /* wMaxPacketSize: 32 Bytes max  */
  0x00,
  CUSTOM_HID_FS_BINTERVAL,  /* bInterval: Polling Interval */
  #endif

  /*---------------------------------------------------------------------------*/
        /* CDC 8 + 58*/
        #if 1
        /* CDC IAD 8*/
        /* Interface Association Descriptor */
        USBD_IAD_BLENGTH,        /*bLength*/
        USB_DESC_TYPE_INTERFACE_ASSOCIATION, /*bDescriptorType*/
        USBD_INTERFACE_CDC_CMD,/*bFirstInterface  = 1*/
        0x02,/*bInterfaceCount */
        0x02,/*bFunctionClass */
        0x02,/*bFunctionSubClass */
        0x01,/*bFunctionProtocol */
        0x00,/*iFunction */

        /* CDC 58*/
        /*Interface Descriptor */
        0x09,   /* bLength: Interface Descriptor size */
        USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
        /* Interface descriptor type */
        USBD_INTERFACE_CDC_CMD,   /* bInterfaceNumber: Number of Interface = 1*/
        0x00,   /* bAlternateSetting: Alternate setting */
        0x01,   /* bNumEndpoints: One endpoints used */
        0x02,   /* bInterfaceClass: Communication Interface Class */
        0x02,   /* bInterfaceSubClass: Abstract Control Model */
        0x01,   /* bInterfaceProtocol: Common AT commands */
        0x00,   /* iInterface: */

        /*Header Functional Descriptor*/
        0x05,   /* bLength: Endpoint Descriptor size */
        0x24,   /* bDescriptorType: CS_INTERFACE */
        0x00,   /* bDescriptorSubtype: Header Func Desc */
        0x10,   /* bcdCDC: spec release number */
        0x01,

        /*Call Management Functional Descriptor*/
        0x05,   /* bFunctionLength */
        0x24,   /* bDescriptorType: CS_INTERFACE */
        0x01,   /* bDescriptorSubtype: Call Management Func Desc */
        0x00,   /* bmCapabilities: D0+D1 */
        0x01,   /* bDataInterface: 1 */

        /*ACM Functional Descriptor*/
        0x04,   /* bFunctionLength */
        0x24,   /* bDescriptorType: CS_INTERFACE */
        0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
        0x02,   /* bmCapabilities */

        /*Union Functional Descriptor*/
        0x05,   /* bFunctionLength */
        0x24,   /* bDescriptorType: CS_INTERFACE */
        0x06,   /* bDescriptorSubtype: Union func desc */
        0x00,   /* bMasterInterface: Communication class interface */
        0x01,   /* bSlaveInterface0: Data Class Interface */

        /*Endpoint 2 Descriptor*/
        0x07,                           /* bLength: Endpoint Descriptor size */
        USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */
        CDC_CMD_EP,                     /* bEndpointAddress */
        0x03,                           /* bmAttributes: Interrupt */
        LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
        HIBYTE(CDC_CMD_PACKET_SIZE),
        CDC_FS_BINTERVAL,                           /* bInterval: */
        /*---------------------------------------------------------------------------*/

        /*Data class interface descriptor*/
        0x09,   /* bLength: Endpoint Descriptor size */
        USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
        USBD_INTERFACE_CDC,   /* bInterfaceNumber: Number of Interface  = 2*/
        0x00,   /* bAlternateSetting: Alternate setting */
        0x02,   /* bNumEndpoints: Two endpoints used */
        0x0A,   /* bInterfaceClass: CDC */
        0x00,   /* bInterfaceSubClass: */
        0x00,   /* bInterfaceProtocol: */
        0x00,   /* iInterface: */

        /*Endpoint OUT Descriptor*/
        0x07,   /* bLength: Endpoint Descriptor size */
        USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
        CDC_OUT_EP,                        /* bEndpointAddress */
        0x02,                              /* bmAttributes: Bulk */
        LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
        HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
        0x00,                              /* bInterval: ignore for Bulk transfer */

        /*Endpoint IN Descriptor*/
        0x07,   /* bLength: Endpoint Descriptor size */
        USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
        CDC_IN_EP,                         /* bEndpointAddress */
        0x02,                              /* bmAttributes: Bulk */
        LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
        HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
        0x00,                               /* bInterval: ignore for Bulk transfer */
        #endif
};
```
在composite.c中新增变量及修改Init、DeInit、Setup、DataIn、DataOut、Ep0_RxReady方法
```
void *pClassData_CDC = NULL;
void *pClassData_HID = NULL;
static uint8_t  USBD_COMPOSITE_Init(USBD_HandleTypeDef *pdev,
                                   uint8_t cfgidx)
{
  uint8_t ret = 0U;

  /* CDC */
  pdev->pUserData = (void *)&USBD_CDC_fops_FS;
  ret += USBD_CDC.Init(pdev, cfgidx);
  pClassData_CDC = pdev->pClassData;
  /* HID */
  pdev->pUserData = (void *)&USBD_CustomHID_fops_FS;
  ret += USBD_CUSTOM_HID.Init(pdev, cfgidx);
  pClassData_HID = pdev->pClassData;

  return (uint8_t)ret;
}

static uint8_t  USBD_COMPOSITE_DeInit(USBD_HandleTypeDef *pdev,
                                     uint8_t cfgidx)
{
  /* CDC */
  pdev->pClassData = pClassData_CDC;
  pdev->pUserData = (void *)&USBD_CDC_fops_FS;
  USBD_CDC.DeInit(pdev, cfgidx);
  /* HID */
  pdev->pClassData = pClassData_HID;
  pdev->pUserData = (void *)&USBD_CustomHID_fops_FS;
  USBD_CUSTOM_HID.DeInit(pdev, cfgidx);

  return (uint8_t)USBD_OK;
}

static uint8_t  USBD_COMPOSITE_Setup(USBD_HandleTypeDef *pdev,
                                    USBD_SetupReqTypedef *req)
{
  USBD_StatusTypeDef ret = USBD_OK;
#if 0
  switch (req->bmRequest & USB_REQ_TYPE_MASK)
  {
    case USB_REQ_TYPE_CLASS :
      switch (req->bRequest)
      {
        default:
          USBD_CtlError(pdev, req);
          ret = USBD_FAIL;
          break;
      }
      break;

    case USB_REQ_TYPE_STANDARD:
      switch (req->bRequest)
      {
        default:
          USBD_CtlError(pdev, req);
          ret = USBD_FAIL;
          break;
      }
      break;

    default:
      USBD_CtlError(pdev, req);
      ret = USBD_FAIL;
      break;
  }
#endif
  switch (req->bmRequest & USB_REQ_TYPE_MASK){
    case USB_REQ_RECIPIENT_INTERFACE:{
      switch(req->wIndex){
        case USBD_INTERFACE_CDC:
        case USBD_INTERFACE_CDC_CMD:{
          pdev->pClassData = pClassData_CDC;
          pdev->pUserData = &USBD_CDC_fops_FS;
          USBD_CDC.Setup(pdev, req);
          break;
        }
        case USBD_INTERFACE_HID:{
          pdev->pClassData = pClassData_HID;
          pdev->pUserData = &USBD_CustomHID_fops_FS;
          USBD_CUSTOM_HID.Setup(pdev, req);
          break;
        }
        default:{break;}
      }
      break;
    }
    case USB_REQ_RECIPIENT_ENDPOINT:{
      switch(req->wIndex){
        case CDC_IN_EP:
        case CDC_OUT_EP:
        case CDC_CMD_EP:{
          pdev->pClassData = pClassData_CDC;
          pdev->pUserData = &USBD_CDC_fops_FS;
          USBD_CDC.Setup(pdev, req);
          break;
        }
        case CUSTOM_HID_EPIN_ADDR:
        case CUSTOM_HID_EPOUT_ADDR:{
          pdev->pClassData = pClassData_HID;
          pdev->pUserData = &USBD_CustomHID_fops_FS;
          USBD_CUSTOM_HID.Setup(pdev, req);
          break;
        }
        default:{break;}
      }
      break;
    }
    default:{break;}
  }
  return (uint8_t)ret;
}

static uint8_t  USBD_COMPOSITE_DataIn(USBD_HandleTypeDef *pdev,
                                     uint8_t epnum)
{
  switch(epnum){
    case (CDC_IN_EP & 0x0F):{
      pdev->pClassData = pClassData_CDC;
      pdev->pUserData = &USBD_CDC_fops_FS;
      USBD_CDC.DataIn(pdev, epnum);
      break;
    }
    case (CUSTOM_HID_EPIN_ADDR & 0x0F):{
      pdev->pClassData = pClassData_HID;
      pdev->pUserData = &USBD_CustomHID_fops_FS;
      USBD_CUSTOM_HID.DataIn(pdev, epnum);
      break;
    }
    default:{break;}
  }
  return (uint8_t)USBD_OK;
}

static uint8_t  USBD_COMPOSITE_EP0_RxReady(USBD_HandleTypeDef *pdev)
{
  pdev->pClassData = pClassData_CDC;
  pdev->pUserData = &USBD_CDC_fops_FS;
  USBD_CDC.EP0_RxReady(pdev);
  return USBD_OK;
}

static uint8_t  USBD_COMPOSITE_DataOut(USBD_HandleTypeDef *pdev,
                                      uint8_t epnum)
{
  switch(epnum){
    case CDC_OUT_EP:
    case CDC_CMD_EP:{
      pdev->pClassData = pClassData_CDC;
      pdev->pUserData = &USBD_CDC_fops_FS;
      USBD_CDC.DataOut(pdev, epnum);
      break;
    }
    case CUSTOM_HID_EPOUT_ADDR:{
      pdev->pClassData = pClassData_HID;
      pdev->pUserData = &USBD_CustomHID_fops_FS;
      USBD_CUSTOM_HID.DataOut(pdev, epnum);
      break;
    }
    default:{break;}
  }
  return (uint8_t)USBD_OK;
}
```
修改usbd_conf.h的最大接口数量及复制一个USBD_static_malloc
```
#define USBD_MAX_NUM_INTERFACES     5
/** Alias for memory allocation. */
#define USBD_malloc_CDC                (uint32_t *)USBD_static_malloc_CDC
它的实现在usbd_conf.c中为CUSTOM_HID的USBD_static_malloc复制品
void *USBD_static_malloc_CDC(uint32_t size)
{
  static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4+1)];/* On 32-bit boundary */
  return mem;
}

```

另外在usbd_con.c的[size=13.3333px]USBD_LL_Init方法中设置端口地址
```
  /* USER CODE BEGIN EndPoint_Configuration */
  HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x00 , PCD_SNG_BUF, 0x18);
  HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x80 , PCD_SNG_BUF, 0x58);
  /* USER CODE END EndPoint_Configuration */
  /* USER CODE BEGIN EndPoint_Configuration_CUSTOM_HID */
  HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , CUSTOM_HID_EPIN_ADDR , PCD_SNG_BUF, 0x98);
  HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , CUSTOM_HID_EPOUT_ADDR , PCD_SNG_BUF, 0xA8);
  /* USER CODE END EndPoint_Configuration_CUSTOM_HID */
  /* USER CODE BEGIN EndPoint_Configuration_CDC */
  HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , CDC_IN_EP , PCD_SNG_BUF, 0x0B8);
  HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , CDC_OUT_EP , PCD_SNG_BUF, 0x0C8);
  HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , CDC_CMD_EP , PCD_SNG_BUF, 0x0D8);
  /* USER CODE END EndPoint_Configuration_CDC */
```


以上为修改部分,该改的都改了,为什么电脑就是不识别呢...求帮忙!!!

























收藏 评论1 发布时间:2024-1-27 22:49

举报

1个回答
xmshao 回答时间:2024-1-29 11:43:14
不知你调整过工程的堆和栈没有,适当调大点试试。还有就是有无响应超时方面、中断优先级竞争方面的问题?毕竟1个接口和2个接口涉及的事件量是不一样的。
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版