花了半个月,才搞定驱动中的枚举部分,现在说linux的枚举,windows可能有差别。
代码我会贴在后面,现在只是实现枚举,你可能对代码不感兴趣,我就不分析代码了,你可以看看
在《自娱自乐1》中的模板,比较一下,我做了什么,这会给你写udc驱动提供个思路。我直接分析
调试打印,就是枚举过程,我们从代码看枚举。打印位置可以在下面的代码里找到。
如果你要弄懂驱动代码中涉及枚举的地方,你就仔细看看代码在那打印的,这个对你完成一个udc驱
动有帮助。
如果你只是想简单了解枚举你就看看我分析的调试打印就可以了。
http://wenku.baidu.com/view/87064d244b35eefdc8d333dc.html
这个是枚举过程,对照着上面说的看我的调试打印,提示我的是从机,他说的是主机。
# insmod s3c2440_add_udc.ko
UPLLCON = 38022, wxl add//驱动usb的时钟源
# insmod s3c2440_udc.ko
# insmod gadget_transfer.ko
s3c2440_start//调用s3c2440_start(),在此会PULL_UP
s3c2440_udc_alloc_request//分配请求结构体内存
gadget_transfer gadget: gadget_transfer ready
# USB reset//pc检测到PULL_UP 复位设备
USB ep0 irq//ep0中断
Host: bRequest = 06 bRequestType = 80 wValue = 0x100wIndex=0x0 wLength=0x40//请求信息
//bRequest = 06是请求描述符,bRequestType = 80输入方向(输入是对主机而言) 端点0,
//请求长度64(微软的策略,这里linux学微软的)。
//wValue = 0x100: 这个前面的1表示设备描述符
USB_REQ_GET_DESCRIPTOR//第一次请求主要是获取最大包长度,此值在设备描述符第8个字节
USB_DT_DEVICE//设备描述符请求
s3c2440_udc_queue//调用了s3c2440_udc_queue()
Slave: length = 18 Vendor = ff0 Product = ff0 Device =212 iManufacturer = 1 iProduct = 2 iSerialNumber = 3 bNumConfigurations = 1
// Vendor = ff0 Product = ff0 Device = 212 这个在上一篇的gadget_transfer驱动中可以看到
// iManufacturer = 1 iProduct = 2iSerialNumber = 3 这个是字符串描述符引索
// bNumConfigurations = 1 你看看我上一篇的gadget_transfar驱动写的是2,这里却是1
/*
bNumConfigurations是配置数,是用count_configs()统计的,和你在gadget驱动中赋值无关
多配置很少,不过还是有,例如multi.c可以配置为RNDIS或ECM。
*/
8bytes USB USB reset //一次发出8个字节,我的ep0最大包长度是8,还有下面的xbytes都是已发的字节数。微软的策略后面没发完的不要了,直接复位设备。没有按usb spec来做。Windows要接受16个才复位。
USB ep0 irq
Host: bRequest = 05 bRequestType = 00 wValue = 0x4wIndex=0x0 wLength=0x0
//主机的请求又来了,这次是设置地址
// bRequest = 05 就是设置地址请求,
// bRequestType = 00 方向out,地址0
//wValue=0x4 设备地址4,在驱动中看不到它的使用,应该是硬件来判断
USB_REQ_SET_ADDRESS
USB ep0 irq//这个我调试是数据没准备好
USB ep0 irq
Host: bRequest = 06 bRequestType = 80 wValue = 0x100wIndex=0x0 wLength=0x12
//这次是真的获取设备描述符,长度18
USB_REQ_GET_DESCRIPTOR
USB_DT_DEVICE
s3c2440_udc_queue
Slave: length = 18 Vendor = ff0 Product = ff0 Device =212 iManufacturer = 1 iProduct = 2 iSerialNumber = 3 bNumConfigurations = 1//上面已解释
8bytes USB ep0 irq
16bytes USB ep0irq
18bytes USB ep0irq
Host: bRequest = 06 bRequestType = 80 wValue = 0x200wIndex=0x0 wLength=0x9
/*
wValue = 0x200: 这个前面的2表示配置描述符,后面是引索
*/
//获取配置描述符
USB_REQ_GET_DESCRIPTOR
USB_DT_CONFIG
s3c2440_udc_queue
Slave: length = 9 TotalLength = 32 NumInterfaces = 1ConfigurationValue = 3 iConfiguration = 4 bMaxPower = 250
/*
length = 9描述符长度为9
TotalLength = 32配置信息的长度--包括配置描述符、接口描述符、端点描述符长度的总和
NumInterfaces = 1 接口数
ConfigurationValue = 3用于表示 USB设备的配置值,主机就是根据这个选
iConfiguration = 4字符串描述符的索引值
bMaxPower = 250用于表示 USB设备运行时所需要消耗的总线电流,单位以2mA 为基准。USB设备可以从USB总线上获得最大的电流为500mA,因此 bMaxPower 字段的最大值可以设置为250。
还有个bmAttributes,没打印
*/
8bytes USB ep0 irq
9bytes USB ep0irq
USB ep0 irq
USB ep0 irq
Host: bRequest = 06 bRequestType = 80 wValue = 0x300wIndex=0x0 wLength=0xff
/*
wValue = 0x300: 这个前面的3表示字符串描述符,后面是引索0
之前并没有看到0引索的字符串描述符,不过看一下composite.c就知道了
/* 0 == report all availablelanguage codes */
可用的语言数,不细说
*/
USB_REQ_GET_DESCRIPTOR
USB_DT_STRING
s3c2440_udc_queue
Slave: length = 4
4bytes USB ep0irq
Host: bRequest = 06 bRequestType = 80 wValue = 0x303wIndex=0x409 wLength=0xff
//3是上面的iSerialNumber = 3
USB_REQ_GET_DESCRIPTOR
USB_DT_STRING
s3c2440_udc_queue
Slave: length = 66
0123456789.0123456789.0123456789
//可以在上一篇的驱动开的这个,static charserial[] = "0123456789.0123456789.0123456789";
8bytes USB ep0 irq
16bytes USB ep0irq
24bytes USB ep0irq
32bytes USB ep0irq
40bytes USB ep0irq
48bytes USB ep0irq
56bytes USB ep0irq
64bytes USB ep0irq
66bytes USB ep0irq
//下面又来一次,就是获得的字符串描述不同而已
Host: bRequest = 06 bRequestType = 80 wValue = 0x200wIndex=0x0 wLength=0xff
USB_REQ_GET_DESCRIPTOR
USB_DT_CONFIG
s3c2440_udc_queue
Slave: length = 9 TotalLength = 32 NumInterfaces = 1ConfigurationValue = 3 iConfiguration = 4 bMaxPower = 250
8bytes USB ep0irq
16bytes USB ep0irq
24bytes USB ep0irq
32bytes USB ep0irq
32bytes USB ep0irq
USB ep0 irq
Host: bRequest = 06 bRequestType = 80 wValue = 0x300wIndex=0x0 wLength=0xff
USB_REQ_GET_DESCRIPTOR
USB_DT_STRING
s3c2440_udc_queue
Slave: length = 4
4bytes USB ep0irq
Host: bRequest = 06 bRequestType = 80 wValue = 0x302wIndex=0x409 wLength=0xff
// iProduct = 2
USB_REQ_GET_DESCRIPTOR
USB_DT_STRING
s3c2440_udc_queue
Slave: length = 46
Gadget gadget_transfer// static const char longname[]= "Gadget gadget_transfer";
8bytes USB ep0irq
16bytes USB ep0irq
24bytes USB ep0irq
32bytes USB ep0irq
40bytes USB ep0irq
46bytes USB ep0irq
Host: bRequest = 06 bRequestType = 80 wValue = 0x300wIndex=0x0 wLength=0xff//再一次,不清楚为什么
USB_REQ_GET_DESCRIPTOR
USB_DT_STRING
s3c2440_udc_queue
Slave: length = 4
4bytes USB ep0irq
Host: bRequest = 06 bRequestType = 80 wValue = 0x302wIndex=0x409 wLength=0xff
USB_REQ_GET_DESCRIPTOR
USB_DT_STRING
s3c2440_udc_queue
Slave: length = 46
Gadget gadget_transfer
8bytes USB ep0irq
16bytes USB ep0irq
24bytes USB ep0irq
32bytes USB ep0irq
40bytes USB ep0irq
46bytes USB ep0irq
USB ep0 irq
Host: bRequest = 06 bRequestType = 80 wValue = 0x100wIndex=0x0 wLength=0x12
USB_REQ_GET_DESCRIPTOR
USB_DT_DEVICE//获取设备描述符
s3c2440_udc_queue
Slave: length = 18 Vendor = ff0 Product = ff0 Device =212 iManufacturer = 1 iProduct = 2 iSerialNumber = 3 bNumConfigurations = 1
8bytes USB ep0irq
16bytes USB ep0irq
18bytes USB ep0irq
USB ep0 irq
Host: bRequest = 06 bRequestType = 80 wValue = 0x100wIndex=0x0 wLength=0x40//这里有用64长度请求一次
USB_REQ_GET_DESCRIPTOR
USB_DT_DEVICE
s3c2440_udc_queue
Slave: length = 18 Vendor = ff0 Product = ff0 Device =212 iManufacturer = 1 iProduct = 2 iSerialNumber = 3 bNumConfigurations = 1
8bytes USB ep0irq
16bytes USB ep0irq
18bytes USB ep0irq
USB ep0 irq
Host: bRequest = 06 bRequestType = 80 wValue = 0x100wIndex=0x0 wLength=0x12
USB_REQ_GET_DESCRIPTOR
USB_DT_DEVICE//又来一次
s3c2440_udc_queue
Slave: length = 18 Vendor = ff0 Product = ff0 Device =212 iManufacturer = 1 iProduct = 2 iSerialNumber = 3 bNumConfigurations = 1
8bytes USB ep0irq
16bytes USB ep0irq
18bytes USB ep0irq
USB ep0 irq
USB ep0 irq
Host: bRequest = 06 bRequestType = 80 wValue = 0x600wIndex=0x0 wLength=0xa
USB_REQ_GET_DESCRIPTOR
USB_DT_DEVICE_QUALIFIER
//设备限定描述符用于指定另一传输速率下该设备的总体信息,如果高速USB设备既需要采用高速传//输又需要全速传输,则它必须支持设备限定描述符(Device_Qualifier)。全速设备不支持
//我的是全速设备用不倒QUALIFIER,composite.c用gadget_is_dualspeed()这个判断
USB ep0 irq
USB ep0 irq
Host: bRequest = 06 bRequestType = 80 wValue = 0x600wIndex=0x0 wLength=0xa
USB_REQ_GET_DESCRIPTOR
USB_DT_DEVICE_QUALIFIER
USB ep0 irq
USB ep0 irq
Host: bRequest = 06 bRequestType = 80 wValue = 0x600wIndex=0x0 wLength=0xa
USB_REQ_GET_DESCRIPTOR
USB_DT_DEVICE_QUALIFIER
USB ep0 irq
USB ep0 irq
Host: bRequest = 06 bRequestType = 80 wValue = 0x200wIndex=0x0 wLength=0x9
USB_REQ_GET_DESCRIPTOR
USB_DT_CONFIG//这次你会看到到wValue & 0xff 是0到3
// iManufacturer = 1 iProduct = 2iSerialNumber = 3
s3c2440_udc_queue
Slave: length = 9 TotalLength = 32 NumInterfaces = 1ConfigurationValue = 3 iConfiguration = 4 bMaxPower = 250
8bytes USB ep0irq
9bytes USB ep0irq
USB ep0 irq
Host: bRequest = 06 bRequestType = 80 wValue = 0x200wIndex=0x0 wLength=0x20
USB_REQ_GET_DESCRIPTOR
USB_DT_CONFIG
s3c2440_udc_queue
Slave: length = 9 TotalLength = 32 NumInterfaces = 1ConfigurationValue = 3 iConfiguration = 4 bMaxPower = 250
8bytes USB ep0irq
16bytes USB ep0irq
24bytes USB ep0irq
32bytes USB ep0irq
USB ep0 irq
Host: bRequest = 06 bRequestType = 80 wValue = 0x300wIndex=0x0 wLength=0xff
USB_REQ_GET_DESCRIPTOR
USB_DT_STRING
s3c2440_udc_queue
Slave: length = 4
4bytes USB ep0irq
USB ep0 irq
Host: bRequest = 06 bRequestType = 80 wValue = 0x302wIndex=0x409 wLength=0xff
USB_REQ_GET_DESCRIPTOR
USB_DT_STRING
s3c2440_udc_queue
Slave: length = 46