USB开发-USB从启动到运行


序:最近在调USB驱动,使用的控制器是Candence USB2.0 High speed Contrller,这是一个支持otg的控制器,有感于usb庞大的知识体系,给同样入坑的同学一点启发,USB在处理细节上会由于硬件和操作系统的不同,但是其大体的流程是一致的。个人水平有限,难免有错欢迎拍砖交流,内容随心情更新…

时间有限,这里不会涉及到一些基础概念的讲解。

知识点1:一个支持otg的usb控制器端做host还是device除了软件支持外,是由ID线决定的 (当然一个支持otg的控制器硬件上必然存在ID线,但是有没有引出来就是硬件设计的问题了)。前提,你要清楚的是你的usb控制器是不是支持otg或者是单host还是单device控制器,没有确认这个,你单纯看外接的usb 连接器类型确认控制器端是做host还是device是错误的。
知识点2:otg设备ID线一般默认条件下ID为高,也就是自身默认是一个device的状态。
举个例子:电脑usb均为只是TYPE A座不存在ID线,一般我们理解只做host端,但是其内部usb controller可能也支持otg,只是强制只做host了,这里的强制指的是比如其ID线内部强制拉低。
type c口手机,存在ID线,当手机接电脑时(准确的说是手机通过外接type c转 type usb A公头接电脑),电脑端不存在ID线,双方依据ID线状态决定了手机为device,电脑为host。
而u盘插入手机(准确的说是u盘通过将存在ID线且为低电平的转接线接入手机type c座),由于手机端id线拉低,故手机知道自己做host,识别u盘。
知识点3(这个我不确定,希望没误导!):otg设备识别自身是host还是device,一旦连接建立(这里说的是硬件连线不断开),就一直是该身份,除非拔了线重新插了ID线反状态其身份才可能发生改变。

一、从代码运行流程讲USB设备如何被识别的

硬件上为了支持作为host,板子是通过mini AB座外接一根mini usb OTG数据线实现的。
下图1和图2 是usb2.0 OTG状态机转换图,其中的id表示usb的ID线,Vbus即usb的电源供电。这个图不着急你立马能看懂,OTG状态机是一个硬件寄存器,其状态是自动切换的。部分讲解中的概念这里说明下:
复位信号:usb的复位是指D+和D-信号线处于拉低的状态。
mini usb OTG数据线:其实就是mini usb B头转TYPE A USB座,但是其内部ID线与GND线进行了短接,所以当该线接入mini usb 座后,ID线会被拉低从而可以做host。
图-1
在这里插入图片描述
图-2
在这里插入图片描述

1.OTG设备作为HOST是如何识别插入的usb 设备

1)程序上电运行 ->使能 otg中断和复位中断(注:otg中断是由于状态机的改变而出发的一些中断,而复位中断对于host模式下是当复位结束后产生的中断),由于状态机默认是A_ILDE,上电后ID线在未接入设备一般是上拉状态,所以一旦程序运行,是一个B_ILDE或B_XXX的状态。
2)插入usb设备,这里以U盘为例,usb控制器ID线(phy的ID线)被拉低,因为B_ILDE->A_ILDE状态机的改变而触发otg空闲中断,在该中断中对vbus进行上电。
3)vbus上电后,U盘设备供电,那么U盘的D+或D-其中一根上拉电平会使得D+或D-其中一根高电平,这就是识别usb设备是full还是low设备的检测机制。状态机会因此进入A_HOST状态并触发A_HOST中断。状态机进入A_HOST后usb控制器会自动发送复位信号,也就是拉低D+/D-,不同控制器持续时间不同和,比如这个控制器默认复位时间为55ms。
4)复位期间通过JK信号检测,确认usb设备是FULL speed还是HIGH speed设备,将识别的设备speed类型更新到speed ctrl寄存器。
5)复位结束后,host会触发复位(完成)中断 //复位后的设备地址为0,因此之后host通过地址0与设备通信
6)接下来就是枚举过程了,具体的枚举过程后面讲。
所以简而言之,从程序运行,到执行复位的流程就是:程序运行,还能中断->插入设备,触发空闲中断,Vbus上电->上电后D+/D-触发状态机切换->引起复位->枚举->设备识别可用
我们不能忽视一种情况,就是也许设备在程序运行前就已经插着了,就像U盘电脑没上电前就插着这种情况,程序的执行逻辑是:
程序上电运行->检测是否是A_ILDE状态(ID线默认是高,A_ILDE表面插入了设备拉低了ID),如果是,Vbus供电->使能 otg中断和复位中断。->3)->4)->5)。所以实际的代码逻辑在1)使能 otg中断和复位中断前有状态机的判断。
在这里插入图片描述

