📄 massstorage.dir
字号:
lowest address, and the Least Significant Bit (LSB) at the highest one.
On ARM Thumb microcontrollers, the endianness of the core is selectable.
However, the little-endian mode is most often used. Therefore, SCSI command
data must be converted before being usable. This is done by declaring
word- and dword-sized fields as byte arrays, and then using a macro for
loading or storing data. Several of them are available in the provided
software:
- Load
- WORDB: Converts a big-endian word value to little-endian
- DWORDB: Converts a big-endian double-word value to little-endian
- Store
- STORE_WORDB: Stores a little-endian word value in big-endian format
- STORE_DWORDB: Stores a little-endian double-word value in big-endian format
!Sense Data
When an error happens during the execution of a command, it is recorded by the
device. The host may then issue a Request Sense command to retrieve
#Sense Data#, i.e., information about previous errors.
While the sense data structure has many fields, only three are really
important. The first one is the Sense Key. It indicates the result of the last
command performed: success, media not ready, hardware error, etc. Two other
fields can then be specified to give a more accurate description of the
problem. They are named }Additional Sense Code} and }Additional Sense Code
Qualifier}.
In the example application, each LUN has its own sense data. It is updated
during command execution if there is any error.
!Commands
The SBC-3 specification gives a list of mandatory and optional commands that
are relevant for a block device (like a Flash drive). In practice, only a
subset of the mandatory commands is effectively used by operating systems;
conversely, several commands which are supposed to be optional are required.
The software provided with this application note implements the following list
of commands:
- SBC-3
- Prevent/Allow Medium Removal
- Read (10)
- Read Capacity (10)
- Verify (10)
- Write (10)
- SPC-4
- Inquiry
- Mode Sense (6)
- Request Sense
- Test Unit Ready
The commands are actually processed in SBC_ProcessCommand.
}Internal State Machine}
As previously stated, most commands have an internal state machine to prevent
blocking the whole system during a data transfer (on the USB or when accessing
a media). A result code is used to indicate that the corresponding function
must be called again for the command to complete (MSDDriver_STATUS_SUCCESS).
A command state structure is used by the driver to record several parameters
during command processing:
\code
typedef struct {
MSDTransfer transfer; //!< Current transfer status
MSCbw cbw; //!< Received CBW
MSCsw csw; //!< CSW to send
unsigned char state; //!< Current command state
unsigned char postprocess; //!< Actions to perform when command is complete
unsigned int length; //!< Remaining length of command
} MSDCommandState;
\endcode
Note that the }state} field must be initialized when the command is first
called. A value of 0 means that no command is currently being executed.
For the commands descriptions and implementation, please reffer to the SCSI
spec. and source code.
Functions to handle SCSI commands:
- SBC_Inquiry
- SBC_Read10
- SBC_ReadCapacity10
- SBC_RequestSense
- SBC_TestUnitReady
- SBC_Write10
- SBC_ModeSense6
!Command Processing
}Flow}
Command processing is actually divided into three phases in the example
software:
- Pre-processing: MSDDriver_PreProcessCommand
- Processing: MSDDriver_ProcessCommand
- Post-processing: MSDDriver_PostProcessCommand
}The Thirteen Cases}
There are basically three actions that should be performed depending on the
case:
- STALL the Bulk-IN endpoint
- STALL the Bulk-OUT endpoint
- Report a Phase Error in the CSW
The table below lists all cases along with the actions which must be taken
after the command, including the correct length/direction of the transfer. The
following notation is used to characterize host and %device expectations:
Data %Transfer Characterization
||Notation||Meaning||Notation||Meaning
|Hn|Host expects no data transfer|Dn|Device expects no data transfer
|Hi|Host expects to #receive# data|Di|Device expects to #send# data
|Ho|Host expects to #send# data|Do|Device expects to #receive# data
|Lh|Length of data expected by the host|Ld|Length of data expected by the %device
|Hx=Dx|Host and %device agree on transfer length and direction (x is either n, i or o)
|Hx>Dx|Host and %device agree on transfer direction, host expects a larger transfer than %device
|Hx<Dx|Host and %device agree on transfer direction, %device expects a larger transfer than host
|Hx<>Dx|Host and %device disagree on transfer direction
The Thirteen Cases
||\#||Case||Length||Residue||Direction||STALL IN?||STALL OUT?||Phase Error?
|1|Hn = Dn|0|0|Irrelevant| | |
|2|Hn < Di|0|Ld - Lh|Irrelevant| | |X
|3|Hn < Do|0|Ld - Lh|Irrelevant| | |X
|4|Hi > Dn|0|Lh|Irrelevant|X| |
|5|Hi > Di|Ld|Lh - Ld|In|X| |
|6|Hi = Di|Ld|0|In| | |
|7|Hi < Di|Lh|Ld - Lh|In| | |X
|8|Hi <> Do|0|0|Irrelevant|X| |X
|9|Ho > Dn|0|Lh|Irrelevant| |X|
|10|Ho <> Di|0|0|Irrelevant| |X|X
|11|Ho > Do|Ld|Lh - Ld|Out| |X|
|12|Ho = Do|Ld|0|Out| | |
|13|Ho < Do|Lh|Lh - Ld|Out| | |X
!!Main Application
After the MSD driver and the media have been initialized using the
corresponding functions, the only requirement for the main application is to
regularly call the state machine function. This is necessary for processing
received commands in a fully asynchronous way.
The application is otherwise free of doing any other task; for example, it
could implement a filesystem and a serial port interface to be accessed with a
standard terminal. An MP3 player could also continue playing a song while its
memory is accessed like an external hard disk.
\image MSDDriverClasses.png "Driver Class Diagram"
*/
/**
\page "USB MSD Basic"
This page gives generic details on the MSD class.
!!!Purpose
The MSD class defines how devices such as a hard disk, a USB floppy disk drive
or a disk-on-key shall operate on the USB. These devices are referred to as
mass storage devices, since they usually offer a high storage capacity. When
plugged to a PC, a %device complying to the MSD specification is accessed like
any other disk on the system.
In practice, the specification only defines a way to wrap existing data
transfer protocols, such as SCSI or the Reduced Block Commands (RBC) set. A
list of the supported protocols and their uses will be given in the following
section.
!!!Data Transfer Protocols
The }Mass Storagae Class Specification Overview 1.2} supports the following
set of %devices:
Protocols for MSD %devices
||Subclass Code||Command Block Spec.||Used by
|01h|Reduced Block Commands(RBC)|Flash %devices
|02h|SFF-8020i, MMC-2|CD & DVD %devices
|03h|QIC-157|Tape %devices
|04h|UFI|Floppy disk drives
|05h|SFF-8070i|Floppy disk drives
|06h|SCSI transparent command set|Any
The SCSI transparent command set comprises all SCSI-related specifications,
such as SCSI Primary Commands (SPC), SCSI Block Commands (SBC), and so on. A
command will be issued by the host to determine exactly with which standard
the %device is compliant.
The protocol used by the %device is specified in its Interface descriptor, in
the }bInterfaceSubclass} field.
!!!Transfer Protocols
There are actually two different transport protocols for the MSD class:
- Control/Bulk/Interface (CBI) transport
- Bulk-Only Transport (BOT)
These two methods are described in two separate stand-alone documents. CBI can
be considered obsolete and is being completely replaced by BOT. It was
originally targeted at full-speed floppy disk drives. Therefore, the rest of
this document will talk about Bulk-Only Transport exclusively.
Transport Protocol Codes
||bInterfaceProtocol||Protocol Implementation
|00h|Control/Bulk/Interrupt protocol (with command completion interrupt)
|01h|Control/Bulk/Interrupt protocol (without command completion interrupt)
|50h|Bulk-only transport
!!!Architecture
...
!!Interfaces & Endpoints
An MSD %device only needs one single interface. The bInterfaceClass field of
the interface descriptor should be set to MSD class code (0x08), the
corresponding data transfer protocol code in the }bInterfaceSubclass} field
and transport protocol code in the }bInterfaceProtocol} field can be found in
the tables on above.
Exactly three %endpoints (when using the Bulk-Only Transport protocol) are
necessary for MSD %devices.
The first one is the Control endpoint 0, and is used for class-specific
requests and for clearing Halt conditions on the other two %endpoints.
Endpoints are halted in response to errors and host bad behavior during data
transfers, and the CLEAR_FEATURE request is consequently used to return them
to a functional state.
The other two %endpoints, which are of type Bulk, are used for transferring
commands and data over the bus. There must be one Bulk-IN and one Bulk-OUT
endpoint.
\image MSDDriverArch.png "Mass Storage Device Driver Architecture"
!!Class-Specific Descriptors
No class-specific descriptors for an MSD %device using the Bulk-only transfport
protocol.
!!Class-Specific Requests
Two class specific requests should be handled.
!GetMaxLUN
A %device can feature one or more Logical Unit (LU). Each of these units will
be treated as a separate disk when plugged to a computer. A %device can have up
to 15 logical units.
The GET_MAX_LUN request is issued by the host to determine the maximum Logical
Unit Number (LUN) supported by the %device. This is not equivalent to the
number of LU on the %device; since units are numbered starting from 0, a %device
with 5 LUs should report a value of 4, which will be the index of the fifth
unit.
Optionally, a %device with only one LUN may STALL this request instead of
returning a value of zero.
!Bulk-Only Mass Storage Reset
This request is used to reset the state of the %device and prepare it to
receive commands and data. Note that the data toggle bits must not be altered
by a RESET command; same for the Halt state of %endpoints, i.e., halted
%endpoints must not be reset to a normal state.
!!Command/Data/Status
Each MSD transaction is divided into three steps:
- Command stage
- Data stage (optional)
- Status stage
During the command stage, a Command Block Wrapper (CBW) is transmitted by the
host to the %device. The CBW describes several parameters of the transaction
(direction, length, LUN) and carries a variable-length command block. The
command block contains data in the format defined by the transfer protocol
used by the %device.
Command Block Wrapper Data Format
||Offset||Field Name||Length||Comment
|0|dCBWSignature|4 bytes|Signature to identify CBW, must be 43425355h
|4|dCBWTag|4 bytes|Tag sent by the host, echoed in the CSW
|8|dCBWTransferLength|4 bytes|Length of transfer during the data stage
|12|bmCBWFlags|1 byte|Bits 0-6: Reserved/obsolete\n
Bit 7: Transfer direction (0 = OUT, 1 = IN)
|13|bCBWLUN|1 byte|Bits 0-3: LUN to which the command is sent\n
Bits 4-7: Reserved
|14|bCBWCBLength|1 byte|Bits 0-5: Length of command block in bytes\n
Bits 6-7: Reserved
|15|CBWCB|0-16 bytes|Command block to be executed by the %device
After the %device has received and interpreted the command, an optional data
stage may take place if the command requires it. During this step, data is
transferred either to or from the %device depending on the command, in several
IN/OUT transfers.
Once the data stage is complete, the host issues a final IN request on the
Bulk-IN endpoint of the %device to request the Command Status Wrapper (CSW).
The CSW is used to report correct or incorrect execution of the command, as
well as indicating the length of remaining data that has not been transferred.
Command Status Wrapper
||Offset||Field Name||Length||Comment
|0|dCSWSignature|4 bytes|Signature to identify CSW, must be 53425355h
|4|dCSWTag|4 bytes|Copy of previous CBW tag
|8|dCSWDataResidue|4 bytes|Difference between expected and real transfer length
|12|bCSWStatus|1 byte|Indicates the success or failure of the command
These steps are all performed on the two Bulk %endpoints, and do not involve
Control endpoint 0 at all.
!!Reset Recovery
When severe errors occur during command or data transfers (as defined in the
}Mass Storage Bulk-only Transport 1.0} document), the %device must halt both
Bulk %endpoints and wait for a #Reset Recovery# procedure. The Reset Recovery
sequence goes as follows:
- The host issues a Bulk-Only Mass Storage Reset request
- The host issues two #CLEAR_FEATURE# requests to unhalt each endpoint
A %device waiting for a Reset Recovery must not carry out CLEAR_FEATURE
requests trying to unhalt either Bulk endpoint until after a Reset request has
been received. This enables the host to distinguish between severe and minor
errors.
The only major error defined by the Bulk-Only Transport standard is when a CBW
is not valid. This means one or more of the following:
- The CBW is not received after a CSW has been sent or a reset.
- The CBW is not exactly 31 bytes in length.
- The dCBWSignature field of the CBW is not equal to 43425355h.
!!!Host Drivers
Almost all operating systems now provide a generic driver for the MSD class.
However, the set of supported data transfer protocols may vary. For example,
Microsoft Windows does not currently support the Reduced Block Command set.
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -