-
Notifications
You must be signed in to change notification settings - Fork 7.5k
USB Multi-instance support #12682
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
USB Multi-instance support #12682
Conversation
All checks are passing now. Review history of this comment for details about previous failed status. |
Codecov Report
@@ Coverage Diff @@
## master #12682 +/- ##
==========================================
- Coverage 48.62% 48.6% -0.03%
==========================================
Files 313 313
Lines 46441 46468 +27
Branches 10712 10722 +10
==========================================
Hits 22584 22584
- Misses 19398 19425 +27
Partials 4459 4459
Continue to review full report at Codecov.
|
Multi-instance what? |
Multiple USB classes (several CDC ACM devices, etc) |
HID class driver APIs have no instance parameter like cdc_acm's "struct device *dev", how HID class driver support multiple HID instances? For example: int hid_int_ep_write(const u8_t *data, u32_t data_len, u32_t *bytes_ret). From my viewpoint, it may be necessary to add the device instance parameter to the HID API, and implement one way to define configurable number of the HID interface/endpoint descriptors because the application determine the instances count. Other classes drivers have the same problem. How to support the multiple instances of controller and devce stack? for example: RT1050 has two USB controllers, Zephyr application cannot initialize two device stack instances to use the two controllers at the same time. From my viewpoint, it may be necessary to add the device instance parameter to the device stack API and controller API. If I am wrong, please let me know. |
@MarkWangChinese I will check also all other classes and push more commits for HID, etc. For the multi controller case, I need to think more, probably we need controller device model and change stack to use this specific device functions. |
Yep, I'd like all implementations of classes to be unified - i.e. defined as a device, all local data (control block) grouped in one structure which could be retrieved with device structure pointer and no other static variables (unless it's a common variable for all instances). A couple of ideas. Each instance will also need a configurable endpoint numbers (kconfig?) and I'd add a test routine executed during usb initialization (included only in debug build) which would go through all instances and check if user has not overlapped EPs in class configurations. |
usb_hid_init(); | ||
usb_hid_register_device(hid_dev, hid_report_desc, | ||
sizeof(hid_report_desc), NULL); | ||
usb_hid_init(hid_dev); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my opinion something like:
usb_hid_register_device(hid_dev, hid_report_desc, sizeof(hid_report_desc), NULL);
usb_cdc_register_device(cdc_dev, ...);
/* other instances or classes registered */
usb_init();
would work better with applications that use multiple classes and multiple instances. Initialization done currently in usb_hid_init()
can be moved to hid_status_cb()
with new event, for example USB_DC_INITIALIZED
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACM CDC is different from the other classes since it has (serial) device already, all other classes should have device similar to HID Device.
About usb_hid_init()
: if we move general init to usb_init()
then the remaining part we can move to usb_hid_register_device()
@masz-nordic @pawelzadrozniak @jfischer-phytec-iot Can you please revisit this PR? |
Add menuconfig option to select another instance of CDC ACM device. Signed-off-by: Andrei Emeltchenko <[email protected]>
Add configuration option for enabling second HID Device Signed-off-by: Andrei Emeltchenko <[email protected]>
Add HID Device associated with the instance of the HID. This allows to create several HID instances for multifunction composite device. Signed-off-by: Andrei Emeltchenko <[email protected]>
Use new HID Device interface for HID sample Signed-off-by: Andrei Emeltchenko <[email protected]>
Refactor of hid-mouse and using new HID Device interface. Signed-off-by: Andrei Emeltchenko <[email protected]>
Use new HID Device interface for tests/boards/intel_s1000_crb Signed-off-by: Andrei Emeltchenko <[email protected]>
Refactor sample using new HID Device interface. Signed-off-by: Andrei Emeltchenko <[email protected]>
Use new multi instance interface and new port names. Signed-off-by: Andrei Emeltchenko <[email protected]>
Change argument for get_dev_data_by_iface(). Signed-off-by: Andrei Emeltchenko <[email protected]>
Reduce time by using the helper. Signed-off-by: Andrei Emeltchenko <[email protected]>
Add conversion since interface number is stored in lower byte of wIndex. Signed-off-by: Andrei Emeltchenko <[email protected]>
Add helpers to be used in USB classes for getting device data. Signed-off-by: Andrei Emeltchenko <[email protected]>
Use new interface for getting device data. Signed-off-by: Andrei Emeltchenko <[email protected]>
Use device data interface to handle device data. Signed-off-by: Andrei Emeltchenko <[email protected]>
Add sample creating 2 serial USB ports and establishing communication between those 2 ports. Signed-off-by: Andrei Emeltchenko <[email protected]>
Add README describing the sample. Signed-off-by: Andrei Emeltchenko <[email protected]>
Remove unneeded "depends on" and use "if USB_CDC_ACM" instead of. Signed-off-by: Andrei Emeltchenko <[email protected]>
Add prefixes to MSC enumerators, otherwise they are (ERROR) are conflicting with other enumerators. ... subsys/usb/class/mass_storage.c:149:2: error: redeclaration of enumerator ‘ERROR’ ERROR, /* error */ ^~~~~ ... ext/hal/st/stm32cube/stm32f4xx/soc/stm32f4xx.h:216:3: note: previous definition of ‘ERROR’ was here ERROR = 0U, ^~~~~ ... Signed-off-by: Andrei Emeltchenko <[email protected]>
config CDC_ACM_PORT_1 | ||
bool "Enable virtual port 1" | ||
help | ||
Enable CDC ACM Virtual port 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not virtual, where does it come from? Also "class device driver port name" sounds strange, why not "CDC ACM class name" or "CDC ACM interface name"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jfischer-phytec-iot interface
and class
might be misunderstood in USB. What about 'CDC_ACM_DEVICE_1`
Also another question: Is this OK to have number of instances defined in menuconfig?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wondering if we specify only number of instances, can we create number of devices with macros in include/misc/util.h
struct usb_cfg_data *cfg = &__usb_data_start[i]; | ||
|
||
if (cfg->cb_usb_status_composite) { | ||
cfg->cb_usb_status_composite(cfg, status, param); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From my understanding, it need calls cfg->cb_usb_status too as follow if cb_usb_status_composite is NULL and cb_usb_status is not NULL.
if (cfg->cb_usb_status_composite) {
cfg->cb_usb_status_composite(cfg, status, param);
} else if (cfg->cb_usb_status) {
cfg->cb_usb_status(status, param);
}
For example: mass1 + cdc_acm1 + cdc_acm2, the mass storage class driver use cb_usb_status and cdc class driver use cb_usb_status_composite.
Or we can remove cb_usb_status and replace cb_usb_status with cb_usb_status_composite, and rename cb_usb_status_composite as another name.
Please let me know if I am wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For composite configuration we need to add cb_usb_status_composite
to MSC. Even if now only one instance of MSC can be enabled.
Probably renaming callback would be the right approach. So we might have common callback with NULL
parameter for non composite configuration in place of cfg
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is better to rename the callback.
Do you plan to add device instance (struct device *dev ) to all USB class drivers? for example: MSC.
If you plan add it, is it better to add one (struct device *dev) parameter to the follow callback functions?
usb_request_handler class_handler;
usb_request_handler vendor_handler;
usb_request_handler custom_handler;
usb_dc_status_callback cb_usb_status;
void (*cb_usb_status_composite)(struct usb_cfg_data *cfg,
enum usb_dc_status_code cb_status,
const u8_t *param);
And add the device_name (const char *dev_name) to struct usb_cfg_data.
After these changes, the usb_get_dev_data_by_cfg, usb_get_dev_data_by_iface and usb_get_dev_data_by_ep are not needed any more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MarkWangChinese fc34152a3bc7cfa7e668d2bd4524d9727725fe99 renames callbacks. There is other PR #13310. You can comment there, since this PR is merged already.
void (*cb_usb_status_composite)(struct usb_cfg_data *cfg, | ||
enum usb_dc_status_code cb_status, | ||
const u8_t *param); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#ifdef CONFIG_USB_COMPOSITE_DEVICE may be needed for the above added lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will fix it in the follow up patches
This is RFC for proposed way of multi - instance USB class support.
Multi - instance means that the same instances of some class might be included to the code, for example 2 CDC ACM (Serial ports). Before you could include only one instance of the same class.
I have created sample illustrating this possibility with 2 USB serial ports.