USB Mass Storage类规范概述 
       USB Mass storage Device协议即海量存储设备协议适用于硬盘,U盘等大容量存储设备。协议使用的接口端点有BulkIn、BulkOut和Interrupt端点。该设备类又包含6个独立的子类以及3种传输协议


  Bulk- Only 传输规范仅仅使用Bulk 端点传送数据/命令/状态,CBI 传输规范则使用Control/Bulk/Interrupt 三种类型的端点进行数据/命令/状态传送
  我们手中的U盘就是遵循SCSI协议的。要知道U盘不仅仅是USB设备,它还是一种存储设备,类似硬盘,USB协议本身没有定义对存储设备操作的指令,所以需要通过SCSI来完成读写等操作。

  Microsoft Windows 中提供对Mass Storage 协议的支持,因此USB 移动设备只需要遵循 Mass Storage 协议来组织数据和处理命令,即可实现与PC 机交换数据。而Flash 的存储单元组织形式采用FAT16 文件系统,这样,就可以直接在Windows的浏览器中通过可移动磁盘来交换数据了,Windows 负责对FAT16 文件系统的管理,USB 设备不需要干预FAT16 文件系统操作的具体细节。

  USB成功枚举之后会在设备管理器上面显示USB MassStorage Device(且带有黄色感叹号),否则会显示unknow device,而只有在进行UFI(具体是在inquiry命令之后)通讯之后主机才会显示盘符,且本来在设备管理器中USB MassStorage Device上的黄色的感叹号消失。

  因为这个时候USB设备已经枚举成功(主机发送的GetDescriptor、SetAddress等之类的请求都回复成功才能正确的枚举),所以可以通过BusHound来查看在USB UFI Command的情况,USB设备的枚举都是通过端点0来实现,而USB UFI Command都是通过端点1来实现,所有的命令的数据流都在端点1。除了BusHound之外,还有很多查看USB总线数据的软件,例如USB View等,查看Flash数据的软件有winhex。

  枚举过程CATC仪器抓取数据的文件:http://download.csdn.net/detail/luckywang1103/6315437      usbUFI.usb

1、GetMaxLun(0xFE)

1)Setup Stage

2)Data Stage

3)Status Stage

以上这个阶段对应的程序是

case GetMaxLun:
        //实际上对U盘来说,忽略该步骤也没有影响
        //要求设备返回一个字节给主机,以表明USB设备有多少个
        //逻辑设备,返回的数据就是这个最大设备逻辑号(0到15)
        //如果返回2,代表有0、1、2三个逻辑设备
        SFR_Write(FIFO0,0x00);
        SFR_Write(E0CSR,0x0a);
break;

接下来开始在端点1进行UFI Command传输

UFI Command构成如下:CBW—>数据—>CSW,三个阶段

CBW:Command Block Wrapper   命令块数据包

CSW:Command Status Wrapper  命令执行状态

 

2、Inquiry Command(0x12)

1)CBW

主机在端点1所发出的UFI Command的DATA0数据可以对照图Table 5.1进行解析。

dCBWSignature:55 53 42 43        help identify this data packet as CBW

dCBWTag:90 C8 E8 88                  Command Block Tag send by host

dCBWDataTransferLength:24 00 00 00        data numbers that host expect to transfer on the Bulk-In or Bulk-Out endpoint

剩余的12 Bytes就是CBWCB:12 00 00 00 24 00 00 00 00 00 00 00

CBWCB(CBW里面的command block)12个字节的解析参考《USB Mass Storage Class-UFI Command Specification》

12:Inquiry Command

24:Allocation Length    specifies the maximum number of bytes of inquiry data to be returned,数据阶段最大传送36 Bytes

2)Data In

这36 Bytes是按照Inquiry data的格式要求返回的,具体协议数据的分析参考《USB Mass Storage Class-UFI Command Specification》

3)CSW

dCSWSignature:55 53 42 53     help identify this data packet as CSW

dCSWTag:90 C8 EB 88      CSW的这个字段同CBW的dCBWTag字段

