eclipse-threadx / usbx

Eclipse ThreadX - USBX is a high-performance USB host, device, and on-the-go (OTG) embedded stack, that is fully integrated with Eclipse ThreadX RTOS
https://github.com/eclipse-threadx/rtos-docs/blob/main/rtos-docs/usbx/index.md
MIT License
154 stars 89 forks source link

How to logically enable/disable USB classes? #53

Closed maxkunes closed 2 years ago

maxkunes commented 2 years ago

If I have a composite device connected to a PC that has CDC and MSD, is there any way to logically enable/disable one or both functions without changing the descriptor?

Say I want my device to mount a serial port on startup and the PC would have to send a message to the serial port to "enable" the MSD USB device. Meaning that at some time after startup, I want my device to provide a storage device to the PC which is not there initially.

I assume it's possible to have multiple descriptor configurations (one composite MSD + CDC, one CDC, one MSD) that during runtime can be switched and the stack has to be re-inited, but I'm wondering if there is a better option (assuming the former is even possible without pulling the USB cable in and out of the PC)

The reason why I want to logically enable/disable it is I think in any other way, the serial device would have to be remounted which could interfere with my application that is communicating over the link.

Assuming its possible to use the composite descriptor for this task, can I enable and disable certain classes that a composite device has after initialization? From what I can tell, if I simply "unregister" one of the classes, I don't see behavior that I would expect. The PC doesn't unmount the storage device properly and will hang when accessed again.

xiaocq2001 commented 2 years ago
  1. Assume on host side multiple configurations are supported (it's supported by USB spec but I'm not sure what's the status for such case on PC): In case there are multiple configurations with different interfaces, for each configuration and interface pair a class must be registered. E.g., The framework include: Configuration 1, including MSD at interface 0 and CDC at interface 1,2 Configuration 2, including MSD at interface 0 Configuration 3, including CDC at interface 0,1 For such configuration you should register class as following: MSD at configuration 1, interface 0 CDC at configuration 1, interface 1 MSD at configuration 2, interface 0 CDC at configuration 3, interface 0 In such case, if host select different configuration, the different registered class instances are activated and can be used.

  2. Assume on device side multiple descriptors are used for different frameworks, to switch: Detach device (of previous framework, e.g., MSD + CDC) Uninitialize DCD Unregister classes (e.g., MSD, CDC) Uninitialize device stack Initialize device stack with new framework (e.g., MSD) Register class (e.g., MSD) Initialize DCD (In such step it can be Attached to host) Please note class register/unregister will not do USB attach/detach or descriptor changes. To change framework reported to host, device stack must be uninitialize and initialize again, with new framework. Before stack uninitialize classes registered must be unregistered.

maxkunes commented 2 years ago

The first option is where the configuration is controlled by the host. So that doesn't really apply here.

And the second option is a matter of changing descriptors and reinitializing. Is that correct?

Anyways, if that's the case-- this can be closed. Thanks for the clarification.

xiaocq2001 commented 2 years ago

Yes, the second option is changing descriptors and reinitializing. That's the only way to inform host that the functionalities in a device has been changed.

maxkunes commented 2 years ago

Ok, thanks!

minnee2 commented 3 months ago
  1. Assume on host side multiple configurations are supported (it's supported by USB spec but I'm not sure what's the status for such case on PC): In case there are multiple configurations with different interfaces, for each configuration and interface pair a class must be registered. E.g., The framework include: Configuration 1, including MSD at interface 0 and CDC at interface 1,2 Configuration 2, including MSD at interface 0 Configuration 3, including CDC at interface 0,1 For such configuration you should register class as following: MSD at configuration 1, interface 0 CDC at configuration 1, interface 1 MSD at configuration 2, interface 0 CDC at configuration 3, interface 0 In such case, if host select different configuration, the different registered class instances are activated and can be used.
  2. Assume on device side multiple descriptors are used for different frameworks, to switch: Detach device (of previous framework, e.g., MSD + CDC) Uninitialize DCD Unregister classes (e.g., MSD, CDC) Uninitialize device stack Initialize device stack with new framework (e.g., MSD) Register class (e.g., MSD) Initialize DCD (In such step it can be Attached to host) Please note class register/unregister will not do USB attach/detach or descriptor changes. To change framework reported to host, device stack must be uninitialize and initialize again, with new framework. Before stack uninitialize classes registered must be unregistered.

@xiaocq2001 Could you by chance be a little more explicit of each step in terms of API calls? I'm trying to do the translation of these device directions (2) to code, would be nice to verify