自娱自乐7之Linux UDC驱动2(自编udc驱动,现完成枚举过程,从驱动代码分析枚举过程)

本文详细介绍了Linux USB设备控制器(UDC)驱动的枚举过程,通过调试打印解析了枚举过程中主机与设备的交互,包括设备描述符、配置描述符、字符串描述符的获取以及地址设置等关键步骤。适合对Linux USB驱动开发感兴趣的读者深入理解枚举流程。
摘要由CSDN通过智能技术生成

花了半个月,才搞定驱动中的枚举部分,现在说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)。全速设备不支持

//我的是全速设备用不倒QUALIFIERcomposite.cgadget_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 03

// 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

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值