打印
[应用相关]

使用STM32CubeMX编写USB复合设备

[复制链接]
7024|24
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
其实很简单搞了好久,怪ST呗,既没做到可读性增强,又搞到复杂了.目的先做一个CDC+MSC复合,就像STLink V2-1一样.
首先生成一个CDC工程并测试.

再用同样方法生成MSC,但是不要覆盖当前工程.因为木有分区和很多逻辑没实现,所以借助工具看看.
开始合并了,把CDC内容挪过来.
新建两个文件.
添加文件到Keil.
Keil的Include还要设置.然后编译测试,当然这个时候是不能用的.
修改CDC所用EP.
修改MSC所用EP.
编辑我们的复合头文件.复合用IAD.大概都是写在一起.
/* Define to prevent recursive inclusion -------------------------------------*/#ifndef __USBD_COMPOSITE_H#define __USBD_COMPOSITE_H#ifdef __cplusplusextern "C" {#endif/* Includes ------------------------------------------------------------------*/#include  "usbd_msc.h"#include  "usbd_cdc.h"#include "usbd_storage_if.h"#include "usbd_cdc_if.h"#define WBVAL(x) (x & 0xFF),((x >> 8) & 0xFF)#define DBVAL(x) (x & 0xFF),((x >> 8) & 0xFF),((x >> 16) & 0xFF),((x >> 24) & 0xFF)#define USBD_IAD_DESC_SIZE           0x08#define USBD_IAD_DESCRIPTOR_TYPE     0x0B#define USBD_CDC_FIRST_INTERFACE     0          /* CDC FirstInterface */#define USBD_CDC_INTERFACE_NUM       2          /* CDC Interface NUM */#define USBD_CDC_CMD_INTERFACE       0#define USBD_CDC_DATA_INTERFACE      1#define USBD_MSC_FIRST_INTERFACE     2          /* MSC FirstInterface */#define USBD_MSC_INTERFACE_NUM       1          /* MSC Interface NUM */#define USBD_MSC_INTERFACE           2#define MSC_INDATA_NUM              (MSC_EPIN_ADDR & 0x0F)#define MSC_OUTDATA_NUM             (MSC_EPOUT_ADDR & 0x0F)#define CDC_INDATA_NUM              (CDC_IN_EP & 0x0F)#define CDC_OUTDATA_NUM             (CDC_OUT_EP & 0x0F)#define CDC_OUTCMD_NUM              (CDC_CMD_EP & 0x0F)#define USBD_COMPOSITE_DESC_SIZE    (9  + 58 + 8 +  32 + 8)extern USBD_ClassTypeDef    USBD_COMPOSITE;/*** @}*//*** @}*/#ifdef __cplusplus}#endif#endif  /* __USBD_MSC_H *//*** @}*//*****************************END OF FILE****/然后写对应C文件,分别初始化各种.
#include "usbd_composite.h"#include "usbd_cdc.h"#include "usbd_msc.h"static USBD_CDC_HandleTypeDef *pCDCData;static USBD_MSC_BOT_HandleTypeDef *pMSCData;static uint8_t  USBD_Composite_Init (USBD_HandleTypeDef *pdev,uint8_t cfgidx);static uint8_t  USBD_Composite_DeInit (USBD_HandleTypeDef *pdev,uint8_t cfgidx);static uint8_t  USBD_Composite_EP0_RxReady(USBD_HandleTypeDef *pdev);static uint8_t  USBD_Composite_Setup (USBD_HandleTypeDef *pdev,USBD_SetupReqTypedef *req);static uint8_t  USBD_Composite_DataIn (USBD_HandleTypeDef *pdev,uint8_t epnum);static uint8_t  USBD_Composite_DataOut (USBD_HandleTypeDef *pdev,uint8_t epnum);static uint8_t  *USBD_Composite_GetFSCfgDesc (uint16_t *length);static uint8_t  *USBD_Composite_GetDeviceQualifierDescriptor (uint16_t *length);USBD_ClassTypeDef  USBD_COMPOSITE ={USBD_Composite_Init,USBD_Composite_DeInit,USBD_Composite_Setup,NULL, /*EP0_TxSent*/USBD_Composite_EP0_RxReady,USBD_Composite_DataIn,USBD_Composite_DataOut,NULL,NULL,NULL,NULL,USBD_Composite_GetFSCfgDesc,NULL,USBD_Composite_GetDeviceQualifierDescriptor,};/* USB composite device Configuration Descriptor *//*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */__ALIGN_BEGIN uint8_t USBD_Composite_CfgFSDesc[USBD_COMPOSITE_DESC_SIZE]  __ALIGN_END ={0x09,   /* bLength: Configuation Descriptor size */USB_DESC_TYPE_CONFIGURATION,   /* bDescriptorType: Configuration */WBVAL(USBD_COMPOSITE_DESC_SIZE),USBD_MAX_NUM_INTERFACES ,  /* bNumInterfaces: */0x01,   /* bConfigurationValue: */0x04,   /* iConfiguration: */0xC0,   /* bmAttributes: */0x96,   /* MaxPower 300 mA *//****************************CDC************************************//* Interface Association Descriptor */USBD_IAD_DESC_SIZE,               // bLengthUSBD_IAD_DESCRIPTOR_TYPE,         // bDescriptorTypeUSBD_CDC_FIRST_INTERFACE,         // bFirstInterfaceUSBD_CDC_INTERFACE_NUM,           // bInterfaceCount0x02,                             // bFunctionClass0x02,                             // bFunctionSubClass0x01,                             // bInterfaceProtocol0x04,                             // iFunction/*Interface Descriptor */0x09,   /* bLength: Interface Descriptor size */USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface *//* Interface descriptor type */USBD_CDC_CMD_INTERFACE,   /* bInterfaceNumber: Number of Interface */0x00,   /* bAlternateSetting: Alternate setting */0x01,   /* bNumEndpoints: One endpoints used */0x02,   /* bInterfaceClass: Communication Interface Class */0x02,   /* bInterfaceSubClass: Abstract Control Model */0x01,   /* bInterfaceProtocol: Common AT commands */0x01,   /* 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 */USBD_CDC_CMD_INTERFACE,   /* bMasterInterface: Communication class interface */USBD_CDC_DATA_INTERFACE,   /* 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),0x01,                           /* bInterval: *//*Data class interface descriptor*/0x09,   /* bLength: Endpoint Descriptor size */USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */USBD_CDC_DATA_INTERFACE,   /* bInterfaceNumber: Number of Interface */0x00,   /* bAlternateSetting: Alternate setting */0x02,   /* bNumEndpoints: Two endpoints used */0x0A,   /* bInterfaceClass: CDC */0x02,   /* bInterfaceSubClass: */0x00,   /* bInterfaceProtocol: */0x01,   /* 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),0x01,                              /* 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),0x01,                               /* bInterval: ignore for Bulk transfer *//****************************MSC************************************//* Interface Association Descriptor */USBD_IAD_DESC_SIZE,                        // bLengthUSBD_IAD_DESCRIPTOR_TYPE,                  // bDescriptorTypeUSBD_MSC_FIRST_INTERFACE,                  // bFirstInterfaceUSBD_MSC_INTERFACE_NUM,                    // bInterfaceCount0x08,                                      // bFunctionClass0x06,                                      // bFunctionSubClass0x50,                                      // bInterfaceProtocol0x05,/********************  Mass Storage interface ********************/0x09,   /* bLength: Interface Descriptor size */USB_DESC_TYPE_INTERFACE,   /* bDescriptorType: */USBD_MSC_INTERFACE,   /* bInterfaceNumber: Number of Interface */0x00,   /* bAlternateSetting: Alternate setting */0x02,   /* bNumEndpoints*/0x08,   /* bInterfaceClass: MSC Class */0x06,   /* bInterfaceSubClass : SCSI transparent*/0x50,   /* nInterfaceProtocol */0x05,          /* iInterface: *//********************  Mass Storage Endpoints ********************/0x07,   /*Endpoint descriptor length = 7*/0x05,   /*Endpoint descriptor type */MSC_EPIN_ADDR,   /*Endpoint address (IN, address 1) */0x02,   /*Bulk endpoint type */LOBYTE(MSC_MAX_FS_PACKET),HIBYTE(MSC_MAX_FS_PACKET),0x01,   /*Polling interval in milliseconds */0x07,   /*Endpoint descriptor length = 7 */0x05,   /*Endpoint descriptor type */MSC_EPOUT_ADDR,   /*Endpoint address (OUT, address 1) */0x02,   /*Bulk endpoint type */LOBYTE(MSC_MAX_FS_PACKET),HIBYTE(MSC_MAX_FS_PACKET),0x01,     /*Polling interval in milliseconds*/};/* USB Standard Device Descriptor */__ALIGN_BEGIN  uint8_t USBD_Composite_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC]  __ALIGN_END ={USB_LEN_DEV_QUALIFIER_DESC,USB_DESC_TYPE_DEVICE_QUALIFIER,0x00,0x02,0x00,0x00,0x00,0x40,0x01,0x00,};/*** @brief  USBD_Composite_Init*         Initialize the Composite interface* @param  pdev: device instance* @param  cfgidx: Configuration index* @retval status*/static uint8_t  USBD_Composite_Init (USBD_HandleTypeDef *pdev,uint8_t cfgidx){uint8_t res = 0;pdev->pUserData =  &USBD_CDC_Interface_fops_FS;res +=  USBD_CDC.Init(pdev,cfgidx);pCDCData = pdev->pClassData;pdev->pUserData = &USBD_Storage_Interface_fops_FS;res +=  USBD_MSC.Init(pdev,cfgidx);pMSCData = pdev->pClassData;return res;}/*** @brief  USBD_Composite_DeInit*         DeInitilaize  the Composite configuration* @param  pdev: device instance* @param  cfgidx: configuration index* @retval status*/static uint8_t  USBD_Composite_DeInit (USBD_HandleTypeDef *pdev,uint8_t cfgidx){uint8_t res = 0;pdev->pClassData = pCDCData;pdev->pUserData = &USBD_CDC_Interface_fops_FS;res +=  USBD_CDC.DeInit(pdev,cfgidx);pdev->pClassData = pMSCData;pdev->pUserData = &USBD_Storage_Interface_fops_FS;res +=  USBD_MSC.DeInit(pdev,cfgidx);return res;}static uint8_t  USBD_Composite_EP0_RxReady(USBD_HandleTypeDef *pdev){return USBD_CDC.EP0_RxReady(pdev);}/*** @brief  USBD_Composite_Setup*         Handle the Composite requests* @param  pdev: device instance* @param  req: USB request* @retval status*/static uint8_t  USBD_Composite_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req){switch (req->bmRequest & USB_REQ_RECIPIENT_MASK){case USB_REQ_RECIPIENT_INTERFACE:switch(req->wIndex){case USBD_CDC_DATA_INTERFACE:case USBD_CDC_CMD_INTERFACE:pdev->pClassData = pCDCData;pdev->pUserData =  &USBD_CDC_Interface_fops_FS;return(USBD_CDC.Setup(pdev, req));case USBD_MSC_INTERFACE:pdev->pClassData = pMSCData;pdev->pUserData =  &USBD_Storage_Interface_fops_FS;return(USBD_MSC.Setup (pdev, req));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 = pCDCData;pdev->pUserData =  &USBD_CDC_Interface_fops_FS;return(USBD_CDC.Setup(pdev, req));case MSC_EPIN_ADDR:case MSC_EPOUT_ADDR:pdev->pClassData = pMSCData;pdev->pUserData =  &USBD_Storage_Interface_fops_FS;return(USBD_MSC.Setup (pdev, req));default:break;}break;}return USBD_OK;}/*** @brief  USBD_Composite_DataIn*         handle data IN Stage* @param  pdev: device instance* @param  epnum: endpoint index* @retval status*/uint8_t  USBD_Composite_DataIn (USBD_HandleTypeDef *pdev,uint8_t epnum){switch(epnum){case CDC_INDATA_NUM:pdev->pClassData = pCDCData;pdev->pUserData =  &USBD_CDC_Interface_fops_FS;return(USBD_CDC.DataIn(pdev,epnum));case MSC_INDATA_NUM:pdev->pClassData = pMSCData;pdev->pUserData =  &USBD_Storage_Interface_fops_FS;return(USBD_MSC.DataIn(pdev,epnum));default:break;}return USBD_FAIL;}/*** @brief  USBD_Composite_DataOut*         handle data OUT Stage* @param  pdev: device instance* @param  epnum: endpoint index* @retval status*/uint8_t  USBD_Composite_DataOut (USBD_HandleTypeDef *pdev,uint8_t epnum){switch(epnum){case CDC_OUTDATA_NUM:case CDC_OUTCMD_NUM:pdev->pClassData = pCDCData;pdev->pUserData =  &USBD_CDC_Interface_fops_FS;return(USBD_CDC.DataOut(pdev,epnum));case MSC_OUTDATA_NUM:pdev->pClassData = pMSCData;pdev->pUserData =  &USBD_Storage_Interface_fops_FS;return(USBD_MSC.DataOut(pdev,epnum));default:break;}return USBD_FAIL;}/*** @brief  USBD_Composite_GetHSCfgDesc*         return configuration descriptor* @param  length : pointer data length* @retval pointer to descriptor buffer*/uint8_t  *USBD_Composite_GetFSCfgDesc (uint16_t *length){*length = sizeof (USBD_Composite_CfgFSDesc);return USBD_Composite_CfgFSDesc;}/*** @brief  DeviceQualifierDescriptor*         return Device Qualifier descriptor* @param  length : pointer data length* @retval pointer to descriptor buffer*/uint8_t  *USBD_Composite_GetDeviceQualifierDescriptor (uint16_t *length){*length = sizeof (USBD_Composite_DeviceQualifierDesc);return USBD_Composite_DeviceQualifierDesc;}/*** @}*//*** @}*//*** @}*/然后CDC的描述太任性了,改.

