利用mass storage class 做免驱动usb设备.

  当需要使用usb bulk传输,想让设备像串口通讯那样和PC主机通信, 通常需要自己做一个PC端的驱动,比较麻烦.

  为避免在pc上编写usb设备驱动的麻烦,可以将设备做成mass storage 类的设备,使用通用的驱动.

  在通讯之前设备端需要先做两件事:

  1,实现mass storage 类的描述符和类请求.

  2,实现必要的SCSI命令,让PC认为该设备已正常运作.

我利用修改linux中的gadget zero设备做了一个简单的设备. 如果是在裸机程序下面做,应该也差不多,直接拿芯片厂商BSP中的USB样例程序修改即可.

  

  

  

1实现mass storage 类的描述符和类请求.

mass storage

在linux中对应代码:

1)设备描述符

static struct usb_device_descriptor device_desc = {
	.bLength =		sizeof device_desc,
	.bDescriptorType =	USB_DT_DEVICE,

	.bcdUSB =		cpu_to_le16(0x0200),
//	.bDeviceClass =		USB_CLASS_VENDOR_SPEC,
	.bDeviceClass =		USB_CLASS_PER_INTERFACE,

	.idVendor =		cpu_to_le16(DRIVER_VENDOR_NUM),
	.idProduct =		cpu_to_le16(DRIVER_PRODUCT_NUM),
	.bNumConfigurations =	1,
};

设备描述符没什么特殊的,因为PC端usb驱动是与设备的接口对应的,与mass storage class对应的是接口描述符

2)接口描述符

/* SCSI device types */
#define TYPE_DISK	0x00
#define TYPE_CDROM	0x05

/* USB protocol value = the transport method */
#define USB_PR_CBI	0x00		/* Control/Bulk/Interrupt */
#define USB_PR_CB	0x01		/* Control/Bulk w/o interrupt */
#define USB_PR_BULK	0x50		/* Bulk-only */

/* USB subclass value = the protocol encapsulation */
#define USB_SC_RBC	0x01		/* Reduced Block Commands (flash) */
#define USB_SC_8020	0x02		/* SFF-8020i, MMC-2, ATAPI (CD-ROM) */
#define USB_SC_QIC	0x03		/* QIC-157 (tape) */
#define USB_SC_UFI	0x04		/* UFI (floppy) */
#define USB_SC_8070	0x05		/* SFF-8070i (removable) */
#define USB_SC_SCSI	0x06		/* Transparent SCSI */

/* Bulk-only class specific requests */
#define USB_BULK_RESET_REQUEST		0xff
#define USB_BULK_GET_MAX_LUN_REQUEST	0xfe

static struct usb_interface_descriptor source_sink_intf = {
	.bLength =		sizeof source_sink_intf,
	.bDescriptorType =	USB_DT_INTERFACE,

	.bNumEndpoints =	2,
//	.bInterfaceClass =	USB_CLASS_VENDOR_SPEC,
	.bInterfaceClass =	USB_CLASS_MASS_STORAGE,
	.bInterfaceSubClass =	USB_SC_SCSI,
	.bInterfaceProtocol =	USB_PR_BULK,
	/* .iInterface = DYNAMIC */
};

符合usb mass storage 类规范。对应下表

使用SCSI命令集,协议实现是Bulk-Only 传输。

3)实现一个mass storage 类的请求

	case USB_BULK_GET_MAX_LUN_REQUEST:
		printk("USB_BULK_GET_MAX_LUN_REQUEST\n");
		if (ctrl->bRequestType !=
		    (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE))
			break;
		*(u8 *) req->buf = 0;

		/* Respond with data/status */
		req->length = min((u16)1, w_length);
		value = usb_ep_queue(f->config->cdev->gadget->ep0, req, GFP_ATOMIC);
		if (value < 0)
			ERROR(f->config->cdev, "source/sinkc response, err %d\n",
					value);
		return(value);

简单返回了一个0。

