USB与SCSI

USB传输协议中的行为分为四种:控制传输,批量传输,中断传输,同步传输。为什么叫做行为,很简单,因为所有操作USB的协议如:SCSI,HID,UVC协议等等,都是基于这四种行为的。当然,USB底下的每一种协议都有他的特点,但这些特点都离不开上面四种传输,而本人对上面三种协议中,SCSI协议是比较熟悉,HID协议也做过相应的开发,UVC的话,只是大概了解了其中的操作。但总结出来,这些协议的特点在于数据的不同,而不是在于传输方式,因为看多了后你会发现,他还是离不开这四种传输方式的。下面就以我对SCSI协议的理解去解释下USB的操作吧,如有错误,请指点指点。。。。。

 

控制传输:

控制传输在我看来是USB传输的起点,他是使用端点0去进行对应的信息应答。这抽象一点的话就是你插个设备到电脑上,电脑要知道你要使用的是什么协议,接口数目,接口类型是什么,你要使用的是哪些端点,你的端点配置是怎样,你的那个设备名字叫什么玩意等等,端点0对于USB传输是必需的,没有端点0,电脑都不知道自己下一步要做什么了。当USB设备插入后,主机会发一些提取描述符的动作,如GET_DEVICE_DESCRIPTOR,GET_CONFIGURATION_DESCRIPTOR

发了这些信息后,紧接着会给设备分配地址:SET_ADDRESS,后面的操作基本也就那些,会多了一些GET_STRING_DESCRIPTOR,但这里要注意,虽然是同为GET_STRING_DESCRIPTOR,有些设备会因为参数不同会有多个这样的描述符,所以这里得要区分好主机发下来的参数。当然,这里就不对这些东西的每个参数进行一一解释了,查一下相应的资料都可以查看到的。这里要注意的就是GET_CONFIGURATION_DESCRIPTOR,这个是配置描述符,关系到上面所说的,你的设备有几个接口,是什么接口,要使用什么样的端点,端点配置又是怎样。当然,之前看资料跟做项目时也发现,同一配置中可以有多个接口,但同一配置中的多个接口中的端点号是不可以复用的。

 

批量传输:

这个传输方式跟控制传输十分相似,但他更具有灵活性,并且,这里不是使用端点0,所以要有两个不同的端点去负责输入跟输出的控制,当然,如果你的设备只需要输入或者输出,那也是可以的,具体是怎样就要看对应要操作的协议了,这个批量传输就个实在的话,就是发送数据给主机,或者接收主机数据,但这个发送跟接收都是带应答的,至于怎样去应答,这个就不是我们去管的了,硬件会给我们处理掉。批量传输是好一些USB协议中的主要操作部分,如等下要说的SCSI协议,在数据传输方面就是通过批量传输来完成的。

 

中断传输和同步传输:

这个我比较少关注,但根据我的一些了解,中断传输是指在主机会在某个固定的时间内发送一个中断信号下去,从机在收到中断信号后自行去处理自己的动作,如HID协议中的鼠标,键盘等,会通过中断传输来检查当前的状态。同步传输的话就是一个数据传输的过程,但他是没有数据校验的,不管对不对,只管往前发送,这也使得数据传输量比较大,适用于音频,视频类的通信。

 

 

 

SCSI协议:

Scsi协议是U盘,读卡器这些大容量存储所使用的协议,整个协议是工作在批量传输的,分为输入跟输出两个方向,这里会切入到两个概念:CBW,CSW。当这些大批量设备传输完成了后,主机会识别到你当前的设备是大容量设备后,就会根据SCSI的协议来发送CBW包下来,CBW包可理解为主机的一个命令包,我们要去解释这个命令包去进行相应的处理,当数据处理完后,就要回复CSW,这相当于scsi协议的一个应答包,是对刚才CBW包的处理情况的一个回应。而我们对相应CBW包的处理将会成为我们的首要工作。

CBW包结构如下图:

 USB与SCSI_第1张图片

CSW包结构如下图:

 USB与SCSI_第2张图片

 