不然看文件吗根本不知道是什么玩意.接着修改usb_device.c
修改最大接口数.
因为是CDC 2个 + MSC 1个.然后如果还没有识别,修改Stack Size.
修改为IAD兼容.
复合成功:
程序:
USB 复合
后话:
如果电脑没驱动,请求助官网:http://www.st.com/en/development-tools/stsw-stm32102.html
思考:
如何复合多重HID呢?复合只是为了增加功能,并不能增加带宽.
沙发
Ketose| | 2017-4-18 10:05 | 只看该作者
非常好,谢谢了。

使用特权

评论回复
板凳
mmuuss586| | 2017-4-18 12:45 | 只看该作者

不错;

使用特权

评论回复
地板
yish| | 2018-10-22 17:37 | 只看该作者
附近怎么下载呢?谢谢!能否发EMAIL给我,10885644@qq.com

使用特权

评论回复
5
zhuomuniao110| | 2018-10-23 11:19 | 只看该作者
这个软件功能很棒

使用特权

评论回复
6
jemy00| | 2018-10-26 13:15 | 只看该作者
赞一个

使用特权

评论回复
7
linyuetian| | 2019-4-6 00:12 | 只看该作者
llll

使用特权

评论回复
8
yazl159357| | 2019-9-10 16:31 | 只看该作者
你好,请问一下能发一份源码吗1935458275@qq.com

