Zephyr: USB: assign endpoints at runtime

Created on 7 Nov 2017  路  9Comments  路  Source: zephyrproject-rtos/zephyr

The configuration of the USB endpoints in the corresponding Kconfigs is too cumbersome and has to be done for each board/SoC and USB class/function.

USB device stack can assign the endpoints at runtime by using something like usb_ep_capabilities:

#define USB_EP_CAPS_IN      BIT(1)
#define USB_EP_CAPS_OUT     BIT(2)
#define USB_EP_CAPS_BI      (BIT(2) | BIT(1))

#define USB_EP_CAPS_SET(ep_idx, cap)    ((cap) << ep_idx) /* ep_idx in the range 0...15 */

static u32_t usb_ep_hw_caps usb_dc_get_ep_capabilities(..)                               
{                                                                                                        
        return USB_EP_CAPS_SET(0, USB_EP_CAPS_BI) | USB_EP_CAPS_SET(1, USB_EP_CAPS_IN);                                                
}    
Enhancement Drivers USB

All 9 comments

@finikorg @ydamigos @youvedeep
I can add it to #4661 if there are no objections.

I have also PR #4763 . This allows to select endpoints.

I agree that it is cumbersome and not flexible to configure USB endpoints for each board/SoC and USB class/function, like we do in commit ca13e798ff183aeba2a563b879cadd7e0401dab4 for 96b_carbon. We should assign the endpoints at runtime. You could do it in PR #4661 or ,even better, a different one to keep things clear and not connect it with the USB descriptors rework.

I agree that current solution is a pain, but I can understand that we want to define endpoints statically at build time since we have all the information we need to define which addr to use. the main issue is we need to deal with every endpoint address for each class/function driver + combination complexity. Ideally we should have a built-time macro USB_ALLOC_ENPOINT(BULK_IN) which takes care of returning an available address depending usb controller capabilities (max endpoints, direction). However I have no easy solution to achieve this at built time. If someone have idea ?
so runtime solution seems a lesser evil... ;-)

It is not that evil. It would be desirable if all USB classes and functions were abstract and the user could combine own functions with those of Zephyr. Problem (1) is the USB device descriptor and (2) endpoints enumerating and assignment.

  1. The descriptor must be fixed after it has been linked, that is: enumerating of the interfaces and its components, calculating the length of interfaces, string indexes and also the strings self must be fixed, see #4661 (WIP, will update asap)

  2. Enumerating and request of the endpoints is almost given with 1 and usb_ep_capabilities.

Alternative:
Combining the #4661 and some macro + python + cmake magic to accomplish the same thing, but I have no plan how to do it.

I totally agree with a USB_ALLOC_ENDPOINT(BULK_IN) approach. And with #6593, I'm not totally sure that 100% static descriptors are feasible.

I also see an issue with the current way of allocating descriptors via Kconfig: only one instance of a cdc_acm device is possible with the current implementation (and I can think of use cases where I'd like to have several cdc_acm interfaces to mux/demux stuff). In general, there is no hard reason why I shouldn't be able to use the same USB class more than once.

Ideally I'd like to be able to get an instance of device in the code, create an interface descriptor (or interface association descriptor) from that, create the USB configuration with the descriptors and the manufacturer & product strings, and reconfigure the USB device. I can try sketching out a few approaches.

Ideally I'd like to be able to get an instance of device in the code, create an interface descriptor (or interface association descriptor) from that, create the USB configuration with the descriptors and the manufacturer & product strings, and reconfigure the USB device. I can try sketching out a few approaches.

It would be nice to have it, but there is still a lot to do before, otherwise it is not consistent and not easy to maintain.
1) There are three usb class drivers / functions in sample that should be moved to subsys/usb beforehand:

  • samples/subsys/usb/dfu, WIP/RFC, see #4373
  • samples/subsys/usb/webusb, duplicate CDC ACM code
  • samples/bluetooth/hci_usb

2) Assignment of the endpoints at runtime should be implemented and class/function descriptors from usb_descriptor.c should be moved to the corresponding class/functions driver. I started it in #4661, but did not updated the PR any further because of #4373 and other projects, but as promised I will update it in the next days. This also will make it possible that only the interface descriptor is provided by the class/function driver and the user application (can/should) picks the class descriptors and assembles the device descriptor.

@jfischer-phytec-iot I can take care of hci_usb since I have created it and know the code

resolved via bf332d00047c31441ae6819f5cd8d0d0a157e2e4

Was this page helpful?
0 / 5 - 0 ratings