Skip to end of metadata
Go to start of metadata

The USB classes available in Micrium OS USB Device share some common characteristics. This section explains these characteristics and their interactions with the core layer. 

About Class Instances

The USB classes available in USB Device implement the concept of class instances. A class instance represents one function within a device. The function can be described by one interface or by a group of interfaces and belongs to a specific class.

Each USB class implementation has some configurations and functions in common, based on the concept of class instance. The common configurations and functions are presented in Table - Constants and Functions Related to the Concept of Multiple Class Instances. In the column title 'Constants or Function', the placeholder XXXX can be replaced by the name of the class: AUDIO (Audio for function names), CDC, HID, MSC, CDC_EEM or VENDOR (Vendor for function names).

Constant or FunctionDescription
.ClassInstanceQty (in structure USBD_XXXX_QTY_CFG)
Configures the maximum number of class instances.
.ConfigQty (in structure USBD_XXXX_QTY_CFG)Configures the maximum number of configurations per device. During the class initialization, a created class instance will be added to one or more configurations.
USBD_XXXX_Add()Creates a new class instance.
USBD_XXXX_CfgAdd()Adds an existing class instance to the specified device configuration.
Table - Constants and Functions Related to the Concept of Multiple Class Instances

In terms of code implementation, the class will declare a local global table that contains a class control structure. The size of the table is determined by the constant USBD_XXXX_CFG_MAX_NBR_DEV. This class control structure is associated with one class instance and will contain specific information to manage the class instance.

The following illustrations present several case scenarios. Each illustration includes a code listing that corresponds to the case scenario. 

Figure - Multiple Class Instances - FS Device (1 Configuration with 1 Interface) represents a typical USB device. The device is Full-Speed (FS) and contains a single configuration. The function of the device is described by one interface composed of a pair of endpoints for data communication. One class instance is created, and it will allow you to manage the entire interface with its associated endpoint.

Multiple Class Instances - FS Device (1 Configuration with 1 Interface)
Figure - Multiple Class Instances - FS Device (1 Configuration with 1 Interface)

The code corresponding to  Figure - Multiple Class Instances - FS Device (1 Configuration with 1 Interface) is shown in Listing - Multiple Class Instances - FS Device (1 Configuration with 1 Interface).

RTOS_ERR           err;
CPU_INT08U         class_0;
USBD_XXXX_QTY_CFG  qty_cfg;


qty_cfg.ClassInstanceQty = 1u;
qty_cfg.ConfigQty        = 1u;

USBD_XXXX_Init(&qty_cfg, &err);                                                                 (1)
if (err.Code != RTOS_ERR_NONE) {
    /* $$$$ Handle the error. */
}

class_0 = USBD_XXXX_Add(&err);                                                                  (2)
if (err.Code != RTOS_ERR_NONE) {
    /* $$$$ Handle the error. */
}

USBD_XXXX_ConfigAdd(class_0, dev_nbr, config_0, &err);                                          (3)
if (err.Code != RTOS_ERR_NONE) {
    /* $$$$ Handle the error. */
}
Listing - Multiple Class Instances - FS Device (1 Configuration with 1 Interface)

(1) Initialize the class. All internal variables, structures, and class ports will be initialized. Note that the Init() function in some classes may take other arguments.

(2) Create the class instance, which is class_0. The function USBD_XXXX_Add() allocates a class control structure associated with class_0. Depending on the class, USBD_XXXX_Add() may have additional parameters aside from the error code that represent class-specific information stored in the class control structure.

(3) Add the class instance, class_0, to the specified configuration number, config_0, on the device referenced by dev_nbrUSBD_XXXX_ConfigAdd() will create the interface 0 and its associated IN and OUT endpoints. As a result, the class instance encompasses the interface 0 and its endpoints. Any communication done on the interface 0 will use the class instance number, class_0.

Figure - Multiple Class Instances - HS/FS Device (2 Configurations and 1 Single Interface) represents an example of a high-speed capable device. The device can support High-Speed (HS) and Full-Speed (FS). The device will contain two configurations:

  • One valid if the device operates at full-speed
  • Another if it operates at high-speed

In each configuration, interface 0 is the same, but its associated endpoints are different. The difference will be the endpoint maximum packet size, which varies according to the speed. If a high-speed host enumerates this device, then by default, the device will work in high-speed mode and thus the high-speed configuration will be active. The host can learn about the full-speed capabilities by getting a Device_Qualifier descriptor followed by an Other_Speed_Configuration descriptor. These two descriptors describe a configuration of a high-speed capable device if it were operating at its other possible speed (refer to Universal Serial Bus 2.0 Specification revision 2.0, section 9.6, for more details about these descriptors).

In our example, the host may want to reset and enumerate the device again in full-speed mode. In this case, the full-speed configuration is active. But whatever the active configuration, the same class instance is used. Indeed, the same class instance can be added to different configurations, although a class instance cannot be added multiple times to the same configuration.

Figure - Multiple Class Instances - HS/FS Device (2 Configurations and 1 Single Interface)