3、Read_Format_Capacity(0x23)

1)CBW

2)Data

3)CSW

4、Read_Capacity(0x25)

1)CBW

2)Data

3)CSW

5、Read_10(0x28)

上面几个请求如果均正确返回,Host会发出Read读文件系统0簇0扇区的DBR数据,进入文件系统识别阶段。

1)CBW

2)Data

3)CSW

6、ModeSense6(0x1A)

1)CBW

2)Data

3)CSW

7、重复第6步,ModeSense6(0x1A)

8、重复第4步,Read_Capacity(0x25)

9、重复第4步,Read_Capacity(0x25)

10、重复第5步,Read_10(0x28)

11、重复第5步,Read_10(0x28)

12、重复第4步,Read_Capacity(0x25)

13、重复第4步,Read_Capacity(0x25)

14、重复第5步,Read_10(0x28)

15、Test Unity Ready(0x00)

1)CBW

3)CSW

16、重复第4步,Read_Capacity(0x25)

17、重复第4步,Read_Capacity(0x25)

18、重复第4步,Read_Capacity(0x25)

19、重复第5步,Read_10(0x28)

20、接下来一直会重复Test Unity Ready(0x00)

说明:

MASS Storage设备所使用的SCSI命令集

0x00: testUnityReady
0x03: Request Sense

0x12: Inquiry

0x1A: ModeSense6

0x1B: StartStop

0x1E: MediumRemoval

0x23: ReadFormatCapacity

0x25: ReadCapacity

0x28: Read10

0x2A: Write10

0x2F: Verify

0x5A: ModeSense10

主机首先发出Inquiry命令,响应了Inquiry之后就可以看到盘符.

Inquiry之后会发出ReadFormatCapacity命令,这个命令在SCSI规范中是“厂家自定义命令”,可以参考UFI命令集文档(实际上,U盘所使用的所有SCSI命令集都可以参考UFI文档,它比SCSI标准文档更简洁明了)。注意这个命令在BusHound里是没有描述的,必须在“Device”选项页里勾选上这个U盘所对应的USB Mass Storage Device这个节点,才能看到这个命令的数据流。

ReadFormatCapacity之后会发出ReadCapacity命令。

U盘读数据(读扇区)时会发送Read(10)。ReadCapacity完成后就会发送Read(10)读取U盘的第一个扇区。

U盘写数据时(写扇区)会发送Write(10)。

TestUnitReady会在无其他数据传输时会定时发送,如果设备没有回应成功的CSW给主机,则主机认为设备已不存在。此时如果再双击磁盘图标,Windows会提示“请插入磁盘”。

Verify在写数据时有用,表示核实数据,一般直接返回成功的CSW就可以了。一般来说,数据校验的工作在接收和向介质写数据时就已经顺带做了,如果发现错误,则直接告诉主机那次的数据传输有误,不会等到主机Verify时。当然,这不是一个必然的方案。

RequestSense:如果CSW指示此次传输不成功,那么主机会发出此请求。

StartStop暂时未发现大用处,一般直接返回成功的CSW。

MediumRemoval在U盘被Eject的时候有用,处理不正确会Windows会弹出错误信息。

ModeSense6/10这两个命令可以不支持(不支持不代表不反应,任何一个命令你都要做出反应,对于不支持的命令,可以通过STALL握手来向主机表明),暂时也未遇到过什么异常情况,而且我查看过一些U盘,有相当一部分就是随便回了几个数据给主机。这两个命令只会在U盘插入后发送一次,此后不再发送。

