USB插上电脑,首先就需要枚举,固件实现一个能简单工作的枚举,只需要支持:
1、支持get desc (包括device、configuration)
2、支持set address
3、支持set configuration
就可以在PC上看到USB设备枚举的过程。
而要支持上述standard request,无非就是
1、接收setup packet
2、data IN ; data IN..
3、status OUT
上述第2步data in可能有(如get desc )也可能没有(如set configuration/set address)。
如果有data IN,也可能只有一个data IN packet,就被PC用status out提前中断。
pc host一般会这样枚举设备:
usb设备插上PC
PC reset usb bus
host发get device desc
device IN 8字节 //这里PC只IN了一个packet,主要就是获取device deor 的长度
status OUT
reset bus
host发get device desc
device IN device desc 18字节 //这里PC把所有device desc 都读取
status OUT
... ...
以上第一个get device desc 的请求,host到底是全部取18个字节还是只取8个字节,都是符合usb specification的。
——————————————————————————
实现了枚举,后面就可以通讯,我们暂且打住不说后续的usb通讯。先说说上述所提到的枚举过程。
这个过程可以说可以保障USB设备基本可用,但可靠性、兼容性将会打折扣,可能有些电脑就不能识别。要想做一个兼容性、可靠性都没有问题的枚举,现在已经有很好的测试手段来辅助。那就是通过windows的whdl测试,如果这个测试环境不方便搭建,也可以退而求其次,用usb.org上的usbcv来测试。通过whdl测试的usb设备,可以说,usb设备可以被所有windows、几乎所有pc所识别。
要通过whdl的测试,必须严格按照usb specification 的chap 9来写固件。总的来说需要:
1、判断setup packet中的每个字节是否合法。包括wvalue/windex/wlength。如果不合法,必须stall。比如set address,如果address值大于127,就必须stall。虽然正常情况下PC不会发下来一个大于127的address。
2、支持所有standard request,除了Synch 。如果不支持某个standard request,必须stall,比如set desc 。
固件只要做到上述两点,就比较容易通过whdl/usbcv的测试,从而提高产品的可靠性、兼容性。
需要注意的几点,别忘了:
1、所有端点的toggle bit都需要在set configuration时clear;
2、在clear feature时,clear相应端点的toggle bit