USB枚举过程说难也不难,只要把需要支持的standard request都支持了就ok。
但是如果需要用控制端点来做通讯,比如一些HID设备,就需要进一步考虑枚举过程的可靠性了。
看到过不少USB的代码,在枚举或者说控制端点传输方面,更多的是来一个packet,处理一个packet,一般来说,如果控制传输没有data out的过程,这样处理还是比较简单的。
但是如果控制端点传输需要data in也需要data out,就必须注意控制传输的每个stage(setup/data/status)都需要小心处理。
比如,会出现两个packet的标志位同时置位的情况:
1、out packet和setup packet同时到来:在一个data in后,pc发下来一个status out,紧接着就会发下一个setup packet。
2、out packet和IN packet同时到来:在一个data out后,pc紧接着发下来一个status in。
3、setup packet和out packet同时到来:setup packet和后面一个data out同时接收到。
以上3种情况,如果不判断来的先后,就会出现误处理。
曾经有一款产品经过whdl测试,也在很多电脑上做过测试,但在客户的一个电脑上出现通讯错误的问题,后来经查,发现这台电脑的usb控制器是OHCI,而不是常用的UHCI,OHCI各个packet发的速度快,会有上述3种情况发生,而固件是来一个packet处理一个packet,不考虑先后顺序,导致出现误处理。
以上问题最简单可靠的解决方法就是用状态机,在什么状态下才处理相应的packet。比如把控制传输分为以下几个阶段:
wait setup、wait data in、wait data out、wait status in、wait status out
这样就不会出现误处理的问题。
后来所有的产品usb枚举/控制传输都采用这种状态机的方式,usb设备发货超过千万量级,都没有出现问题。