usb复合设备,串口和U盘搞定!

[复制链接]
24930|59
手机看帖
扫描二维码
随时随地手机跟帖
lcdi|  楼主 | 2013-5-23 22:06 | 显示全部楼层 |阅读模式
本帖最后由 lcdi 于 2013-6-1 20:40 编辑

我想把U盘(SD卡)和串口做成一个复合设备。
参考了一些资料,ConfigDescriptor里用IAD复合描述符,现在的问题是只能枚举出一个设备,DeviceDescriptor里的idProduct如果是mass storage demo里的设置,枚举出的就是mass storage,如果用demo里的虚拟串口里的设置,枚举出的就是虚拟串口。
那么,在复合设备里这个idProduct应该如何设置呢?

——————————————————————————————————————————————————————————————————————————————
在4.0库里的composite例子,把里面的HID部分去掉,换成virtual comport部分。
搞了好几天,遇到一些问题,也算加深了了解。把一些关键点写下来给大家参考:

1:主要修改usb_desc.c里的Composite_ConfigDescriptor,
bNumInterfaces要改成总共的interface数目,我这里串口用了2个,u盘用了1个。然后是具体的描述,因为串口有2个interface,所以需要IAD描述,如果只有一个,就可以像例程那样直接描述。
    // IAD
    0x08,        //描述符大小
    0x0B,        //IAD描述符类型
    0x00,        // bFirstInterface
    0x02,        // bInterfaceCount
    0x02,        // bFunctionClass: CDC Class
    0x02,        // bFunctionSubClass
    0x01,        // bFunctionProtocol
    0x00,        // iFunction         
下面接串口本来的描述符,IAD里很简单
原串口用了IN2,是中断传输,一直没找到和搞清楚具体的服务函数在哪儿?!有知道的说一声吧。
因为u盘也用IN2和OUT2,所以把这里改成IN4。
描述完串口接着描述u盘
                  // IAD
    0x08,        //描述符大小
    0x0B,        //IAD描述符类型
    0x02,        // bFirstInterface
    0x01,        // bInterfaceCount
    0x08,        // bFunctionClass: MASS STORAGE Class
    0x06,        // bFunctionSubClass
    0x50,        // bFunctionProtocol
    0x01,        // iFunction         
下来照搬u盘描述即可。
Composite_ConfigDescriptor 修改完了,别忘了修改一下usb_desc.h里的Composite_SIZ_CONFIG_DESC,因为增加了描述内容嘛。
这时候就能枚举出符合设备了。
2:整合,增加了端点,需要修改usb_prop.c里端点初始化部分。usb_endp.c里callback函数要修改。按照callback函数的增减修改usb_conf.h。
这里有很重要的定义,改不好的话设备还是用不了。
EP_NUM 是使用的端点数,我使用到ep4,那这里就是5。
下来是BTABLE_ADDRESS
各端点的缓冲区地址设置。BTABLE_ADDRESS是0,第一个缓冲区地址我这里要设为0x28。因为BTABLE_ADDRESS到第一个缓冲区之间是各缓冲区的偏移地址存放处,我用了5个端点,每个端点8个字节,所以我要把第一个缓冲区放在0x28才行。
这个问题搞了好久才明白,参考https://bbs.21ic.com/icview-208240-1-1.html ,很详细。

至此,修改完成,两种设备共存都正常工作了!

只是驱动不容易装,如果我安装ST的串口驱动(修改过PID),那么就只有这个设备,u盘没有,如果直接自动装驱动,有u盘没串口。这时候手动更新有惊叹号的设备,指定串口的驱动,装好后测试也就正常了。
——————————————————————————————————————————————————————————————————————————
U盘部分不需要驱动,串口部分不能自动安装驱动(即使系统安装过也不行),变惊叹号设备。如果再安装一次倒是可以用了,但是U盘却没了。对这个惊叹号设备手动选择驱动类型,强制使用以前安装的驱动则可以正常使用。这样搞总是不正常的样子。
其实,要修改驱动包里的INF, %DESCRIPTION%=DriverInstall,USB\VID_0483&PID_5750改成
%DESCRIPTION%=DriverInstall,USB\VID_0483&PID_5750&MI_00就可以一切正常了。
因为我这里设置串口为interface 0 开始的,惊叹号设备里也能看到 VID_0483&PID_5750&MI_00这样的信息,所以这样设置驱动就知道是要匹配0号interface的。
至此,全部正常!
huangxz| | 2013-5-23 22:12 | 显示全部楼层
我也很想知道,很久以前就想这么搞,到现在还没搞清楚

使用特权

评论回复
lcdi|  楼主 | 2013-5-23 22:45 | 显示全部楼层
huangxz 发表于 2013-5-23 22:12
我也很想知道,很久以前就想这么搞,到现在还没搞清楚