使用特权

评论回复
9
yazl159357| | 2019-9-25 19:58 | 只看该作者
大神您好,能给一份源码吗

使用特权

评论回复
10
搞个大新闻| | 2020-4-24 15:58 | 只看该作者
老哥,stm32cubemx自动生成的代码的USBD_static_malloc不能用,必须重写

否则会给CDC和MSC句柄分配同一块内存,就乱套了

使用特权

评论回复
11
渴望阳光的种子| | 2020-4-24 19:32 | 只看该作者
搞个大新闻 发表于 2020-4-24 15:58
老哥,stm32cubemx自动生成的代码的USBD_static_malloc不能用,必须重写

否则会给CDC和MSC句柄分配同一块 ...

老哥你来的真及时,我刚好弄这个遇到问题了

使用特权

评论回复
12
渴望阳光的种子| | 2020-4-24 19:35 | 只看该作者
搞个大新闻 发表于 2020-4-24 15:58
老哥,stm32cubemx自动生成的代码的USBD_static_malloc不能用,必须重写

否则会给CDC和MSC句柄分配同一块 ...

USB大容量设备显示无法启动,还有串口只能接收不能发送是这里的问题吗?

使用特权

评论回复
13
渴望阳光的种子| | 2020-4-24 20:15 | 只看该作者
搞个大新闻 发表于 2020-4-24 15:58
老哥,stm32cubemx自动生成的代码的USBD_static_malloc不能用,必须重写

