Use Mass Storage class as a driver-free USB device.

Source: Internet
Author: User

If you want to use USB bulk for transmission and want devices to communicate with PC hosts like serial communication, you usually need to build a PC-side driver, which is troublesome.

To avoid the trouble of writing a USB device driver on a PC, you can make the device into a mass storage device and use a general driver.

Before communication, the device must do two things:

1. Implement the descriptor and class request of the Mass Storage Class.

2. Implement the necessary SCSI commands to make the PC think the device is operating normally.

 

I made a simple device by modifying the gadget zero device in Linux. If it is done under a bare metal program, it should be similar. Just change it with the USB sample program in the chip vendor BSP.

  

  

  

1. Implement the descriptor and class request of the Mass Storage Class.

Mass Storage

Corresponding code in Linux:

1) device descriptor

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,};

There is nothing special about the device descriptor, because the PC-side USB driver corresponds to the device interface and the Mass Storage Class corresponds to the interface descriptor.

2) interface Descriptor

/* SCSI device types */#define TYPE_DISK0x00#define TYPE_CDROM0x05/* USB protocol value = the transport method */#define USB_PR_CBI0x00/* Control/Bulk/Interrupt */#define USB_PR_CB0x01/* Control/Bulk w/o interrupt */#define USB_PR_BULK0x50/* Bulk-only *//* USB subclass value = the protocol encapsulation */#define USB_SC_RBC0x01/* Reduced Block Commands (flash) */#define USB_SC_80200x02/* SFF-8020i, MMC-2, ATAPI (CD-ROM) */#define USB_SC_QIC0x03/* QIC-157 (tape) */#define USB_SC_UFI0x04/* UFI (floppy) */#define USB_SC_80700x05/* SFF-8070i (removable) */#define USB_SC_SCSI0x06/* Transparent SCSI *//* Bulk-only class specific requests */#define USB_BULK_RESET_REQUEST0xff#define USB_BULK_GET_MAX_LUN_REQUEST0xfestatic 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 */};

Complies with USB Mass Storage specifications. Corresponding table

The SCSI command set is used for bulk-only transmission.

3) implement a Mass Storage Class request

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);

A simple 0 is returned.

In Linux, requests such as obtaining descriptors are put together in composite. C, and requests of different devices are put in the xxx_setup function of their respective interfaces in f_xxx.c.

 

After the above Descriptor and class request are implemented, connect the embedded device to the computer, and Windows will list the USB mass storage device in the Device Manager. However, there is a yellow exclamation point.

According to the USB packet capture situation, after the computer driver fails to send the SCSI command for several times, the enumeration process will be re-performed. If the device is abnormal for several times, the device will be considered abnormal.

 

2) Necessary SCSI commands

Process the following commands sent by the mass storage PC driver.

# Define SC _inquiry 0x12

# Define SC _test_unit_ready 0x00

# Define SC _read_capacity 0x25
# Define SC _read_format_capacities 0x23

The first two must be required, and the last two are added. If you do not delete them, no test is performed.

These commands can be placed in the Linux gadget driver or in the Application Layer Program for processing.

The process is as follows:

Receive SCSI commands -----> process SCSI commands -----> return status

Basically according to the SCSI protocol

CBW: Command block wrapper command block Packet

CSW: command status wrapper Command Execution status

Define struct according to the CBW and CSW formats:

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;};

 

Take the SC _inquiry command as an example.

When my program receives the 0x12 command, it will be processed according to the specification in the SCSI protocol. I need to return the data in the following table format to the host.

 

.

The last five digits of the first byte determine whether the host is recognized as a cdrom, a removable disk, or another type of device.

RMB indicates whether a device can be removed.

Additional length (n-4) needs to be filled.

Others can be entered as needed.

 

Then return the CSW status:

Dcswsignature is fixed to 0x53425355,

Dcswtag is the same as that sent by CBW,

Dcswdataresidue is equal to the difference between the length and the actual length of the CBW.

Bcswstatus indicates that the command succeeded or failed, 0 indicates that the command succeeded, and other values indicate that the command failed.

 

In addition, this command

# Define SC _test_unit_ready 0x00

The host will not stop sending messages during idle time. if the CSW returned by this command is successful, the host uses the read_format_capacities command to query the formatted capacity and read (10) the file system information. if the correct information is not obtained, Windows will pop out the dialog box and ask if you want to format it.

Because I do not really need to create a USB flash disk or other devices, so 0x00 command, I CSW directly returns 1. in this way, when you click the drive letter of the device, it will prompt that no device is inserted. this has no impact on me. I only use the mass storage shell for communication. I just cheated on the standard drive of mass storage.

 

Now I can use custom SCSI commands or rewrite Standard Commands for communication.

 

 

 

 

 

 

  

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.