嗯,这次一定要弄清楚,因为别人既然能做出来,那我们也一定能做出来!

使用特权

评论回复
huangxz| | 2013-5-23 23:03 | 显示全部楼层
lcdi 发表于 2013-5-23 22:45
嗯,这次一定要弄清楚,因为别人既然能做出来,那我们也一定能做出来!
...

因为手头上没有这样的设备,用bushound采集一下usb的枚举,也许可以看的出一点。

使用特权

评论回复
香水城| | 2013-5-24 09:38 | 显示全部楼层
如果是基于STM32F103 的USB模块,ST提供的最新USB库中有复合设备的demo,它是基于MSC+HID的。

STM32F10x and STM32L1xx USB full-speed device library

在其readme文件中关于PID VID有如下解释:
When even one of the interface class of the device is changed, it should be handled
differently by Windows. However, it doesn't recognize the modification. To avoid conflict on
Windows, we suggest to assign another VID/PID to the device (idProduct = 0x5750) or
delete device instance from device manager.

使用特权

评论回复
lcdi|  楼主 | 2013-5-24 10:07 | 显示全部楼层
香水城 发表于 2013-5-24 09:38
如果是基于STM32F103 的USB模块,ST提供的最新USB库中有复合设备的demo,它是基于MSC+HID的。

STM32F10x a ...

多谢版主,我试过指定另一个ID,会辨认出一个复合设备。但是安装驱动失败,我再看看库里的说明吧:)

使用特权

评论回复
香水城| | 2013-5-24 10:27 | 显示全部楼层
本帖最后由 香水城 于 2013-5-24 10:29 编辑

我觉得还是不用改PID、VID,而是“or delete device instance from device manager.”比较好。因为你擅自改动了PID,对应驱动文件里也要改哦。

使用特权

评论回复
清风致影| | 2013-5-24 10:58 | 显示全部楼层
如果有例程就好了

使用特权

评论回复
lcdi|  楼主 | 2013-5-24 23:33 | 显示全部楼层
目前正在修改4.0版本库里的那个复合设备的例程,它也是用了另外一个PID,我要把HID改成串口,串口驱动只需要改INF文件里的PID,还是容易的,调好了再来汇报

使用特权

评论回复
lcdi|  楼主 | 2013-5-25 21:33 | 显示全部楼层
USB还是相当复杂的,用官方的例程基本改好了,不过通讯还没成,还要看看哪里不对。
枚举和驱动都能装上了。
因为我是用mass storage和virtual com来组合的,virtual com有两个interface,所以还是需要IAD描述。

使用特权

评论回复
hawksabre| | 2013-5-26 15:09 | 显示全部楼层
在官网上找找看   不知道有没有这一块的例程   感觉应该有吧  

使用特权

评论回复
lcdi|  楼主 | 2013-5-29 18:13 | 显示全部楼层
这两天通讯不成的原因就是缓冲区地址设置不对,第一个地址按本来的例程是0x18,前面留的空间不够。
吐槽一下ST,在这里给个注释说明一下就好了,修改了很多地方最后才找到问题。

使用特权

评论回复
quyifei| | 2013-6-1 21:04 | 显示全部楼层
非常不错,我也在做这样的尝试,顶你!

使用特权

评论回复
lcdi|  楼主 | 2013-6-1 23:09 | 显示全部楼层
huangxz 发表于 2013-5-23 22:12
我也很想知道,很久以前就想这么搞,到现在还没搞清楚

终于搞好了,顶楼更新了修改经验:)

使用特权

评论回复
拿起书本| | 2013-6-2 15:33 | 显示全部楼层
学到了不少东西,后面有些项目要用到这些,这个东西要顶,要顶·

使用特权

评论回复
babypig177| | 2013-6-7 16:01 | 显示全部楼层
留个爪爪,以备后用,谢谢了

使用特权

评论回复
trumpxp| | 2013-6-7 19:05 | 显示全部楼层
学到了很多知识   顶一个  不错哦   楼主  顶起来

使用特权

评论回复
njchenmin| | 2013-7-21 15:36 | 显示全部楼层
学习一下:)

使用特权

评论回复
woshansi| | 2014-1-25 22:52 | 显示全部楼层
lz,我的hid键盘无法发送按键的值是什么问题,或者说有可能是啥问题

使用特权

评论回复
lcdi|  楼主 | 2014-1-26 16:55 | 显示全部楼层
woshansi 发表于 2014-1-25 22:52
lz,我的hid键盘无法发送按键的值是什么问题,或者说有可能是啥问题

这种没搞过,建议你先在库的例程上一点一点修改,看看

使用特权

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

本版积分规则

个人签名:http://www.eeboard.com/avago-shengji?invite_id=5579

29

主题

407

帖子

7

粉丝