在linux中,linux把一些诸如获取描述符之类的请求集中在了一起放在了composite.c 中,不同设备类请求放在各自个f_xxx.c中各自的接口的xxx_setup函数中。

当实现了以上描述符和类请求之后,把嵌入式设备接上电脑,windows就会在设备管理器中列出usb mass storage设备。不过有一个黄色感叹号。

根据usb抓包情况来看是,电脑上面驱动发送SCSI命令数次不成功之后,会重新枚举过程,数次不正常之后就会认为该设备不正常。

2)必要的SCSI命令

大概要处理mass storage pc端驱动发过来的一下命令

#define SC_INQUIRY   0x12

#define SC_TEST_UNIT_READY  0x00

#define SC_READ_CAPACITY  0x25
#define SC_READ_FORMAT_CAPACITIES 0x23

前两条应该是必须的,后两条我也给加上了,去掉行不行,没有测试。

这些命令即可以放到linux gadget driver中也可以放到应用层程序中处理. 我是放到了应用层.

处理的流程基本是:

接收SCSI命令----->处理SCSI命令----->返回状态

基本是按照SCSI协议进行

CBW:Command Block Wrapper   命令块数据包

CSW:Command Status Wrapper  命令执行状态

按照CBW和CSW格式定义结构体:

struct ms_cbw_struct{
	u32 dCBWSignature;
	u32 dCBWTag;
	u32 dCBWDataTransferLength;
	u8 bmCBWFlags;
	u8 bCBWLUN;
	u8 bCBWCBLength;
	u8 CBWCB[SCSI_CMD_MAX_LEN];
};

struct ms_csw_struct{
	u32 dCSWSignature;
	u32 dCSWTag;
	u32 dCSWDataResidue;
	u8 bCSWStatus;
};

以SC_INQUIRY   命令为例

当我程序收到 0x12 命令,我就要按照scsi协议中该命令的规范来处理,我需要返回下面表格格式的数据给主机

.

第一个字节后5位决定了主机识别成一个cdrom或是可移动盘或其他类型的设备.

RMB表示是否是一个可以移除设备.

Additional length (n-4)  需要填写.

其他的可根据需要填写.

之后返回状态CSW:

dCSWSignature固定为0x53425355,

dCSWTag 与CBW发过来的相同,

dCSWDataResidue等于CBW中要得长度和实际长度的差值.

bCSWStatus 表示命令成功或失败, 0表示成功,其他值表示失败.

另外这条命令

#define SC_TEST_UNIT_READY  0x00

是主机会在空闲时间不停发送的. 并且一开始连上主机,如果这条命令返回的CSW 成功,那么主机会使用READ_FORMAT_CAPACITIES 命令查询格式化的容量,read(10)读文件系统的信息. 如果得不到正确信息windows就会跳出对话框问你要不要格式化等等.

由于现在我并非真的需要做一个U盘之类的设备,所以0x00 命令,我CSW直接返回1. 这样当你点击该设备的盘符,就会提示说没有设备插入. 这对我没有影响,我只是用mass storage这个壳来进行通信的. 只是骗过mass storage的标准驱动而已.

现在我就可以通过自定义的SCSI命令或者改写标准的命令来进行通信了.

  

利用mass storage class 做免驱动usb设备.

时间: 2024-10-10 08:48:04

利用mass storage class 做免驱动usb设备.的相关文章

Linux下的硬件驱动——USB设备(转载)

usb_bulk_msg函数 当对usb设备进行一次读或者写时,usb_bulk_msg 函数是非常有用的; 然而, 当你需要连续地对设备进行读/写时,建议你建立一个自己的urbs,同时将urbs 提交给usb子系统. 转载于此http://os.chinaunix.net/a2003/0630/1056/000001056933.shtml Linux下的硬件驱动——USB设备(上)(驱动配置部分) USB设备越来越多,而Linux在硬件配置上仍然没有做到完全即插即用,对于Linux怎样配置和

如何实现Linux下的U盘(USB Mass Storage)驱动

