4.USB详解(U盘)

1.简介

  前面我们介绍了USB的枚举,还没真正与产品挂钩,生活中常用的USB设备大家都很熟悉,键盘、鼠标、U盘,USB设备分为5大类:显示器、通信设备、音频设备、人机输入、海量存储。今天我们来看下U盘的使用,即海量存储设备,在4种传输方式中使用批量传输方式。

2.U盘(mass storage device)

2.1 描述符

  在USB协议中规定了大容量存储设备,大容量设备有很多种,U盘就是其中一种,bInterfaceClass字段为0x08,bInterfaceSubClass有好几种,但大部分U盘都使用0x06,即SCSI命令集,bInterfaceProtocol字段有3种:0x00、0x01、0x50,前两种需要使用中断传输,最后一种使用批量传输,一般使用批量传输。用描述符软件查看U盘如下所示,关键字段用了红色方框:
在这里插入图片描述

2.2 类特殊请求

  U盘枚举的时候除了有前面说到的标准设备请求外,在Bulk-Only协议中定义了两个类特殊请求:Bulk-Only Mass Storage ResetGet Max LUN。前者是复位到命令状态的请求,后者是获取最大逻辑单元请求。

2.2.1 Bulk Only Mass Storage Reset

在这里插入图片描述

2.2.2 Get Max LUN

在这里插入图片描述

2.2.3 伪代码

  接上一节的控制传输流程添加代码:

//控制传输流程
void usb_control_transmit()
{
	usb_ctl_req req;
	static int state;
	
	if(state == 建立过程){
		//读8个字节长度请求
		usb_read_ep0(&req, 8);
		
		switch(req.bmRequestType & 0x1f){
			case DEVICE:
				SET_ADDRESS:
					结束流程,没有数据过程;
					break;					
				
				GET_DESCRIPTOR:
					设备、配置、接口描述符;
					state = 数据过程;
					break;
				
			case INTERFACE:
				switch(req.bmRequestType & 0x60){
                    case Standard:
						break;
					
					case Class:
						switch (req.bRequest){
							case Bulk Only Mass Storage Reset:
								初始化端口状态,准备接收命令。
							break;
							
							case Get Max LUN:
							    返回最大逻辑单元。
							break;
							
							default:
							break;
						} 
						break;

					default:
						break;	
                }
				break;
				
			case ENDPOINT:
				break;
				
			default:
				break;
		}	
	}else if(数据过程){
		发送数据/接收数据;
		数据发送完成/接收完成结束;
	}
}

2.3 Bulk-Only

  在接口协议类型中指定了协议使用批量传输Bulk-Only,Bulk-Only协议也有像控制传输的三个过程:命令阶段、数据阶段、状态阶段(相当于封装了3个批量传输),在命令阶段使用命令块封包CBW(Command Block Wrapper),在状态阶段使用CSW(Command Status Wrapper)来回复,它们的格式如下所示:
在这里插入图片描述
在这里插入图片描述

2.4 SCSI

  我们知道了传输协议Bulk-Only,但还需要知道传输协议的格式scsi是如何的(虽然在接口子类定义的是SCSI,但实际上是使用UFI命令集),U盘中常用的只有几个:INQUIRY、READ CAPACITY、READ、WRITE等。

2.4.1 INQUIRY

命令请求目标设备的一些基本信息。

2.4.2 READ FORMAT CAPACITIES

表示设备智齿最大的格式化容量,容量=块数*每块字节数,通常每块字节数为512。

2.4.3 READ CAPACITY

读容量命令可以让主机读取到当前存储媒介的容量。

2.4.4 READ(10)

读出取存储设备数据。

2.4.5 WRITE(10)

写入存储设备数据。

2.4.6 REQUEST SENSE

用来探测上一个命令执行失败的原因,主机可以在每个命令之后使用该命令来读取命令执行情况。

2.4.7 TEST UNIT READ

TEST UNIT READY命令用来测试设备的某个逻辑单元是否准备好,如果准备好则在状态阶段返回执行成功,如果没准备好则返回执行失败,当主机使用REQUEST SENSE命令来探测错误原因的时候,设置Sense Key为NOT READY。

2.4.8 伪代码

void mssstorage_device(){
	//1.获取cbw,31字节
	cbw = get_cbw();

	//2.判断操作码
	switch(cbw.optcode){
		case INQUIRY:
			break;

		case READ FORMAT CAPACITIES:
			break;

		case READ CAPACITY:
			break;
		
 		case READ10:
 			break;
 
 		case WRITE10:
 			break;
 			
 		case REQUEST SENSE:
 			break;
 		
 		case TEST UNIT READ:
 			break;

		default:
			break;
	}
	
	//3.发送csb
	send_csb(csb);
}

3.参考文档

USB官网:https://www.usb.org/
usbmass-ufi10.pdf
usbmassbulk_10.pdf

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值