The code corresponding to  Figure - Multiple Class Instances - HS/FS Device (2 Configurations and 1 Single Interface) is shown in Listing - Multiple Class Instances - HS/FS Device (2 Configurations and 1 Single Interface).

RTOS_ERR           err;
CPU_INT08U         class_0;
USBD_XXXX_QTY_CFG  qty_cfg;


qty_cfg.ClassInstanceQty = 1u;
qty_cfg.ConfigQty        = 2u;

USBD_XXXX_Init(&qty_cfg, &err);                                                                 (1)
if (err.Code != RTOS_ERR_NONE) {
    /* $$$$ Handle the error. */
}

class_0 = USBD_XXXX_Add(&err);                                                                  (2)
if (err.Code != RTOS_ERR_NONE) {
    /* $$$$ Handle the error. */
}

USBD_XXXX_ConfigAdd(class_0, dev_nbr, config_0_fs, &err);                                       (3)
if (err.Code != RTOS_ERR_NONE) {
    /* $$$$ Handle the error. */
}

USBD_XXXX_ConfigAdd(class_0, dev_nbr, config_0_hs, &err);                                       (4)
if (err.Code != RTOS_ERR_NONE) {
    /* $$$$ Handle the error. */
}
Listing - Multiple Class Instances - HS/FS Device (2 Configurations and 1 Single Interface)

(1) Initialize the class. Any internal variables, structures, and class ports will be initialized.

(2) Create the class instance, class_0. The function USBD_XXXX_Add() allocates a class control structure associated to class_0. Depending on the class, besides the parameter for an error code, USBD_XXXX_Add() may have additional parameters representing class-specific information stored in the class control structure.

(3) Add the class instance, class_0, to the full-speed configuration, config_0_fs. USBD_XXXX_ConfigAdd() will create the interface 0 and its associated IN and OUT endpoints. If the full-speed configuration is active, any communication done on the interface 0 will use the class instance number, class_0.

(4) Add the class instance, class_0, to the high-speed configuration, config_0_hs.

Figure - Multiple Class Instances - FS Device (2 Configurations and Multiple Interfaces) represents a more complex example. A full-speed device is composed of two configurations. The device has two functions which belong to the same class, but each function is described by two interfaces and has a pair of bidirectional endpoints.

In this example, two class instances are created. Each class instance is associated with a group of interfaces as opposed to  Figure - Multiple Class Instances - FS Device (1 Configuration with 1 Interface) and  Figure - Multiple Class Instances - HS/FS Device (2 Configurations and 1 Single Interface) where the class instance was associated with a single interface.

Multiple Class Instances - FS Device (2 Configurations and Multiple Interfaces)
Figure - Multiple Class Instances - FS Device (2 Configurations and Multiple Interfaces)

The code corresponding to  Figure - Multiple Class Instances - FS Device (2 Configurations and Multiple Interfaces) is shown in Listing - Multiple Class Instances - FS Device (2 Configurations and Multiple Interfaces). The error handling is omitted for clarity.

RTOS_ERR           err;
CPU_INT08U         class_0;
CPU_INT08U         class_1;
USBD_XXXX_QTY_CFG  qty_cfg;


qty_cfg.ClassInstanceQty = 2u;
qty_cfg.ConfigQty        = 2u; 

USBD_XXXX_Init(&qty_cfg, &err);                                                                 (1)

class_0 = USBD_XXXX_Add(&err);                                                                  (2)
class_1 = USBD_XXXX_Add(&err);                                                                  (3)

USBD_XXXX_ConfigAdd(class_0, dev_nbr, cfg_0, &err);                                             (4)
USBD_XXXX_ConfigAdd(class_1, dev_nbr, cfg_0, &err);                                             (5)

USBD_XXXX_ConfigAdd(class_0, dev_nbr, cfg_1, &err);                                             (6)
USBD_XXXX_ConfigAdd(class_1, dev_nbr, cfg_1, &err);                                             (6)
Listing - Multiple Class Instances - FS Device (2 Configurations and Multiple Interfaces)

(1) Initialize the class. Any internal variables, structures, and class ports will be initialized.

(2) Create the class instance, class_0. The function USBD_XXXX_Add() allocates a class control structure associated with class_0.

(3) Create the class instance, class_1. The function USBD_XXXX_Add() allocates another class control structure associated with class_1.

(4) Add the class instance, class_0, to the configuration, cfg_0. USBD_XXXX_ConfigAdd() will create the interface 0, interface 1, alternate interfaces, and the associated IN and OUT endpoints. The class instance number, class_0, will be used for any data communication on interface 0 or interface 1.

(5) Add the class instance, class_1, to the configuration, cfg_0. USBD_XXXX_ConfigAdd() will create the interface 2, interface 3 and their associated IN and OUT endpoints. The class instance number, class_1, will be used for any data communication on interface 2 or interface 3.

(6) Add the same class instances, class_0 and class_1, to the other configuration, cfg_1.

  • No labels