1d1bdd85a3
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
214 lines
10 KiB
ReStructuredText
214 lines
10 KiB
ReStructuredText
.. _usbtrace:
|
|
|
|
================
|
|
USB Device Trace
|
|
================
|
|
|
|
**USB Device Tracing Controls**. The NuttX USB device subsystem supports
|
|
a fairly sophisticated tracing facility. The basic trace cabability is
|
|
controlled by these NuttX configuration settings:
|
|
|
|
- ``CONFIG_USBDEV_TRACE``: Enables USB tracing
|
|
- ``CONFIG_USBDEV_TRACE_NRECORDS``: Number of trace entries to remember
|
|
|
|
**Trace IDs**. The trace facility works like this: When enabled, USB
|
|
events that occur in either the USB device driver or in the USB class
|
|
driver are logged. These events are described in
|
|
``include/nuttx/usb/usbdev_trace.h``. The logged events are identified
|
|
by a set of event IDs:
|
|
|
|
========================= ==================================
|
|
``TRACE_INIT_ID`` Initialization events
|
|
``TRACE_EP_ID`` Endpoint API calls
|
|
``TRACE_DEV_ID`` USB device API calls
|
|
``TRACE_CLASS_ID`` USB class driver API calls
|
|
``TRACE_CLASSAPI_ID`` Other class driver system API calls
|
|
``TRACE_CLASSSTATE_ID`` Track class driver state changes
|
|
``TRACE_INTENTRY_ID`` Interrupt handler entry
|
|
``TRACE_INTDECODE_ID`` Decoded interrupt event
|
|
``TRACE_INTEXIT_ID`` Interrupt handler exit
|
|
``TRACE_OUTREQQUEUED_ID`` Request queued for OUT endpoint
|
|
``TRACE_INREQQUEUED_ID`` Request queued for IN endpoint
|
|
``TRACE_READ_ID`` Read (OUT) action
|
|
``TRACE_WRITE_ID`` Write (IN) action
|
|
``TRACE_COMPLETE_ID`` Request completed
|
|
``TRACE_DEVERROR_ID`` USB controller driver error event
|
|
``TRACE_CLSERROR_ID`` USB class driver error event
|
|
========================= ==================================
|
|
|
|
**Logged Events**. Each logged event is 32-bits in size and includes
|
|
|
|
#. 8-bits of the trace ID (values associated with the above)
|
|
#. 8-bits of additional trace ID data, and
|
|
#. 16-bits of additional data.
|
|
|
|
**8-bit Trace Data** The 8-bit trace data depends on the specific event
|
|
ID. As examples,
|
|
|
|
- For the USB serial and mass storage class, the 8-bit event data is
|
|
provided in ``include/nuttx/usb/usbdev_trace.h``.
|
|
- For the USB device driver, that 8-bit event data is provided within
|
|
the USB device driver itself. So, for example, the 8-bit event data
|
|
for the LPC1768 USB device driver is found in
|
|
``arch/arm/src/lpc17xx_40xx/lpc17_40_usbdev.c``.
|
|
|
|
**16-bit Trace Data**. The 16-bit trace data provided additional context
|
|
data relevant to the specific logged event.
|
|
|
|
**Trace Control Interfaces**. Logging of each of these kinds events can
|
|
be enabled or disabled using the interfaces described in
|
|
``include/nuttx/usb/usbdev_trace.h``.
|
|
|
|
**Enabling USB Device Tracing**. USB device tracing will be configured
|
|
if ``CONFIG_USBDEV`` and either of the following are set in the NuttX
|
|
configuration file:
|
|
|
|
- ``CONFIG_USBDEV_TRACE``, or
|
|
- ``CONFIG_DEBUG_FEATURES and CONFIG_DEBUG_USB``
|
|
|
|
**Log Data Sink**. The logged data itself may go to either (1) an
|
|
internal circular buffer, or (2) may be provided on the console. If
|
|
``CONFIG_USBDEV_TRACE`` is defined, then the trace data will go to the
|
|
circular buffer. The size of the circular buffer is determined by
|
|
``CONFIG_USBDEV_TRACE_NRECORDS``. Otherwise, the trace data goes to
|
|
console.
|
|
|
|
**Example**. Here is an example of USB trace output using
|
|
``apps/examples/usbserial`` for an LPC1768 platform with the following
|
|
NuttX configuration settings:
|
|
|
|
- ``CONFIG_DEBUG_FEATURES``, ``CONFIG_DEBUG_INFO``, ``CONFIG_USB``
|
|
- ``CONFIG_EXAMPLES_USBSERIAL_TRACEINIT``,
|
|
``CONFIG_EXAMPLES_USBSERIAL_TRACECLASS``,
|
|
``CONFIG_EXAMPLES_USBSERIAL_TRACETRANSFERS``,
|
|
``CONFIG_EXAMPLES_USBSERIAL_TRACECONTROLLER``,
|
|
``CONFIG_EXAMPLES_USBSERIAL_TRACEINTERRUPTS``
|
|
|
|
Console Output::
|
|
|
|
ABDE
|
|
usbserial_main: Registering USB serial driver
|
|
uart_register: Registering /dev/ttyUSB0
|
|
usbserial_main: Successfully registered the serial driver
|
|
1 Class API call 1: 0000
|
|
2 Class error: 19:0000
|
|
usbserial_main: ERROR: Failed to open /dev/ttyUSB0 for reading: 107
|
|
usbserial_main: Not connected. Wait and try again.
|
|
3 Interrupt 1 entry: 0039
|
|
4 Interrupt decode 7: 0019
|
|
5 Interrupt decode 32: 0019
|
|
6 Interrupt decode 6: 0019
|
|
7 Class disconnect(): 0000
|
|
8 Device pullup(): 0001
|
|
9 Interrupt 1 exit: 0000
|
|
|
|
The numbered items are USB USB trace output. You can look in the file
|
|
``drivers/usbdev/usbdev_trprintf.c`` to see examctly how each output
|
|
line is formatted. Here is how each line should be interpreted:
|
|
|
|
== ==================== ================ ================================== =================
|
|
N. USB EVENT ID 8-bit EVENT DATA MEANING 16-bit EVENT DATA
|
|
1 TRACE_CLASSAPI_ID1 1 USBSER_TRACECLASSAPI_SETUP1 0000
|
|
2 TRACE_CLSERROR_ID1 19 USBSER_TRACEERR_SETUPNOTCONNECTED1 0000
|
|
3 TRACE_INTENTRY_ID1 1 LPC17_40_TRACEINTID_USB2 0039
|
|
4 TRACE_INTDECODE_ID2 7 LPC17_40_TRACEINTID_DEVSTAT2 0019
|
|
5 TRACE_INTDECODE_ID2 32 LPC17_40_TRACEINTID_SUSPENDCHG2 0019
|
|
6 TRACE_INTDECODE_ID2 6 LPC17_40_TRACEINTID_DEVRESET2 0019
|
|
7 TRACE_CLASS_ID1 3 (See TRACE_CLASSDISCONNECT1) 0000
|
|
8 TRACE_DEV_ID1 6 (See TRACE_DEVPULLUP1) 0001
|
|
9 TRACE_INTEXIT_ID1 1 LPC17_40_TRACEINTID_USB2 0000
|
|
== ==================== ================ ================================== =================
|
|
|
|
NOTES:
|
|
|
|
1. See include/nuttx/usb/usbdev_trace.h
|
|
2. See arch/arm/src/lpc17xx_40xx/lpc17_40_usbdev.c
|
|
|
|
In the above example you can see that:
|
|
|
|
- **1**. The serial class USB setup method was called for the USB
|
|
serial class. This is the corresponds to the following logic in
|
|
``drivers/usbdev/pl2303.c``:
|
|
|
|
.. code-block:: c
|
|
|
|
static int pl2303_setup(FAR struct uart_dev_s *dev)
|
|
{
|
|
...
|
|
usbtrace(PL2303_CLASSAPI_SETUP, 0);
|
|
...
|
|
|
|
- **2**. An error occurred while processing the setup command because
|
|
no configuration has yet been selected by the host. This corresponds
|
|
to the following logic in ``drivers/usbdev/pl2303.c``:
|
|
|
|
.. code-block:: c
|
|
|
|
static int pl2303_setup(FAR struct uart_dev_s *dev)
|
|
{
|
|
...
|
|
/* Check if we have been configured */
|
|
|
|
if (priv->config == PL2303_CONFIGIDNONE)
|
|
{
|
|
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_SETUPNOTCONNECTED), 0);
|
|
return -ENOTCONN;
|
|
}
|
|
...
|
|
|
|
- **3-6**. Here is a USB interrupt that suspends and resets the device.
|
|
- **7-8**. During the interrupt processing the serial class is
|
|
disconnected
|
|
- **9**. And the interrupt returns
|
|
|
|
**USB Monitor**. The *USB monitor* is an application in the
|
|
``apps/system/usbmonitor`` that provides a convenient way to get debug
|
|
trace output. If tracing is enabled, the USB device will save encoded
|
|
trace output in in-memory buffer; if the USB monitor is also enabled,
|
|
that trace buffer will be periodically emptied and dumped to the system
|
|
logging device (the serial console in most configurations). The
|
|
following are some of the relevant configuration options:
|
|
|
|
=========================================== ===================================================
|
|
Device Drivers -> USB Device Driver Support .
|
|
``CONFIG_USBDEV_TRACE=y`` Enable USB trace feature
|
|
``CONFIG_USBDEV_TRACE_NRECORDS=nnnn`` Buffer nnnn records in memory. If you lose trace data,
|
|
. then you will need to increase the size of this buffer
|
|
. (or increase the rate at which the trace buffer is emptied).
|
|
``CONFIG_USBDEV_TRACE_STRINGS=y`` Optionally, convert trace ID numbers to strings.
|
|
. This feature may not be supported by all drivers.
|
|
=========================================== ===================================================
|
|
|
|
=========================================== ===================================================
|
|
Application Configuration -> NSH LIbrary .
|
|
``CONFIG_NSH_USBDEV_TRACE=n`` Make sure that any built-in tracing from NSH is disabled.
|
|
``CONFIG_NSH_ARCHINIT=y`` Enable this option only if your board-specific logic
|
|
. has logic to automatically start the USB monitor.
|
|
. Otherwise the USB monitor can be started or stopped
|
|
. with the usbmon_start and usbmon_stop commands from the NSH console.
|
|
=========================================== ===================================================
|
|
|
|
=============================================== ============================================
|
|
Application Configuration -> System NSH Add-Ons .
|
|
``CONFIG_USBMONITOR=y`` Enable the USB monitor daemon
|
|
``CONFIG_USBMONITOR_STACKSIZE=nnnn`` Sets the USB monitor daemon stack size to nnnn. The default is 2KiB.
|
|
``CONFIG_USBMONITOR_PRIORITY=50`` Sets the USB monitor daemon priority to nnnn.
|
|
. This priority should be low so that it does not
|
|
. interfere with other operations, but not so low that
|
|
. you cannot dump the buffered USB data sufficiently
|
|
. rapidly. The default is 50.
|
|
``CONFIG_USBMONITOR_INTERVAL=nnnn`` Dump the buffered USB data every nnnn seconds.
|
|
. If you lose buffered USB trace data, then dropping
|
|
. this value will help by increasing the rate at which
|
|
. the USB trace buffer is emptied.
|
|
``CONFIG_USBMONITOR_TRACEINIT=y`` Selects which USB event(s) that you want to be traced.
|
|
``CONFIG_USBMONITOR_TRACECLASS=y`` .
|
|
``CONFIG_USBMONITOR_TRACETRANSFERS=y`` .
|
|
``CONFIG_USBMONITOR_TRACECONTROLLER=y`` .
|
|
``CONFIG_USBMONITOR_TRACEINTERRUPTS=y`` .
|
|
=============================================== ============================================
|
|
|
|
NOTE: If USB debug output is also enabled, both outputs will appear on
|
|
the serial console. However, the debug output will be asynchronous with
|
|
the trace output and, hence, difficult to interpret.
|