2.JK信号识别

这是控制器与设备之间通过JK信号确认设备是FULL还是HIghspeed的过程,有空再写这个,待续

3.枚举

枚举过程简单而言就是初始化设备的一个过程,枚举是通过端点0控制传输方式通信的,经过枚举后该设备才真正起效。
1)host发送获取设备描述符。
//在设置device地址之前,有的控制器可能会再次复位设备(可选)
2)host设置设备地址(在此之前是用广播地址0通信) //具体设置设备地址流程是:首先host发送设置设备地址指令、地址(数据过程),设备返回ACK;然后host会发送IN请求device输入,直到device返回一个空数据域的数据包,然后host返回ACK后,当device收到这个ACK,device才真正开始启用新的设备地址。注意这里的IN过程是必须的,是host与device间确认新的地址是否起效的过程。
3)host使用新的设备地址获取设备描述符(以后都使用该设备地址通信),可获得配置描述符个数。
4)获取第i个配置描述符(获取数据长度9字节),配置描述符含有该配置下的配置、接口、端点描述符的总长度
5)获取第i个配置描述符(长度为包含该配置、接口、端点描述符的总长度)
//注:如果有多个配置描述符,循环4)->5)直到获取完
6)获取idproduct索引字符串描述符
7)获取idpmanufacturer索引字符串描述符
8)获取idserial numbert索引字符串描述符
9)设置配置描述符(也就是启用某个配置,因为可能多个配置)
设置完配置描述符,枚举过程结束,通用类usb设备设置识别完成。(当设置完配置描述符后,非0端点才开始可以启用
//这里没有说SOF包,SOF包是控制器复位完成后1ms后,host自动每ms(FULL speed)或125us(HIGH speed)发送的令牌包,没有应答。所以枚举期间会看到该包,所以这个包并不属于枚举的某个必然过程,并且SOF包是广播包,所有设备都可以收到。

至于再具体的分类,比如是U盘还是HID设备等等,会在该枚举后,遵循对应类型的具体协议再通过控制传输方式获取具体信息后,对应的设备才真正算可以用了。
下面是逻辑分析仪抓到的usb 控制包:
1)获取设备描述符
在这里插入图片描述2)设置设备地址
在这里插入图片描述3)使用设备地址获取设备描述符
在这里插入图片描述4)获取配置描述符(获取数据长度9字节)
在这里插入图片描述5)获取配置描述符
在这里插入图片描述6)获取idproduct索引字符串描述符
在这里插入图片描述

7)获取idpmanufacturer索引字符串描述符
在这里插入图片描述
8)获取idserial numbert索引字符串描述符
在这里插入图片描述

9)设置配置描述符
在这里插入图片描述
后续:具体分类,比如u盘设备接下来会根据BULK-ONLY协议发送GET MAX LUN等具体类请求,在应用处理上使用在BULK-ONLY协议基础上SCSI协议实现U盘数据的读写 。针对HID类设备根据该类具体协议操作,就要再研究具体类的实现了。
另外,文章写的主要是host模式,device模式的软件流程很好理解,因为usb流程都是host发起的,device只是被动接受。

二、代码实现流程图

这里的控制器是使用DMA进行数据传输的,当然不使用DMA也是可以的,主要该usb控制器内部集成了DMA控制器。DMA的作用毕竟在大数据传输时体现其高效性,不用白不用。

1.主流程图

在这里插入图片描述
cusbhUsbhDeviceAdd()接口实现对通用设备的枚举:
在这里插入图片描述

2.中断

这里的usb主要使用了otg中断和DMA中断来逻辑处理:
在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值