否则会给CDC和MSC句柄分配同一块 ...

哦,我不是这里的问题,我已经解决了,是PMA设置的问题,楼主没有提到

使用特权

评论回复
14
ycgxy1650601| | 2021-8-10 16:10 | 只看该作者
搞个大新闻 发表于 2020-4-24 15:58
老哥,stm32cubemx自动生成的代码的USBD_static_malloc不能用,必须重写

否则会给CDC和MSC句柄分配同一块 ...

mymalloc如何实现 “USBD_CDC_HandleTypeDef”和“USBD_MSC_BOT_HandleTypeDef” 两个不同的内存申请?

使用特权

评论回复
15
earlmax| | 2021-8-11 17:48 | 只看该作者
代码看着有点乱呢   

使用特权

评论回复
16
maudlu| | 2021-8-11 17:48 | 只看该作者
用STM32CubeMX 做USB HID 通信成功的吗  

使用特权

评论回复
17
mattlincoln| | 2021-8-11 17:48 | 只看该作者
STM32F4的2个USB是否可以同时使用

使用特权

评论回复
18
mollylawrence| | 2021-8-11 17:48 | 只看该作者
有谁使用Cube实现过USB读卡器功能

使用特权

评论回复
19
geraldbetty| | 2021-8-11 17:49 | 只看该作者
USB作为设备使用的例程。   

使用特权

评论回复
20
macpherson| | 2021-8-11 17:49 | 只看该作者
用新版STM32Cubemx  

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

68

主题

134

帖子

3

粉丝