其中dCBWTagdCSWTag是一样的,他们就相当于判定当前的CBW包跟CSW包是不是一致的,而dCBWSignaturedCSWSignature则是CBW包跟CSW包的包头,由特定的字符组成,dCBWDataTransferLength则是此次数据传输的长度,如果这次数据传输的长度不够长了会怎么办,这个会在CSW包中的dCSWatrResidue中体现出来,dCSWatrResidue表示此次数据传输的数据量还缺多少。bmCBWFlags是这次CBW包所要求的数据传输方向,说白了就是到底是主机发数据下来还是从机发数据上去。bCBWLUN代表当前要操作的逻辑单元,假设你当前要做一个双盘符的大容量设备,那我们CBW下来后我从机必需要知道你是在操作哪一个逻辑单元,而这个就体现在bCBWLUN中,而这个的数目会在大容量设备枚举的最后阶段中一个get max lun的控制传输命令中,由从机回复给主机,跟主机说:老子有多少个逻辑单元,后面的操作你给我好好地区分好。于是在后面的操作中,CBW就会乖乖地给你区分好要操作的逻辑单元是哪个了。CBW中的bCBWCBLength,这个看名字也看得出来了,我就不说了,最后就还有一个CSW包的bCSWStatus,这个是当前CBW包的应答状态,如果应答一切正常,那OK,这里就填0,否则为1.

 

当我们接收到CBW包后,我们要做的事情就是去解释,CBW包的CBWCB就是我们所要提取的信息所在,而CBWCB中,我们所提取的第一个信息是此包要我们做什么,我这里以读命令为例大概说一下:

 USB与SCSI_第3张图片

CBWCB中,我们首先关注的是operation code,这个是决定了我们自己到底要做些什么操作,然后也决定了cbwcb跟后的数据格式是怎样分布的,这里,他的第25位是要告诉从机,你要操作的是哪个逻辑地址,78位是跟从机说,你要操作的这个逻辑地址长度是多长,结合28h是个读命令,我们不难得出,这是主机要求我们从某一个逻辑地址中读取某一长度的数据。这样,我们跟下来的操作就是通过USB的批量传输,将对应的数据发送到主机上去,然后回CBW包,那这个读操作就算是完成了。

 

当然,在这里还有很多种CBWCB的命令,我们以operation code的不同来讲解其中几种比较重要的命令

00h:这个是test ready命令,在PC上,我们如果枚举正常,信息读写正常,空闲的时候,主机就会发送test ready命令下来,这个命令不用回复跟应答数据,只要回复个CBW即可,那有人就会说,这样有什么用?不急,先看完下面几个命令后再跟你讲解。

03h:这个是REQUEST SENSE命令,如果我们的设备出现CBW应答异常,那主机会发这个命令下来去检查设备的状态,而这个命令是要求我们从机返回当前设备状态的命令。

1ah:这个也是一个状态命令MODE SENSE,但这个跟前面的读取设备状态不一样,这个是判定当前设备是不是处于写保护的状态,如果是的话,那对于写操作,主机都不会发下来的。

12hInquiryData命令,这个命令对于设备来说是很重要的,为什么这样说,那是因为,你的设备是大容量设备,但大容量设备可是有好几种耶,你是哪一种啊,U盘还是硬盘,或者说是CDROM,这都是要去让主机知晓的,那主机又是如何知晓?他其实就是发送个12h命令下来,然后我们就要回复这个设备的一些基本信息上去,这个命令的重要性不可仅仅如此,到下次我再去讲解。

23h:读取容量命令,这个是跟主机说,你的存储容量是多大,然后主机就会根据这个来进行数据的处理。

25h:作用跟23h基本相同。

28h:读命令,这个上面已作说明,不再解释。

2a:写命令,这个就是跟读是相对的,但结构上与读是一致的,没什么好说。。。。。。

 

重要的命令大概就是上面这几条了,当然,还有一些1bh,1eh等等,这些都是有自己对应的意义,好像你电脑想要让U盘脱盘,那主机也会发相应的命令下来,具体要怎样操作,可以通过Bushound来观察,结合scsi协议去了解,这里不一一解释。

 

到了这里,00h这个命令的重要性就可以很好地讲解了,因为这里有个03H是用来返回设备状态的,如果这个时候我们00hcsw包应答位bCSWStatus为异常,那我们主机一识别到异常后,就会发送03H下来,让我们从机返回一下自己的状态,这样就会让从机去进行一些状态切换,不明白?举个例,一个读卡器,我插上卡跟不插上卡,他的状态是完全不一样的,一个的状态是有操作设备的状态,一个是没操作设备的状态,如果我们刚开始的读卡器是插上设备的,但后机我要换卡,我没把读卡器拔出来,只是把卡拔出来换卡,那这个时候,这个状态的转换就很重要了,所以简单点理解的话,00h就是一直在判定当前的状态是不是正常的。空闲时发送频率会是1S左右一次

 

好了,这次就说这些了,有时间把U盘的管理算法也给写出来给大家了解一下。

 

最后的最后,如有什么不同的意见和看法,请多加指点,共同进步,谢谢^-^


           by:静下来

      2015.1.7

你可能感兴趣的:(USB与SCSI)