nuttx/Documentation/guides/drivers/usbtrace.rst
Vinicius May f6ecf80ebb Documentation: brand new layout for NuttX documentation.
The documentation grew one page at a time, so the tree follows the
history of who wrote what and not the shape of NuttX. Scheduling is
spread over three places, a driver page can sit above the subsystem
that owns it, and the front page lists everything at the same level.
That is a lot to face when all you want to know is where the scheduler
lives.

This change files every page under the code it describes. It is a move,
not a rewrite: outside the ten pages named below, every page keeps the
text that is already in master, and no page's text is deleted.

What it does:

* Groups the table of contents into nine chapters.
* Moves the OS subsystems under os/: scheduling, memory, drivers,
  filesystem, networking, IPC, interrupts, libs, time.
* Renames the platform pages to the names the source tree uses, and
  derives their tags from the tree instead of by hand.
* Splits guides/ by subject.
* Adds Documentation/redirects.py, with a rule for every page that left
  its old path, so old URLs keep working. The redirect page also carries
  a link's #anchor across to the new page.

Ten pages have text that is new or rewritten. Nine of them are the
landing page of a chapter, which has to exist for the new structure:

    index                  the front page
    os/index               OS Design
    os/scheduling/index    Scheduling
    os/interrupts/index    Interrupts
    os/ipc/index           IPC
    os/time/index          Time and timers
    about/index            About
    developing/index       Developing NuttX
    ReleaseNotes/index     Release notes

The tenth is os/libs/libbuiltin, the only page here with technical
content: libs/libbuiltin/ had no page at all. Five SVG diagrams come
with these pages, hand-written XML with no editor metadata.

Nothing outside Documentation/ is touched.

How it was checked:

* Sphinx builds with -W: no warnings, and no document left outside a
  toctree.
* A script, offered in the PR, proves the narrow claim this rests on.
  For every page outside the ten named above it erases what a move
  touches -- link target, path, tag line, toctree block, table border --
  from the whole old text and the whole new text, and requires the two
  to be byte for byte identical. It also requires every sentence of a
  deleted page to turn up somewhere, and every page that left its old
  path to have a redirect, from a URL that existed, to where its content
  went. It exits non-zero and names the page if any of that is not true,
  and it tests added pages too, so forgetting to declare one cannot make
  it pass.
* An independent audit checked 133 factual claims on these ten pages
  against the tree, one shell command per claim: 130 confirmed, 1
  refuted and fixed here, 2 not checkable.
* tools/checkpatch.sh is clean over the range.

The diff is large because moving a page changes every link that points
to it. Most of it is pure renames, and board pages that gained one tag
line.

Assisted-by: Claude:claude-opus-5
2026-10-08 01:40:54 +08:00

209 lines
9.9 KiB
ReStructuredText

.. _usbtrace:
================
USB Device Trace
================
**USB Device Tracing Controls**. The NuttX USB device subsystem supports
a fairly sophisticated tracing facility. The basic trace capability 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.
=========================================== ===================================================
=============================================== ============================================
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.