1.. _usb_device_stack:
2
3USB device support
4##################
5
6.. contents::
7    :local:
8    :depth: 3
9
10Overview
11********
12
13The USB device stack is a hardware independent interface between USB
14device controller driver and USB device class drivers or customer applications.
15It is a port of the LPCUSB device stack and has been modified and expanded
16over time. It provides the following functionalities:
17
18* Uses the :ref:`usb_dc_api` provided by the device controller drivers to interact with
19  the USB device controller.
20* Responds to standard device requests and returns standard descriptors,
21  essentially handling 'Chapter 9' processing, specifically the standard
22  device requests in table 9-3 from the universal serial bus specification
23  revision 2.0.
24* Provides a programming interface to be used by USB device classes or
25  customer applications. The APIs is described in
26  :zephyr_file:`include/zephyr/usb/usb_device.h`
27
28.. note::
29   It is planned to deprecate all APIs listed in :ref:`usb_api` and the
30   functions that depend on them between Zephyr v4.0.0 and v4.1.0, and remove
31   them in v4.3.0. The new USB device support, represented by the APIs in
32   :ref:`usb_device_next_api`, will become the default in Zephyr v4.1.0.
33
34Supported USB classes
35*********************
36
37Audio
38=====
39
40There is an experimental implementation of the Audio class. It follows specification
41version 1.00 (``bcdADC 0x0100``) and supports synchronous synchronisation type only.
42See :zephyr:code-sample:`usb-audio-headphones-microphone` and
43:zephyr:code-sample:`usb-audio-headset` samples for reference.
44
45Bluetooth HCI USB transport layer
46=================================
47
48Bluetooth HCI USB transport layer implementation uses :ref:`bt_hci_raw`
49to expose HCI interface to the host. It is not fully in line with the description
50in the Bluetooth specification and consists only of an interface with the endpoint
51configuration:
52
53* HCI commands through control endpoint (host-to-device only)
54* HCI events through interrupt IN endpoint
55* ACL data through one bulk IN and one bulk OUT endpoints
56
57A second interface for the voice channels has not been implemented as there is
58no support for this type in :ref:`bluetooth`. It is not a big problem under Linux
59if HCI USB transport layer is the only interface that appears in the configuration,
60the btusb driver would not try to claim a second (isochronous) interface.
61The consequence is that if HCI USB is used in a composite configuration and is
62the first interface, then the Linux btusb driver will claim both the first and
63the next interface, preventing other composite functions from working.
64Because of this problem, HCI USB should not be used in a composite configuration.
65This problem is fixed in the implementation for new USB support.
66
67See :zephyr:code-sample:`bluetooth_hci_usb` sample for reference.
68
69.. _usb_device_cdc_acm:
70
71CDC ACM
72=======
73
74The CDC ACM class is used as backend for different subsystems in Zephyr.
75However, its configuration may not be easy for the inexperienced user.
76Below is a description of the different use cases and some pitfalls.
77
78The interface for CDC ACM user is :ref:`uart_api` driver API.
79But there are two important differences in behavior to a real UART controller:
80
81* Data transfer is only possible after the USB device stack has been
82  initialized and started, until then any data is discarded
83* If device is connected to the host, it still needs an application
84  on the host side which requests the data
85* The CDC ACM poll out implementation follows the API and blocks when the TX
86  ring buffer is full only if the hw-flow-control property is enabled and
87  called from a non-ISR context.
88
89The devicetree compatible property for CDC ACM UART is
90:dtcompatible:`zephyr,cdc-acm-uart`.
91CDC ACM support is automatically selected when USB device support is enabled
92and a compatible node in the devicetree sources is present. If necessary,
93CDC ACM support can be explicitly disabled by :kconfig:option:`CONFIG_USB_CDC_ACM`.
94About four CDC ACM UART instances can be defined and used,
95limited by the maximum number of supported endpoints on the controller.
96
97CDC ACM UART node is supposed to be child of a USB device controller node.
98Since the designation of the controller nodes varies from vendor to vendor,
99and our samples and application should be as generic as possible,
100the default USB device controller is usually assigned an ``zephyr_udc0``
101node label. Often, CDC ACM UART is described in a devicetree overlay file
102and looks like this:
103
104.. code-block:: devicetree
105
106	&zephyr_udc0 {
107		cdc_acm_uart0: cdc_acm_uart0 {
108			compatible = "zephyr,cdc-acm-uart";
109			label = "CDC_ACM_0";
110		};
111	};
112
113Sample :zephyr:code-sample:`usb-cdc-acm` has similar overlay files.
114And since no special properties are present, it may seem overkill to use
115devicetree to describe CDC ACM UART.  The motivation behind using devicetree
116is the easy interchangeability of a real UART controller and CDC ACM UART
117in applications.
118
119Console over CDC ACM UART
120-------------------------
121
122With the CDC ACM UART node from above and ``zephyr,console`` property of the
123chosen node, we can describe that CDC ACM UART is to be used with the console.
124A similar overlay file is used by the :zephyr:code-sample:`usb-cdc-acm-console` sample.
125
126.. code-block:: devicetree
127
128	/ {
129		chosen {
130			zephyr,console = &cdc_acm_uart0;
131		};
132	};
133
134	&zephyr_udc0 {
135		cdc_acm_uart0: cdc_acm_uart0 {
136			compatible = "zephyr,cdc-acm-uart";
137			label = "CDC_ACM_0";
138		};
139	};
140
141Before the application uses the console, it is recommended to wait for
142the DTR signal:
143
144.. code-block:: c
145
146	const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
147	uint32_t dtr = 0;
148
149	if (usb_enable(NULL)) {
150		return;
151	}
152
153	while (!dtr) {
154		uart_line_ctrl_get(dev, UART_LINE_CTRL_DTR, &dtr);
155		k_sleep(K_MSEC(100));
156	}
157
158	printk("nuqneH\n");
159
160CDC ACM UART as backend
161-----------------------
162
163As for the console sample, it is possible to configure CDC ACM UART as
164backend for other subsystems by setting :ref:`devicetree-chosen-nodes`
165properties.
166
167List of few Zephyr specific chosen properties which can be used to select
168CDC ACM UART as backend for a subsystem or application:
169
170* ``zephyr,bt-c2h-uart`` used in Bluetooth,
171  for example see :zephyr:code-sample:`bluetooth_hci_uart`
172* ``zephyr,ot-uart`` used in OpenThread,
173  for example see :zephyr:code-sample:`openthread-coprocessor`
174* ``zephyr,shell-uart`` used by shell for serial backend,
175  for example see :zephyr_file:`samples/subsys/shell/shell_module`
176* ``zephyr,uart-mcumgr`` used by :zephyr:code-sample:`smp-svr` sample
177
178POSIX default tty ECHO mitigation
179---------------------------------
180
181POSIX systems, like Linux, default to enabling ECHO on tty devices. Host side
182application can disable ECHO by calling ``open()`` on the tty device and issuing
183``ioctl()`` (preferably via ``tcsetattr()``) to disable echo if it is not desired.
184Unfortunately, there is an inherent race between the ``open()`` and ``ioctl()``
185where the ECHO is enabled and any characters received (even if host application
186does not call ``read()``) will be echoed back. This issue is especially visible
187when the CDC ACM port is used without any real UART on the other side because
188there is no arbitrary delay due to baud rate.
189
190To mitigate the issue, Zephyr CDC ACM implementation arms IN endpoint with ZLP
191after device is configured. When the host reads the ZLP, which is pretty much
192the best indication that host application has opened the tty device, Zephyr will
193force :kconfig:option:`CONFIG_CDC_ACM_TX_DELAY_MS` millisecond delay before real
194payload is sent. This should allow sufficient time for first, and only first,
195application that opens the tty device to disable ECHO if ECHO is not desired.
196If ECHO is not desired at all from CDC ACM device it is best to set up udev rule
197to disable ECHO as soon as device is connected.
198
199ECHO is particurarly unwanted when CDC ACM instance is used for Zephyr shell,
200because the control characters to set color sent back to shell are interpreted
201as (invalid) command and user will see garbage as a result. While minicom does
202disable ECHO by default, on exit with reset it will restore the termios settings
203to whatever was set on entry. Therefore, if minicom is the first application to
204open the tty device, the exit with reset will enable ECHO back and thus set up
205a problem for the next application (which cannot be mitigated at Zephyr side).
206To prevent the issue it is recommended either to leave minicom without reset or
207to disable ECHO before minicom is started.
208
209DFU
210===
211
212USB DFU class implementation is tightly coupled to :ref:`dfu` and :ref:`mcuboot_api`.
213This means that the target platform must support the :ref:`flash_img_api` API.
214
215See :zephyr:code-sample:`usb-dfu` sample for reference.
216
217USB Human Interface Devices (HID) support
218=========================================
219
220HID support abuses :ref:`device_model_api` simply to allow applications to use
221the :c:func:`device_get_binding`. Note that there is no HID device API as such,
222instead the interface is provided by :c:struct:`hid_ops`.
223The default instance name is ``HID_n``, where n can be {0, 1, 2, ...} depending on
224the :kconfig:option:`CONFIG_USB_HID_DEVICE_COUNT`.
225
226Each HID instance requires a HID report descriptor. The interface to the core
227and the report descriptor must be registered using :c:func:`usb_hid_register_device`.
228
229As the USB HID specification is not only used by the USB subsystem, the USB HID API
230reference is split into two parts, :ref:`usb_hid_common` and :ref:`usb_hid_device`.
231HID helper macros from :ref:`usb_hid_common` should be used to compose a
232HID report descriptor. Macro names correspond to those used in the USB HID specification.
233
234For the HID class interface, an IN interrupt endpoint is required for each instance,
235an OUT interrupt endpoint is optional. Thus, the minimum implementation requirement
236for :c:struct:`hid_ops` is to provide ``int_in_ready`` callback.
237
238.. code-block:: c
239
240	#define REPORT_ID		1
241	static bool configured;
242	static const struct device *hdev;
243
244	static void int_in_ready_cb(const struct device *dev)
245	{
246		static uint8_t report[2] = {REPORT_ID, 0};
247
248		if (hid_int_ep_write(hdev, report, sizeof(report), NULL)) {
249			LOG_ERR("Failed to submit report");
250		} else {
251			report[1]++;
252		}
253	}
254
255	static void status_cb(enum usb_dc_status_code status, const uint8_t *param)
256	{
257		if (status == USB_DC_RESET) {
258			configured = false;
259		}
260
261		if (status == USB_DC_CONFIGURED && !configured) {
262			int_in_ready_cb(hdev);
263			configured = true;
264		}
265	}
266
267	static const uint8_t hid_report_desc[] = {
268		HID_USAGE_PAGE(HID_USAGE_GEN_DESKTOP),
269		HID_USAGE(HID_USAGE_GEN_DESKTOP_UNDEFINED),
270		HID_COLLECTION(HID_COLLECTION_APPLICATION),
271		HID_LOGICAL_MIN8(0x00),
272		HID_LOGICAL_MAX16(0xFF, 0x00),
273		HID_REPORT_ID(REPORT_ID),
274		HID_REPORT_SIZE(8),
275		HID_REPORT_COUNT(1),
276		HID_USAGE(HID_USAGE_GEN_DESKTOP_UNDEFINED),
277		HID_INPUT(0x02),
278		HID_END_COLLECTION,
279	};
280
281	static const struct hid_ops my_ops = {
282		.int_in_ready = int_in_ready_cb,
283	};
284
285	int main(void)
286	{
287		int ret;
288
289		hdev = device_get_binding("HID_0");
290		if (hdev == NULL) {
291			return -ENODEV;
292		}
293
294		usb_hid_register_device(hdev, hid_report_desc, sizeof(hid_report_desc),
295					&my_ops);
296
297		ret = usb_hid_init(hdev);
298		if (ret) {
299			return ret;
300		}
301
302		return usb_enable(status_cb);
303	}
304
305
306If the application wishes to receive output reports via the OUT interrupt endpoint,
307it must enable :kconfig:option:`CONFIG_ENABLE_HID_INT_OUT_EP` and provide
308``int_out_ready`` callback.
309The disadvantage of this is that Kconfig options such as
310:kconfig:option:`CONFIG_ENABLE_HID_INT_OUT_EP` or
311:kconfig:option:`CONFIG_HID_INTERRUPT_EP_MPS` apply to all instances. This design
312issue will be fixed in the HID class implementation for the new USB support.
313
314See :zephyr:code-sample:`usb-hid-mouse` sample for reference.
315
316Mass Storage Class
317==================
318
319MSC follows Bulk-Only Transport specification and uses :ref:`disk_access_api` to
320access and expose a RAM disk, emulated block device on a flash partition,
321or SD Card to the host. Only one disk instance can be exported at a time.
322
323The disc to be used by the implementation is set by the
324:kconfig:option:`CONFIG_MASS_STORAGE_DISK_NAME` and should be the same as the
325name used by the disc access driver that the application wants to expose to the
326host. Flash, RAM, and SDMMC/MMC disk drivers use node property ``disk-name`` to
327set the disk name.
328
329For the emulated block device on a flash partition, the flash partition and
330flash disk to be used must be described in the devicetree. If a storage partition
331is already described at the board level, application devicetree overlay must also
332delete ``storage_partition`` node first. :kconfig:option:`CONFIG_MASS_STORAGE_DISK_NAME`
333should be the same as ``disk-name`` property.
334
335.. code-block:: devicetree
336
337	/delete-node/ &storage_partition;
338
339	&mx25r64 {
340		partitions {
341			compatible = "fixed-partitions";
342			#address-cells = <1>;
343			#size-cells = <1>;
344
345			storage_partition: partition@0 {
346				label = "storage";
347				reg = <0x00000000 0x00020000>;
348			};
349		};
350	};
351
352	/ {
353		msc_disk0 {
354			compatible = "zephyr,flash-disk";
355			partition = <&storage_partition>;
356			disk-name = "NAND";
357			cache-size = <4096>;
358		};
359	};
360
361The ``disk-property`` "NAND" may be confusing, but it is simply how some file
362systems identifies the disc. Therefore, if the application also accesses the
363file system on the exposed disc, default names should be used, see
364:zephyr:code-sample:`usb-mass` sample for reference.
365
366Networking
367==========
368
369There are three implementations that work in a similar way, providing a virtual
370Ethernet connection between the remote (USB host) and Zephyr network support.
371
372* CDC ECM class, enabled with :kconfig:option:`CONFIG_USB_DEVICE_NETWORK_ECM`
373* CDC EEM class, enabled with :kconfig:option:`CONFIG_USB_DEVICE_NETWORK_EEM`
374* RNDIS support, enabled with :kconfig:option:`CONFIG_USB_DEVICE_NETWORK_RNDIS`
375
376See :zephyr:code-sample:`zperf` or :zephyr:code-sample:`socket-dumb-http-server` for reference.
377Typically, users will need to add a configuration file overlay to the build,
378such as :zephyr_file:`samples/net/zperf/overlay-netusb.conf`.
379
380Applications using RNDIS support should enable :kconfig:option:`CONFIG_USB_DEVICE_OS_DESC`
381for a better user experience on a host running Microsoft Windows OS.
382
383Binary Device Object Store (BOS) support
384****************************************
385
386BOS handling can be enabled with Kconfig option :kconfig:option:`CONFIG_USB_DEVICE_BOS`.
387This option also has the effect of changing device descriptor ``bcdUSB`` to ``0210``.
388The application should register descriptors such as Capability Descriptor
389using :c:func:`usb_bos_register_cap`. Registered descriptors are added to the root
390BOS descriptor and handled by the stack.
391
392See :zephyr:code-sample:`webusb` sample for reference.
393
394Implementing a non-standard USB class
395*************************************
396
397The configuration of USB device is done in the stack layer.
398
399The following structures and callbacks need to be defined:
400
401* Part of USB Descriptor table
402* USB Endpoint configuration table
403* USB Device configuration structure
404* Endpoint callbacks
405* Optionally class, vendor and custom handlers
406
407For example, for the USB loopback application:
408
409.. literalinclude:: ../../../../subsys/usb/device/class/loopback.c
410   :language: c
411   :start-after: usb.rst config structure start
412   :end-before: usb.rst config structure end
413   :linenos:
414
415Endpoint configuration:
416
417.. literalinclude:: ../../../../subsys/usb/device/class/loopback.c
418   :language: c
419   :start-after: usb.rst endpoint configuration start
420   :end-before: usb.rst endpoint configuration end
421   :linenos:
422
423USB Device configuration structure:
424
425.. literalinclude:: ../../../../subsys/usb/device/class/loopback.c
426   :language: c
427   :start-after: usb.rst device config data start
428   :end-before: usb.rst device config data end
429   :linenos:
430
431
432The vendor device requests are forwarded by the USB stack core driver to the
433class driver through the registered vendor handler.
434
435For the loopback class driver, :c:func:`loopback_vendor_handler` processes
436the vendor requests:
437
438.. literalinclude:: ../../../../subsys/usb/device/class/loopback.c
439   :language: c
440   :start-after: usb.rst vendor handler start
441   :end-before:  usb.rst vendor handler end
442   :linenos:
443
444The class driver waits for the :makevar:`USB_DC_CONFIGURED` device status code
445before transmitting any data.
446
447.. _testing_USB_native_sim:
448
449Interface number and endpoint address assignment
450************************************************
451
452In USB terminology, a ``function`` is a device that provides a capability to the
453host, such as a HID class device that implements a keyboard. A function
454contains a collection of ``interfaces``; at least one interface is required. An
455interface may contain device ``endpoints``; for example, at least one input
456endpoint is required to implement a HID class device, and no endpoints are
457required to implement a USB DFU class. A USB device that combines functions is
458a multifunction USB device, for example, a combination of a HID class device
459and a CDC ACM device.
460
461With Zephyr RTOS USB support, various combinations are possible with built-in USB
462classes/functions or custom user implementations. The limitation is the number
463of available device endpoints. Each device endpoint is uniquely addressable.
464The endpoint address is a combination of endpoint direction and endpoint
465number, a four-bit value. Endpoint number zero is used for the default control
466method to initialize and configure a USB device. By specification, a maximum of
467``15 IN`` and ``15 OUT`` device endpoints are also available for use in functions.
468The actual number depends on the device controller used. Not all controllers
469support the maximum number of endpoints and all endpoint types. For example, a
470device controller might support one IN and one OUT isochronous endpoint, but
471only for endpoint number 8, resulting in endpoint addresses 0x88 and 0x08.
472Also, one controller may be able to have IN/OUT endpoints on the same endpoint
473number, interrupt IN endpoint 0x81 and bulk OUT endpoint 0x01, while the other
474may only be able to handle one endpoint per endpoint number. Information about
475the number of interfaces, interface associations, endpoint types, and addresses
476is provided to the host by the interface, interface specific, and endpoint
477descriptors.
478
479Host driver for specific function, uses interface and endpoint descriptor to
480obtain endpoint addresses, types, and other properties. This allows function
481host drivers to be generic, for example, a multi-function device consisting of
482one or more CDC ACM and one or more CDC ECM class implementations is possible
483and no specific drivers are required.
484
485Interface and endpoint descriptors of built-in USB class/function
486implementations in Zephyr RTOS typically have default interface numbers and
487endpoint addresses assigned in ascending order. During initialization,
488default interface numbers may be reassigned based on the number of interfaces in
489a given configuration. Endpoint addresses are reassigned based on controller
490capabilities, since certain endpoint combinations are not possible with every
491controller, and the number of interfaces in a given configuration. This also
492means that the device side class/function in the Zephyr RTOS must check the
493actual interface and endpoint descriptor values at runtime.
494This mechanism also allows as to provide generic samples and generic
495multifunction samples that are limited only by the resources provided by the
496controller, such as the number of endpoints and the size of the endpoint FIFOs.
497
498There may be host drivers for a specific function, for example in the Linux
499Kernel, where the function driver does not read interface and endpoint
500descriptors to check interface numbers or endpoint addresses, but instead uses
501hardcoded values. Therefore, the host driver cannot be used in a generic way,
502meaning it cannot be used with different device controllers and different
503device configurations in combination with other functions. This may also be
504because the driver is designed for a specific hardware and is not intended to
505be used with a clone of this specific hardware. On the contrary, if the driver
506is generic in nature and should work with different hardware variants, then it
507must not use hardcoded interface numbers and endpoint addresses.
508It is not possible to disable endpoint reassignment in Zephyr RTOS, which may
509prevent you from implementing a hardware-clone firmware. Instead, if possible,
510the host driver implementation should be fixed to use values from the interface
511and endpoint descriptor.
512
513Testing over USBIP in native_sim
514********************************
515
516A virtual USB controller implemented through USBIP might be used to test the USB
517device stack. Follow the general build procedure to build the USB sample for
518the :ref:`native_sim <native_sim>` configuration.
519
520Run built sample with:
521
522.. code-block:: console
523
524   west build -t run
525
526In a terminal window, run the following command to list USB devices:
527
528.. code-block:: console
529
530   $ usbip list -r localhost
531   Exportable USB devices
532   ======================
533    - 127.0.0.1
534           1-1: unknown vendor : unknown product (2fe3:0100)
535              : /sys/devices/pci0000:00/0000:00:01.2/usb1/1-1
536              : (Defined at Interface level) (00/00/00)
537              :  0 - Vendor Specific Class / unknown subclass / unknown protocol (ff/00/00)
538
539In a terminal window, run the following command to attach the USB device:
540
541.. code-block:: console
542
543   $ sudo usbip attach -r localhost -b 1-1
544
545The USB device should be connected to your Linux host, and verified with the
546following commands:
547
548.. code-block:: console
549
550   $ sudo usbip port
551   Imported USB devices
552   ====================
553   Port 00: <Port in Use> at Full Speed(12Mbps)
554          unknown vendor : unknown product (2fe3:0100)
555          7-1 -> usbip://localhost:3240/1-1
556              -> remote bus/dev 001/002
557   $ lsusb -d 2fe3:0100
558   Bus 007 Device 004: ID 2fe3:0100
559
560USB Vendor and Product identifiers
561**********************************
562
563The USB Vendor ID for the Zephyr project is ``0x2FE3``.
564This USB Vendor ID must not be used when a vendor
565integrates Zephyr USB device support into its own product.
566
567Each USB :zephyr:code-sample-category:`sample<usb>` has its own unique Product ID.
568The USB maintainer, if one is assigned, or otherwise the Zephyr Technical
569Steering Committee, may allocate other USB Product IDs based on well-motivated
570and documented requests.
571
572The following Product IDs are currently used:
573
574+----------------------------------------------------+--------+
575| Sample                                             | PID    |
576+====================================================+========+
577| :zephyr:code-sample:`usb-cdc-acm`                  | 0x0001 |
578+----------------------------------------------------+--------+
579| Reserved (previously: usb-cdc-acm-composite)       | 0x0002 |
580+----------------------------------------------------+--------+
581| Reserved (previously: usb-hid-cdc)                 | 0x0003 |
582+----------------------------------------------------+--------+
583| :zephyr:code-sample:`usb-cdc-acm-console`          | 0x0004 |
584+----------------------------------------------------+--------+
585| :zephyr:code-sample:`usb-dfu` (Run-Time)           | 0x0005 |
586+----------------------------------------------------+--------+
587| Reserved (previously: usb-hid)                     | 0x0006 |
588+----------------------------------------------------+--------+
589| :zephyr:code-sample:`usb-hid-mouse`                | 0x0007 |
590+----------------------------------------------------+--------+
591| :zephyr:code-sample:`usb-mass`                     | 0x0008 |
592+----------------------------------------------------+--------+
593| :zephyr:code-sample:`testusb-app`                  | 0x0009 |
594+----------------------------------------------------+--------+
595| :zephyr:code-sample:`webusb`                       | 0x000A |
596+----------------------------------------------------+--------+
597| :zephyr:code-sample:`bluetooth_hci_usb`            | 0x000B |
598+----------------------------------------------------+--------+
599| Reserved (previously: bluetooth_hci_usb_h4)        | 0x000C |
600+----------------------------------------------------+--------+
601| Reserved (previously: wpan-usb)                    | 0x000D |
602+----------------------------------------------------+--------+
603| :zephyr:code-sample:`uac2-explicit-feedback`       | 0x000E |
604+----------------------------------------------------+--------+
605| :zephyr:code-sample:`uac2-implicit-feedback`       | 0x000F |
606+----------------------------------------------------+--------+
607| :zephyr:code-sample:`usb-dfu` (DFU Mode)           | 0xFFFF |
608+----------------------------------------------------+--------+
609
610The USB device descriptor field ``bcdDevice`` (Device Release Number) represents
611the Zephyr kernel major and minor versions as a binary coded decimal value.
612