电子工程师名片——UFI Command,USB盘符的显示的更多相关文章

  1. 电子工程师名片——FAT16文件系统(转)

    源:电子工程师名片——FAT16文件系统 从8月8号开始,连续一个月利用每天下班时间和周末的时间终于初步完成了一个电子工程师的电路板名片,就像U盘一样,不过这个FLASH只有64KB的大小,用的单片机 ...

  2. java显示本地磁盘所有盘符,显示桌面路径

    import java.io.File; import javax.swing.filechooser.FileSystemView; /** 显示本地磁盘根盘符,显示桌面路径 */ public c ...

  3. 电子工程师名片——FAT16文件系统

    从8月8号开始,连续一个月利用每天下班时间和周末的时间终于初步完成了一个电子工程师的电路板名片,就像U盘一样,不过这个FLASH只有64KB的大小,用的单片机是C8051F320,是一个USB型的单片 ...

  4. 电子工程师名片——SPI NOR Flash

    使用了MX25L512的SPI接口的Flash 电路连接图: 总的大小512kb,即64kB,sector的大小为256 Bytes,block的大小为4k Bytes 调试时出现的问题: 1.Fla ...

  5. 让虚拟机的软盘盘符不显示(适用于所有windows系统包括Windows Server)

  6. Win10 隐藏盘符

    1.隐藏盘符 打开磁盘管理 -> 对要隐藏的盘符单击右键 -> 更改驱动器号和路径 -> 删除. 打开资源管理,已经看不到该盘符,该盘符已被隐藏.只是隐藏,该盘符上的数据仍然还在. ...

  7. 真相:中国版BBB用USB连电脑没有盘符的根本原因分析

    很多网友在问:为什么中国版的装完驱动插上板子没有显示端口号和69M的盘符??楼主发现,在开机启动的时候,加载g_multi模块时出现错误提示 invalid argument.         Emb ...

  8. Windows下USB磁盘开发系列一:枚举系统中U盘的盘符

    个时候我们需要区分系统磁盘中,哪些是U盘,这样我们在访问的时候可以区别对待.具体方法如下: 1,调用GetLogicalDrives()返回系统盘符标记位 API GetLogicalDrives() ...

  9. 外网远程顶级域名连接群晖的WebDAV文件服务映射盘符

       外网远程顶级域名连接群晖的WebDAV文件服务映射盘符 https://www.cnblogs.com/delphixx/p/11846546.html 电子文件管理规范   1.手机拍照截屏 ...

随机推荐

  1. Android 隐藏输入软键盘

    //隐藏输入键盘 ((InputMethodManager)getSystemService(INPUT_METHOD_SERVICE)) .hideSoftInputFromWindow(BshTo ...

  2. cf C. Tourist Problem

    http://codeforces.com/contest/340/problem/C #include <cstdio> #include <cstring> #includ ...

  3. Ghost源代码

    http://download.csdn.net/download/xiaoshuai0101/4739231 彻底的掩藏磁盘,让病毒和破坏的人没有一点办法上传者 guizhoutiger

  4. 【转】(总结)Linux下su与su -命令的本质区别

    原文网址:http://www.ha97.com/4001.html 本人以前一直习惯直接使用root,很少使用su,前几天才发现su与su -命令是有着本质区别的! 大部分Linux发行版的默认账户 ...

  5. VC++ 2013 开发windows窗体程序

    开发工具版本:Visual Studio Express 2013 for Windows Desktop 1. 新建Visual C++下面的"Win32 Project" 2. ...

  6. SICP 练习 1.3

    (define (sum a b) (+ a b)) (define (sum-two a b c) ( cond ((and (> (sum a b) (sum a c)) (> (su ...

  7. Factorials 阶乘

    Description N的阶乘写作N!表示小于等于N的所有正整数的乘积.阶乘会很快的变大,如13!就必须用32位整数类型来存储,70!即使用浮点数也存不下了.你的任务是找到阶乘最后面的非零位.举个例 ...

  8. What’s the difference between an interface and an abstract class in Java?

    原文 What’s the difference between an interface and an abstract class in Java? It’s best to start answ ...

  9. C++小知识之sprintf用法

    sprintf   字串格式化命令,主要功能是把格式化的数据写入某个字符串中.sprintf 是个变参函数,使用时经常出问题,而且只要出问题通常就是能导致程序崩溃的内存访问错误,但好在由sprintf ...

  10. 表单javascript checkbox全选 反选 全不选

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...