本帖最后由 宫影空明人不往 于 2023-9-27 17:12 编辑
前言最近在学习USB设备,刚好看见Geehy出了一个USB相关的SDK。 具体链接为:https://www.geehy.com/support/apm32?id=489 里面集结了F0,F1,F4的USB例程,非常方便USB的开发。
正好我手里面有一块F103的板子,可以去参照它的SDK进行修改,将其单个CDC的工程修改成一个双CDC的工程。 因为时间有限,改写后的效果只是能被电脑识别出双CDC,CDC2的数据收发在后续进行补充。 那就让我们开始吧。
1. 修改设备描述符因为需要修改为双CDC设备即复合设备(严格意义上应该是组合设备,但是电脑也是这么显示的那就成为复合设备),因此首先需要更改设备描述符。 设备描述符修改部分如下: /* bDeviceClass */
0xEF,
/* bDeviceSubClass */
0x02,
/* bDeviceProtocol */
0x01,
2.修改配置描述符从单CDC修改成双CDC,接口的数量从2改为4。 /* bNumInterfaces */
0x04,
接着就是加上接口关联描述符(IAD描述符)。 /* IAD Interface Association Descritor */
/* blength */
0x08,
/* IAD */
0x0b,
/* FirstInterface */
0x00,
/* InterfaceCount */
0x02,
/* FunctionClass:CDC */
0x02,
/* FunctionSubClass */
0x02,
/* FunctionProtcol */
0x01,
/* Function */
0x02,
一共需要添加两个IAD描述符,需要更改的是第一个接口编号以及接口数量。 每一个IAD描述符包含CDC的两个接口,控制接口以及输入输出接口。因此一共有四个接口(需要注意接口编号的更改)。
接口描述符下则包含其端点(控制端点一个,输入输出端点两个)。因此,双CDC一共需要6个端点。 因此在usbd_cdc.h中需要新增CDC2的端点定义 #define USBD_CDC2_FS_MP_SIZE 0x40
#define USBD_CDC2_HS_MP_SIZE 0x200
#define USBD_CDC2_CMD_MP_SIZE 0x08
#define USBD_CDC2_DATA_MP_SIZE 0x07
#define USBD_CDC2_CMD_EP_ADDR 0x84
#define USBD_CDC2_DATA_IN_EP_ADDR 0x83
#define USBD_CDC2_DATA_OUT_EP_ADDR 0x03
同时还需要更改配置描述符数组的大小 #define USBD_CONFIG_DESCRIPTOR_SIZE 141
这样,配置描述符就完成了。
2. 端点初始化USB的端点初始化在USBD_CDC_ClassInitHandler这一个函数中。通过查看函数可以知道它首先对usbDevCDC这一个结构体的数据进行初始化,向里面赋上端点的相应的信息,在调用usbDevCDC这个结构体里面的参数进行端点进行初始化。 因此首先对usbDevCDC进行修改。 <blockquote>uint8_t epInAddr2;
主要是根据CDC1增加CDC2相应的参数。 完成之后就对USBD_CDC_ClassInitHandler函数进行修改,大致代码如下: usbDevCDC->epCmdAddr2 = USBD_CDC2_CMD_EP_ADDR;
usbDevCDC->epInAddr2 = USBD_CDC2_DATA_IN_EP_ADDR;
具体请根据函数进行修改。
3. PMA初始化 端点传输数据需要缓冲空间进行传输,该空间又称为PMA。新增了3个端点则需要对其PMA进行初始化,具体代码如下: USBD_ConfigPMA(&usbDeviceHandler, USBD_CDC2_EP_OUT_ADDR, USBD_EP_BUFFER_SINGLE, USBD_CDC2_EP_OUT_SIZE);
USBD_ConfigPMA(&usbDeviceHandler, USBD_CDC2_EP_IN_ADDR, USBD_EP_BUFFER_SINGLE, USBD_CDC2_EP_IN_SIZE);
USBD_ConfigPMA(&usbDeviceHandler, USBD_CDC2_EP_CMD_ADDR, USBD_EP_BUFFER_SINGLE, USBD_CDC2_EP_CMD_SIZE);
同时,缓冲区的地址以及大小也要定义,这里我就延续CDC1的分配,输入输出端点缓冲区为64,控制端点缓冲区为16。具体配置如下: #define USBD_CDC2_EP_OUT_ADDR 0x03
#define USBD_CDC2_EP_OUT_SIZE 0x1A0
#define USBD_CDC2_EP_IN_ADDR 0x83
#define USBD_CDC2_EP_IN_SIZE 0x150
#define USBD_CDC2_EP_CMD_ADDR 0x84
#define USBD_CDC2_EP_CMD_SIZE 0x190
到这里,双CDC的配置就完成了。
4. 程序验证 将修改好的工程进行编译,没有错误后将其烧到F103的板子上。将板子复位并通过USB线接入到电脑。 打开设备管理器查看可以发现,电脑将其识别成了一个复合设备,同时多出了COM7以及COM8两个串口。
查看复合设备的属性,其PID和VID值符合我编写的USB设备。 #define USBD_GEEHY_VID 12619
#define USBD_FS_PID 1002
这样的话至少描述符那边是没有什么问题了。接着就是通过串口助手工具进行查看。COM7是能够正常打印信息的,
而COM8(即CDC2)因为还没有编写相应的输出输入函数,因此没有数据打印。
5.总结
通过上述可知,修改描述符以及初始化相应端点使得电脑能够识别出多个CDC,但没有相应的数据传输。
因此后续对CDC2的数据传输代码进行编写。
|