📄 periph_io_requests.htm
字号:
or failure) without requiring a context switch. In this situation the completion
routine is called
in the current context to process the request immediately. This was
designed to improve system performance. The developer should be aware that
issuing another request in a completion routine could cause a recursion, if
that request was completed immediately. The SDIO core, however, will take
some
measures
to
break the
recursion cycle and prevent a stack overflow.</p>
<p class="BODYTEXT">The completion routine for an asynchronous
transaction could be called from a non-preemptible
context. The driver should only issue asynchronous requests
and make calls to non-blocking API's. Drivers can safely recycle the bus
request back to the SDIO core in this context.</p>
<p class="HEADING3">SDIO CMD52 and CMD53:</p>
<p class="BODYTEXT">The SDIO core provides convenient methods for setting up
and issuing SDIO register read/write (CMD52) and extended read/write (CMD52)
commands. The core provides <font face="Courier New, Courier, mono"><a href="PD_Reference.htm#FUNC_SDLIB_IssueCMD52">SDLIB_IssueCMD52()</a>,</font> a
synchronous I/O method, that internally allocates a bus request, sets the
proper argument and flags, issues the
command, waits
for completion,
and processes the response. This reduces a handful of lines of code to a single
function call. If the request must be submitted asynchronously, the core provides
the <font face="Courier New, Courier, mono"><a href="PD_Reference.htm#FUNC_SDLIB_SetupCMD52Request">SDLIB_SetupCMD52Request()</a></font> which
initializes all the request fields except the completion routine and context.
The request can then be submitted as a generic raw request asynchronously.</p>
<p class="BODYTEXT">Using SDIO extended commands (CMD53) requires that the driver
allocate a request, fill in parameters and set the argument
using the <font face="Courier New, Courier, mono">SET_SDIO_CMD53_ARG()</font> macro.
The request must be sent as a raw request and the driver must specify the
presence of data and the direction (read or write). The driver must also set
the data
buffer pointer and set the number of blocks
and the block length. When using CMD53 in bytes transfer mode the
block count is always 1 with a maximum block length of 512 bytes. When using
CMD53
in
block transfer mode, the driver must set it's function block length register
to the
size of
each
block
and
specify
that
value
in the bus request. The SDIO core does not support CMD53's "infinite" block
mode.</p>
<p class="HEADING3">Block Count and Size Limitations:</p>
<p class="BODYTEXT">Some host controllers impose a per-transaction block count
and block size limits. The bus driver may also limit the number of blocks and
size of
each block per transaction to manage bandwidth among multiple functions on
a single card. A driver should check its operational limits using the <font face="Courier New, Courier, mono"><a href="PD_Reference.htm#FUNC_SDDEVICE_GET_OPER_BLOCK">SDDEVICE_GET_OPER_BLOCK()</a></font> and
<font face="Courier New, Courier, mono"><a href="PD_Reference.htm#FUNC_SDDEVICE_GET_OPER_BLOCK_LEN">SDDEVICE_GET_OPER_BLOCK_LEN()</a></font> and
limit its block transfer requests accordingly.</p>
<p class="HEADING3">Short Data Transfers</p>
<p class="BODYTEXT">A function driver may provide a hint to a host controller
driver (HCD) to optimize a short (and fast) data transfer. This optimization
can improve performance by allowing the HCD to poll the controller for completion
instead of waiting for data completion interrupts. A short data transfer is
indicated using the <font face="Courier New, Courier, mono">SDREQ_FLAGS_SHORT_DATA_TRANSFER</font> flag
in the
request.The
function
driver must guarantee that the transfer can be completed in a reasonable amount
of time without detriment to overall system response. A short data transfer
should meet the following requirements to
qualify for
this
optimization:
<ul>
<li>The data transfer should be short, consisting of only 1 block and usually
less than 8 bytes
in
length.</li>
<li>If the transfer is a read operation, the data start bit must
occur within a very short period, usually several clocks. The SD/SDIO
spec allows for a significant delay before the arrival of the start bit.
If a significant delay can occur, the function
driver should avoid this technique.</li>
<li>If the transfer is a write operation, the program done signal should occur
within several clock cycles. The SD/SDIO spec allows for a significant delay
before program done is asserted. If a significant delay can occur, the function
driver should avoid this technique.</li>
</ul></p>
<p class="BODYTEXT"">
Short transfer optimizations are optional and the host can choose to
ignore
this flag entirely and process data transfers with interrupts.
</p>
<p class="BODYTEXT""><a name="DMAOperation"></a><strong>Direct Memory Access:</strong></p>
<p class="BODYTEXT"">Function drivers can optionally submit data transfer requests
using buffers that can be directly accessed by host controller hardware. This
can
improve throughput and significantly
reduce overhead for large data transfers. Direct memory access is optional
and all host controller drivers will continue to accept data buffers for programmed
I/O operation.</p>
<p class="BODYTEXT"">Function drivers are
responsible for managing DMA buffers in an OS-dependent
way. Function drivers may allocate buffers internally or utilize buffers
passed down from subsystems (i.e. files systems, network stacks)
or
user mode
applications. These buffers may or may not be suitable for DMA operations.
Function drivers must insure that the DMA requirements for the platform, operating
system
(or subsystem) and host controller driver (HCD) are
met, if it chooses to submit DMA buffers in bus requests. Function drivers
can obtain the DMA restrictions for the platform/HCD via the macro: <font face="Courier New, Courier, mono"><a href="PD_Reference.htm#FUNC_SDGET_DMA_DESCRIPTION">SDGET_DMA_DESCRIPTION()</a></font>.
If
this macro returns NULL, then the HCD or platform does not support
DMA and the driver should be prepared to transfer the buffer using normal bus
requests. Otherwise a pointer to an OS-dependent <font face="Courier New, Courier, mono">SDDMA_DESCRIPTION</font> structure
is returned. Each operating system will define its own <font face="Courier New, Courier, mono">SDDMA_DESCRIPTION</font> structure.
The structure reflects the capabilities of the platform, host controller and
version of the operating system. It will contain information for the
allocation of coherent (cache-coherent)
and properly aligned buffers. This information can be used to allocate internal
buffers or passed to subsystems (filesystem, network stack) that are capable
of creating these buffers. Most
platforms will require the function driver to adhere to physical address and
transfer
length
alignment
restrictions. For each OS supported, the <font face="Courier New, Courier, mono">SDDMA_DESCRIPTION</font> provides
enough information for the function driver to allocate
DMA-friendly buffers or pass the DMA requirements to the owners
of these buffers (i.e.
subsystems). </p>
<p class="BODYTEXT"">Function drivers must provide a DMA descriptor
list (array of <font face="Courier New, Courier, mono">SDDMA_DESCRIPTORs</font>)
for the DMA buffer used in a bus request. A descriptor list consists of one
or more descriptors (<font face="Courier New, Courier, mono">SDDMA_DESCRIPTOR</font>)
that provide OS-specific information on each
block
or page
of physical
memory assigned to this buffer. The blocks/pages that are described can be
non-contiguous. If a buffer was provided by a subsystem (filesystem, network
stack) or user-mode
application,
the function
driver
may be required to create a descriptor list or request the subsystem to prepare
one. If the buffer
allocation is outside the control of the function driver, the
driver
must
always
check
DMA
restrictions
and if necessary transfer the buffer without DMA.</p>
<p class="BODYTEXT"">If
a data buffer meets the DMA
requirements of the platform/HCD and the driver was able to create a DMA descriptor
list, then the function driver can set the flag: <font face="Courier New, Courier, mono">SDREQ_FLAGS_DATA_DMA</font> in
the bus request.
When the flag is set, the <font face="Courier New, Courier, mono">pDataBuffer</font> member
of the request must point to an array (list)
of <font face="Courier New, Courier, mono">SDDMA_DESCRIPTOR</font> structures
and the <font face="Courier New, Courier, mono">DescriptorCount</font> field
is set to the number of array elements. Function drivers must adhere
to the maximum number of descriptors
allowed per transfer and the maximum number of bytes that can be processed
per descriptor. This information is provided in the <font face="Courier New, Courier, mono">SDDMA_DESCRIPTION</font> structure.
Function drivers can submit DMA-prepared bus requests just like any
other request (i.e. synchronous or asynchronous submission).</p>
<p class="BODYTEXT"">Refer to the SDIO sample drivers for OS-specific usage
of the <font face="Courier New, Courier, mono">SDDMA_DESCRIPTION</font> and <font face="Courier New, Courier, mono">SDDMA_DESCRIPTOR</font> structures.
Refer to the <font face="Courier New, Courier, mono">ctsystem_xxxx.h</font> header
file (ex. <font face="Courier New, Courier, mono">ctsystem_linux.h</font>)
for the definition of these structures.</p>
<p class="BODYTEXT""><em>Note on Scatter Gather DMA:</em></p>
<p class="BODYTEXT"">Scatter gather DMA is a technique in which an entire DMA
descriptor list of potentially non-contiguous pages/blocks can be translated
and programmed into a controller. The controller will traverse
this list (typically
in host
memory as well)
and read (gather) or write (scatter) from/to these pages.
This technique (within the scope of SD/SDIO) can be used to move a very large
amount
of data with very little
CPU intervention. The use of scatter gather DMA is host
controller dependent. As noted earlier the <font face="Courier New, Courier, mono">SDDMA_DESCRIPTION</font> structure
typically contains a field for the maximum number of descriptors per bus request.
A value greater than 1 does NOT always imply that the host will use scatter
gather. In some hardware implementations the host controller may simply process
the
next DMA descriptor at each DMA completion event. Setting the max descriptor
count greater than one is provided as an optimization for transfers with many
descriptors and a host merely "emulates" scatter gather behavior. In more
advanced host controllers, the entire descriptor list may be processed in one
DMA operation
using a true scatter gather engine. This provides the highest performance and
the least amount of CPU utilization. Some OS implementations will provide a
"hint" that the host controller implements true
scatter gather DMA
using
a set
of flags.</p>
<!-- InstanceEndEditable -->
<br/>
</table></td></tr>
<table width="100%" border="0" cellspacing="0" cellpadding="2" >
<tr> <td><div align="right"><a href="#TopTopic">Back to top</a></div></td></tr>
<tr bgcolor="#0000FF">
<td>
<font color="#FFFFFF"face="Arial, Helvetica, sans-serif"><strong>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -