关于Linux初次获取USB设备描述符策略问题(8 or 64)

探讨了USB设备枚举过程中的控制端点0及其最大数据包长度的确定方法,对比了Linux与Windows的不同策略,并介绍了Linux如何改进以兼容更多设备。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

每个USB设备都有个控制端点,用于在枚举过程中同USB Host进行通信,例如,读取设备描述符、分配地址等等...,都是通过端点0来完成的。对于端点来说,它都具有个发送或接收数据包的最大值,对于普通端点来说,它都在端点描述符中的wMaxPacketSize中被定义,但是端点0没有端点描述符,那么它就定义在USB设备描述符中的bMaxPacketSize0中。如果要和端点0进行通信,那么首先应该得到bMaxPakcetSize0这个值,但是没有通信如何得到这个值,难道进入了一个死循环?

我们都知道,对于低速设备来说,端点0的最大数据包长度为8字节,对于全速设备来说,可以8、16、32、或64字节,对于高速设备来说,只能是64字节,也就说端点0的最大数据包长度至少为8,而通过设备描述符发现,bMaxPacketSize0刚好定义在8字节处,也就是说可以先读取8字节的设备描述符,从而得到了bMaxPacketSize0这个值,那么以后的传输就可以按照最大数据包长度这个值来进行传输。Linux也正是按照这个策略来的。

但是有的USB设备并不这样,在你获取8字节的设备描述符的时候它会将18字节的设备描述符全部返回给你,这样就可能会导致错误,但是在Windows下不会。原来Windows下的做法是首先发送获取64字节的设备描述符请求,如果端点0的最大数据包长度是32或64,设备只需要将18字节的设备描述符全部返回即可,但是如果端点0的最大数据包长度是8或16,而设备描述符长度是18字节,不能一次性传完,那么没有关系,对设备做一次reset,清除本次控制传输,由于前面已经得到了端点0的最大数据包长度,那么后面同样以最大数据包长度来通信,这就是Windows下的做法。

所以后来在Linux代码中也加入了这种策略,谁让厂家在测试USB设备的时候是在Windows下进行的呢,所以说不得不妥协,其实Linux的那种策略才是USB协议提供的策略。在后来的代码中,即先采用Windows的策略获取描述符(默认2次),如果失败,再采用标准的方法(默认两次)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值