摘要 本文主要介绍了USB Mass Storage的相关的各种协议之间的关系,以及如何在Linux的USB驱动框架下实现U盘驱动 本文提供多种格式供: 在线阅读 HTML HTMLs PDF CHM TXT RTF 下载(7zip压缩包) HTML HTMLs PDF CHM TXT RTF HTML版本的在线地址为: http://www.crifan.com/files/doc/docbook/usb_disk_driver/release/html/usb_disk_driver.htm

实现Linux下的U盘(USB Mass Storage)驱动

如何实现Linux下的U盘(USB Mass Storage)驱动 版本:v0.7 How to Write Linux USB MSC (Mass Storage Class) Driver Crifan Li 摘要 本文主要介绍了USB Mass Storage的相关的各种协议之间的关系,以及如何在Linux的USB驱动框架下实现U盘驱动 本文提供多种格式供: 在线阅读 HTML HTMLs PDF CHM TXT RTF WEBHELP 下载(7zip压缩包) HTML HTMLs PDF

USB mass storage协议

这一节主要把在实现“linux模拟U盘功能”过程中的一些调试过程记录下来,并加以解析. 一.背景知识     1.USB Mass Storage类规范概述        USB 组织在universal Serial Bus Mass Storage Class Spaceification 1.1版本中定义了海量存储设备类(Mass Storage Class)的规范,这个类规范包括四个         独立的子类规范,即:        1. USB Mass Storage Class

USB Mass Storage大容量存储的基本知识

http://www.crifan.com/files/doc/docbook/usb_disk_driver/release/htmls/ch02_msc_basic.html 目录 2.1. USB Mass Storage相关的协议 2.1.1. USB Mass Storage相关协议简介 2.1.1.1. USB MSC Control/Bulk/Interrupt (CBI) Transport 2.1.1.2. USB MSC Bulk-Only (BBB) Transport 2

Android USB Connections Explained: MTP, PTP, and USB Mass Storage

Android USB Connections Explained: MTP, PTP, and USB Mass Storage Older Android devices support USB mass storage for transferring files back and forth with a computer. Modern Android devices use the MTP or PTP protocols — you can choose which one you

USB Mass Storage协议分析

目录 简介 指令数据和状态协议 CBW指令格式 CSWCommand Status Wrapper状态格式 SCSI命令集 Format Unit Inquiry MODE SELECT 简介 USB Mass storage Device协议即海量存储设备协议适用于硬盘,U盘等大容量存储设备.协议使用的接口端点有BulkIn.BulkOut和Interrupt端点.该设备类又包含6个独立的子类以及3种传输协议. bInterfaceSubClass 命令集 描述 01h RBC 通常,Flas

USB设备驱动概述

USB设备驱动 ·  17.1 USB总线协议 ·  17.1.1 USB设备简介 ·  17.1.2 USB连接拓扑结构 ·  17.1.3 USB通信的流程 ·  17.1.4 USB四种传输模式 ·  17.2.1 观察USB设备的工具 ·  17.2.2 USB设备请求 ·  17.2.3 设备描述符 ·  17.2.4 配置描述符 ·  17.2.5 接口描述符 ·  17.2.6 端点描述符 ·  17.3.1 功能驱动与物理总线驱动 ·  17.3.2 构造USB请求包 ·  17

USB Mass Storage学习笔记-STM32+FLASH实现U盘

一.内容概述 采用STM32内部自带USB控制器外加大页NAND FLASH K9F1G08U0A实现一个128M的U盘. 1.STM32的USB控制器 STM32F103的MCU自带USB从控制器,符合USB规范的通信连接:PC主机和微控制器之间的数据传输是通过共享一专用的数据缓冲区来完成的,该数据缓冲区能被USB外设直接访问.这块专用数据缓冲区的大小由所使用的端点数目和每个端点最大的数据分组大小所决定,每个端点最大可使用512字节缓冲区,最多可用于16个单向或8个双向端点.USB模块同PC主