Migration Guide to Silicon Labs USB Device Stack#

Overview#

The following are main differences between the Silicon Labs USB Device stack and Micrium OS USB Device stack:

  • Silicon Labs USB Device stack only supports one USB device.

  • Silicon Labs USB Device stack does not support High Speed.

  • Silicon Labs USB Device stack does not support the Audio class and the CDC EEM subclass.

  • Silicon Labs USB Device stack does not support Isochronous endpoints.

  • Silicon Labs USB Device stack uses compile-time #defines for configuration.

  • Silicon Labs USB Device stack does not use dynamic allocation. Required data is allocated statically.

  • Silicon Labs USB Device stack uses the CMSIS-RTOS2 abstraction layer and can therefore work with different OSes.

  • Silicon Labs USB Device stack has a better hardware integration; No BSP and Platform Manager integration are required unlike with MicriumOS.

  • Silicon Labs APIs return a sl_status_t integer code instead of the MicriumOS RTOS_ERR struct.

Initialization#

Unlike Micrium OS, Silicon Labs USB Device stack does not use dynamic allocation to initialize the different pool objects needed. As a result, notice that you don't need to pass any USBD_XXXX_QTY_CFG type argument with initialization functions. Instead, set a compile-time #define-s in the sl_usbd_core_config.h file. The quantity fields in the different USBD_XXXX_QTY_CFG structures should all have an associated #define, except if the feature is no longer supported by Silicon Labs stack.

As mentioned, Silicon Labs stack only handles one USB Device. The driver for the USB device controller is integrated with the stack. As a result, you don't need a BSP or the Platform Manager. The only required hardware configuration is the GPIO setup when the VBUS SENSE signal is used, which is configurable inside the sl_usbd_driver_config.h file.

Note that if you are using Silicon Labs Simplicity Studio and the Project Configuration Tools, all your USB Device initialization code can be generated and integrated to the system initialization code of your project automatically. All you need to do is set up your project file accordingly. For examples about how to use Project Configuration Tools, see USB Device sample apps in Simplicity Studio.

See API function mapping tables at section API Names Equivalence to help migrate your code to Silicon Labs USB Device stack. Examples below also show the main differences during the initialization process between Micrium OS-USBD and Silicon Labs USB Device.

Example - Core Initialization with Micrium OS shows how the USB Device core initialization was done with Micrium OS-USBD stack and Example - Core Initialization with Silicon Labs shows how to perform the same initialization with the Silicon Labs stack.

Example - Core Initialization with Micrium OS#
  CPU_INT08U       config_nbr_fs;
  CPU_INT08U       dev_nbr;
  USBD_QTY_CFG     cfg_qty_usbd;
  USBD_DEV_CFG     cfg_usbd_dev;
  USBD_DEV_DRV_CFG cfg_usbd_dev_drv;
  USBD_DEV_CFG     cfg_usbd_dev;
  USBD_DEV_DRV_CFG cfg_usbd_dev_drv;
  RTOS_ERR         err;

  // Initializing USB device module                                  (1)
  cfg_qty_usbd.DevQty = 1u;
  cfg_qty_usbd.ConfigQty = 2u;
  cfg_qty_usbd.IF_Qty = 10u;
  cfg_qty_usbd.IF_AltQty = 10u;
  cfg_qty_usbd.IF_GrpQty = 2u;
  cfg_qty_usbd.EP_DescQty = 10u;
  cfg_qty_usbd.URB_ExtraQty = 10u;
  cfg_qty_usbd.StrQty = 15u;
  cfg_qty_usbd.EP_OpenQty = 10u;

  USBD_Init(&cfg_qty_usbd, &err);
  if (err.Code != RTOS_ERR_NONE) {
    // An error occurred. Error handling should be added here.
  }

  // Adding Device with controller info                              (2)
  cfg_usbd_dev.ProductID = 0x1234u;
  cfg_usbd_dev.ProductID = 0x1001u;
  cfg_usbd_dev.ProductID = 0x0001u;
  cfg_usbd_dev.VendorID = 0xFFFEu;
  cfg_usbd_dev.DeviceBCD = 0x0100u;
  cfg_usbd_dev.ManufacturerStrPtr = "Micrium inc";
  cfg_usbd_dev.ProductStrPtr = "Product";
  cfg_usbd_dev.SerialNbrStrPtr = "1234567890ABCDEF";
  cfg_usbd_dev.LangId = USBD_LANG_ID_ENGLISH_US;

  cfg_usbd_dev_drv.EP_OpenQty = 10u;
  cfg_usbd_dev_drv.URB_ExtraQty = 0u;

  dev_nbr = USBD_DevAdd(EX_USBD_CTRLR_NAME,
                        DEF_NULL,
                        &cfg_usbd_dev,
                        &cfg_usbd_dev_drv,
                        DEF_NULL,
                        &err);
  if (err.Code != RTOS_ERR_NONE) {
    // An error occurred. Error handling should be added here.
  }

  // Adding full-speed configuration                                 (3)
  config_nbr_fs = USBD_ConfigAdd(dev_nbr,
                                 DEF_BIT_NONE,
                                 100u,
                                 USBD_DEV_SPD_FULL,
                                 "Full-Speed config",
                                 &err);
  if (err.Code != RTOS_ERR_NONE) {
    // An error occurred. Error handling should be added here.
  }

(1) Instead of calling USBD_Init(), call sl_usbd_core_init(). The USBD_QTY_CFG argument is not needed. Instead, set the pool quantities in the sl_usbd_core_config.h file.

(2) Because Silicon Labs USB Device stack supports only one USB Device, you don't need to call any API function to add a USB device. Instead of the USBD_DEV_CFG argument, the device information can be configured in the sl_usbd_device_config.h file. Because the driver is integrated to the stack, no USBD_DEV_DRV_CFG argument needs to be passed to the USB device stack.

(3) Instead of calling USBD_ConfigAdd(), call sl_usbd_core_add_configuration() to add a new configuration. This new function does not take a device_number argument since only one device can be handled by the stack.

Example - Core Initialization with Silicon Labs#
sl_status_t  status;
uint8_t      config_nbr_fs;

// Initializing USB device module
status = sl_usbd_core_init();
if (status != SL_STATUS_OK) {
  // An error occurred. Error handling should be added here.
}


// Adding a full-speed configuration to the device
status = sl_usbd_core_add_configuration(0,
                                        100u,
                                        SL_USBD_DEVICE_SPEED_FULL,
                                        "Full-Speed config",
                                        &config_nbr_fs);
if (status != SL_STATUS_OK) {
  // An error occured. Error handling should be added here.
}

Classes are also initialized differently. The following examples show CDC-ACM and highlight differences. Example - CDC ACM Class Initialization with Micrium OS shows how the CDC ACM Class was initialized with Micrium OS-USBD stack and Example - CDC ACM Class Initialization with Silicon Labs shows how the same is now done with Silicon Labs USB Device stack. Note that the migration process will be very similar for the other supported classes and therefore only the CDC ACM example is shown.

Example - CDC ACM Class Initialization with Micrium OS#
  CPU_INT08U       cdc_acm_nbr;
  USBD_CDC_QTY_CFG cfg_qty_cdc;
  RTOS_ERR         err;

  // Initializing CDC base class                                     (1)
  cfg_qty_cdc.ClassInstanceQty = 1u;
  cfg_qty_cdc.ConfigQty = 2u;
  cfg_qty_cdc.DataIF_Qty = 2u;

  USBD_CDC_Init(&cfg_qty_cdc, &err);
  if (err.Code != RTOS_ERR_NONE) {
    // An error occurred. Error handling should be added here.
  }

  // Initializing ACM subclass                                       (2)
  USBD_ACM_SerialInit(1u, &err);
  if (err.Code != RTOS_ERR_NONE) {
    // An error occurred. Error handling should be added here.
  }

  // Create CD ACM class instance                                    (3)
  cdc_acm_nbr = USBD_ACM_SerialAdd(64u,
                                   (USBD_ACM_SERIAL_CALL_MGMT_DATA_CCI_DCI | USBD_ACM_SERIAL_CALL_MGMT_DEV),
                                   &err);
  if (err.Code != RTOS_ERR_NONE) {
    // An error occurred. Error handling should be added here.
  }

  // Add class instance to config                                    (4)
  USBD_ACM_SerialConfigAdd(cdc_acm_nbr,
                           dev_nbr,
                           config_nbr_fs,
                           &err);
  if (err.Code != RTOS_ERR_NONE) {
    // An error occurred. Error handling should be added here.
  }

  // Register line coding and ctrl line change callbacks.            (5)
  // These 2 calls are optinnal.
  USBD_ACM_SerialLineCodingReg(cdc_acm_nbr,
                               App_USBD_CDC_ACM_TerminalLineCoding,
                               DEF_NULL,
                               &err);
  if (err.Code != RTOS_ERR_NONE) {
    // An error occurred. Error handling should be added here.
  }

  USBD_ACM_SerialLineCtrlReg(cdc_acm_nbr,
                             App_USBD_CDC_ACM_TerminalLineCtrl,
                             DEF_NULL,
                             &err);
  if (err.Code != RTOS_ERR_NONE) {
    // An error occurred. Error handling should be added here.
  }

(1) Instead of calling USBD_CDC_Init(), call sl_usbd_cdc_init(). Instead of passing a configuration structure of type USBD_QTY_CFG, set the pool quantities in the sl_usbd_core_config.h file

(2) Instead of calling USBD_ACM_SerialInit(), call sl_usbd_cdc_acm_init(). Instead of passing a subclass_instance_qty argument, set the pool quantity for CDC ACM in the sl_usbd_core_config.h file.

(3) Instead of calling USBD_ACM_SerialAdd(), call sl_usbd_cdc_acm_create_instance().

(4) Instead of calling USBD_ACM_SerialConfigAdd(), call sl_usbd_cdc_acm_add_to_configuration(). Not need for dev_nbr argument.

(5) Instead of using functions USBD_ACM_SerialLineCodingReg() and USBD_ACM_SerialLineCtrlReg() to register callback functions, pass an sl_usbd_cdc_acm_callbacks_t argument to sl_usbd_cdc_acm_create_instance().

Example - CDC ACM Class Initialization with Silicon Labs#
sl_status_t  status;
uint8_t      subclass_nbr;


// Callback functions
sl_usbd_cdc_acm_callbacks_t app_usbd_cdc_acm_callbacks = {
  app_usbd_cdc_acm_connect,
  app_usbd_cdc_acm_disconnect,
  app_usbd_cdc_acm_line_control_changed,
  app_usbd_cdc_acm_line_coding_changed,
};

// Initializing CDC base class
status = sl_usbd_cdc_init();
if (status != SL_STATUS_OK) {
  // An error occurred. Error handling should be added here.
}

// Initializing ACM subclass
status = sl_usbd_cdc_acm_init();
if (status != SL_STATUS_OK) {
  // An error occurred. Error handling should be added here.
}

// Create CD ACM class instance
status = sl_usbd_cdc_acm_create_instance(64u,
                                         SL_USBD_ACM_SERIAL_CALL_MGMT_DATA_CCI_DCI | SL_USBD_ACM_SERIAL_CALL_MGMT_DEV,
                                         app_usbd_cdc_acm_callbacks,
                                         &subclass_nbr);
if (status != SL_STATUS_OK) {
  // An error occurred. Error handling should be added here.
}

// Add class instance to config
status = sl_usbd_cdc_acm_add_to_configuration(subclass_nbr,
                                              config_nbr_fs);
if (status != SL_STATUS_OK) {
  // An error occurred. Error handling should be added here.
}

API Names Equivalence#

Tables below show the API mapping between the deprecated MicriumOS-USBD stack and the new Silicon Labs USB Device stack.

Core API Functions#

MicriumOS USBD

Silicon Labs USB Device

Information

USBD_ConfigureBufAlignOctets()

NA

The internal buffers are already aligned to match the USB Controller requirement.

USBD_ConfigureMemSeg()

NA

Silicon Labs USB device stack does not use dynamic allocation. Required data is allocated statically.

USBD_Init()

sl_usbd_core_init()

USBD_DevAdd()

NA

Silicon Labs USB Device Stack supports only one device that is automatically added when initializing the stack.

USBD_DevTaskPrioSet()

-

You can configure the USB Device core task priority at compile-time with SL_USBD_TASK_PRIORITY configuration.

USBD_DevNbrGetFromName()

NA

Only one device is supported with Silicon Labs USB device stack.

USBD_DevStart()

sl_usbd_core_start_device()

With Silicon Labs USB Device stack, SL_USBD_AUTO_START_USB_DEVICE configuration allows you to automatically start the device when enabled. In that case, no need to call sl_usbd_core_start_device().

USBD_DevStop()

sl_usbd_core_stop_device()

USBD_DevStateGet()

sl_usbd_core_get_device_state()

USBD_DevSpdGet()

sl_usbd_core_get_device_speed()

USBD_DevSelfPwrSet()

sl_usbd_core_set_device_self_power()

USBD_DevSetMS_VendorCode()

NA

Microsoft OS descriptors are not supported by Silicon Labs USB Device stack.

USBD_DevGetCfg()

sl_usbd_core_get_device_configuration()

USBD_DevFrameNbrGet()

sl_usbd_core_get_device_frame_number()

USBD_ConfigAdd()

sl_usbd_core_add_configuration()

USBD_ConfigOtherSpeed()

NA

Silicon Labs USB device stack does not support High Speed mode.

USBD_IF_Add()

sl_usbd_core_add_interface()

USBD_IF_AltAdd()

sl_usbd_core_add_alt_interface()

USBD_IF_Grp()

sl_usbd_core_add_interface_group()

USBD_DescDevGet()

sl_usbd_core_get_device_descriptor()

USBD_DescConfigGet()

sl_usbd_core_get_configuration_descriptor()

USBD_DescStrGet()

sl_usbd_core_get_string_descriptor()

USBD_StrAdd()

sl_usbd_core_add_string()

USBD_StrIxGet()

sl_usbd_core_get_string_index()

USBD_DescWr08()

sl_usbd_core_write_08b_to_descriptor_buf()

USBD_DescWr16()

sl_usbd_core_write_16b_to_descriptor_buf()

USBD_DescWr24()

sl_usbd_core_write_24b_to_descriptor_buf()

USBD_DescWr32()

sl_usbd_core_write_32b_to_descriptor_buf()

USBD_DescWr()

sl_usbd_core_write_buf_to_descriptor_buf()

USBD_CtrlRx()

sl_usbd_core_write_control_sync()

USBD_CtrlTx()

sl_usbd_core_read_control_sync()

USBD_BulkAdd()

sl_usbd_core_add_bulk_endpoint()

USBD_BulkRx()

sl_usbd_core_read_bulk_sync()

USBD_BulkRxAsync()

sl_usbd_core_read_bulk_async()

USBD_BulkTx()

sl_usbd_core_write_bulk_sync()

USBD_BulkTxAsync()

sl_usbd_core_write_bulk_async()

USBD_IntrAdd()

sl_usbd_core_add_interrupt_endpoint()

USBD_IntrRx()

sl_usbd_core_read_interrupt_sync()

USBD_IntrRxAsync()

sl_usbd_core_read_interrupt_async()

USBD_IntrTx()

sl_usbd_core_write_interrupt_sync()

USBD_IntrTxAsync()

sl_usbd_core_write_interrupt_async()

USBD_IsocAdd()

NA

Isochronous endpoints are not supported.

USBD_IsocSyncRefreshSet()

NA

Isochronous endpoints are not supported.

USBD_IsocSyncAddrSet()

NA

Isochronous endpoints are not supported.

USBD_IsocRxAsync()

NA

Isochronous endpoints are not supported.

USBD_IsocTxAsync()

NA

Isochronous endpoints are not supported.

USBD_EP_TxZLP()

sl_usbd_core_endpoint_write_zlp()

USBD_EP_RxZLP()

sl_usbd_core_endpoint_read_zlp()

USBD_EP_Abort()

sl_usbd_core_abort_endpoint()

USBD_EP_Stall()

sl_usbd_core_stall_endpoint()

USBD_EP_IsStalled()

sl_usbd_core_is_endpoint_stalled()

USBD_EP_MaxPktSizeGet()

sl_usbd_core_get_max_endpoint_packet_size()

USBD_EP_MaxPhyNbrGet()

sl_usbd_core_get_max_phy_endpoint_number()

USBD_EP_MaxNbrOpenGet()

sl_usbd_core_get_max_open_endpoint_number()

CDC ACM Class API Functions#

MicriumOS USBD

Silicon Labs USB Device

Information

CDC API Functions

USBD_CDC_ConfigureMemSeg()

NA

Silicon Labs USB device stack does not use dynamic allocation. Required data is allocated statically.

USBD_CDC_Init()

sl_usbd_cdc_init()

USBD_CDC_Add()

sl_usbd_cdc_create_instance()

USBD_CDC_ConfigAdd()

sl_usbd_cdc_add_to_configuration()

USBD_CDC_IsConn()

sl_usbd_cdc_is_enabled()

USBD_CDC_DataIF_Add()

sl_usbd_cdc_add_data_interface()

USBD_CDC_DataRx()

sl_usbd_cdc_read_data()

USBD_CDC_DataTx()

sl_usbd_cdc_write_data()

USBD_CDC_Notify()

sl_usbd_cdc_notify_host()

CDC ACM API Functions

USBD_ACM_SerialConfigureBufAlignOctets()

NA

The internal buffers are already aligned to match the USB Controller requirement.

USBD_ACM_SerialConfigureMemSeg()

NA

Silicon Labs USB device stack does not use dynamic allocation. Required data is allocated statically.

USBD_ACM_SerialInit()

sl_usbd_cdc_acm_init()

USBD_ACM_SerialAdd()

sl_usbd_cdc_acm_create_instance()

USBD_ACM_SerialConfigAdd()

sl_usbd_cdc_acm_add_to_configuration()

USBD_ACM_SerialIsConn()

sl_usbd_cdc_acm_is_enabled()

USBD_ACM_SerialRx()

sl_usbd_cdc_acm_read()

USBD_ACM_SerialTx()

sl_usbd_cdc_acm_write()

USBD_ACM_SerialLineCtrlGet()

sl_usbd_cdc_acm_get_line_control_state()

USBD_ACM_SerialLineCodingGet()

sl_usbd_cdc_acm_get_line_coding()

USBD_ACM_SerialLineCodingSet()

sl_usbd_cdc_acm_set_line_coding()

USBD_ACM_SerialLineStateSet()

sl_usbd_cdc_acm_set_line_state_event()

USBD_ACM_SerialLineStateClr()

sl_usbd_cdc_acm_clear_line_state_event()

USBD_ACM_SerialLineCtrlReg()

-

Use the p_acm_callbacks argument of sl_usbd_cdc_acm_create_instance() to register callback functions. In the sl_usbd_cdc_acm_callbacks_t struct, you have the line_control_changed field to register a callback function to notify you of Line Control changes.

USBD_ACM_SerialLineCodingReg()

-

Use the p_acm_callbacks argument of sl_usbd_cdc_acm_create_instance() to register callback functions. In the sl_usbd_cdc_acm_callbacks_t struct, you have the line_coding_changed field to register a callback function to notify you of Line Coding changes.

HID Class API Functions#

MicriumOS USBD

Silicon Labs USB Device

Information

USBD_HID_ConfigureBufAlignOctets()

NA

The internal buffers are already aligned to match the USB Controller requirement.

USBD_HID_ConfigureReportID_Qty()

-

You can configure the number of HID report IDs at compile-time with SL_USBD_HID_REPORT_ID_QUANTITY configuration.

USBD_HID_ConfigurePushPopItemsQty()

-

You can configure the number of HID push/pop items at compile-time with SL_USBD_HID_PUSH_POP_ITEM_QUANTITY configuration.

USBD_HID_ConfigureMemSeg()

NA

Silicon Labs USB device stack does not use dynamic allocation. Required data is allocated statically.

USBD_HID_ConfigureTmrTaskStk()

-

You can configure the HID Timer task priority at compile-time with SL_USBD_TASK_PRIORITY configuration.

USBD_HID_Init()

sl_usbd_hid_init()

USBD_HID_TmrTaskPrioSet()

-

You can configure the HID Timer task stack size at compile-time with SL_USBD_HID_TIMER_TASK_STACK_SIZE configuration.

USBD_HID_Add()

sl_usbd_hid_create_instance()

USBD_HID_ConfigAdd()

sl_usbd_hid_add_to_configuration()

USBD_HID_IsConn()

sl_usbd_hid_is_enabled()

USBD_HID_Rd()

sl_usbd_hid_read_sync()

USBD_HID_Wr()

sl_usbd_hid_write_sync()

-

sl_usbd_hid_write_async()

-

sl_usbd_hid_read_async()

MSC Class API Functions#

MicriumOS USBD

Silicon Labs USB Device

Information

USBD_MSC_ConfigureBufAlignOctets()

NA

The internal buffers are already aligned to match the USB Controller requirement.

USBD_MSC_ConfigureDataBufLen()

-

You can configure the MSC buffer size at compile-time with SL_USBD_MSC_DATA_BUFFER_SIZE configuration.

USBD_MSC_ConfigureMemSeg()

NA

Silicon Labs USB device stack does not use dynamic allocation. Required data is allocated statically.

USBD_MSC_Init()

sl_usbd_msc_init() and sl_usbd_msc_scsi_init()

Silicon Labs USB Device splits the MSC class and SCSI subclass functions. Both init functions need to be call when SCSI subclass used.

USBD_MSC_Add()

sl_usbd_msc_create_instance() and sl_usbd_msc_scsi_create_instance()

Silicon Labs USB Device splits the MSC class and SCSI subclass functions. Only the SCSI function needs to be call when SCSI subclass is used.

USBD_MSC_TaskPrioSet()

-

You can configure each MSC instance task priority at compile-time with SL_USBD_MSC_SCSI_<INSTANCE>_TASK_PRIORITY configuration.

USBD_MSC_ConfigAdd()

sl_usbd_msc_add_to_configuration() and sl_usbd_msc_scsi_add_to_configuration()

Silicon Labs USB Device splits the MSC class and SCSI subclass functions. Only the SCSI function needs to be call when SCSI subclass is used.

USBD_MSC_IsConn()

sl_usbd_msc_is_enabled() and sl_usbd_msc_scsi_is_enabled()

USBD_MSC_SCSI_LunAdd()

sl_usbd_msc_lun_add() and sl_usbd_msc_scsi_lun_add()

USBD_MSC_SCSI_LunAttach()

sl_usbd_msc_scsi_lun_attach()

USBD_MSC_SCSI_LunDetach()

sl_usbd_msc_scsi_lun_detach()

-

sl_usbd_msc_scsi_lun_get_capacity()

Vendor Class API Functions#

MicriumOS USBD

Silicon Labs USB Device

Information

USBD_Vendor_ConfigureMsExtPropertiesQty()

NA

Microsoft OS descriptors are not supported by Silicon Labs USB Device stack.

USBD_Vendor_ConfigureMemSeg()

NA

Silicon Labs USB device stack does not use dynamic allocation. Required data is allocated statically.

USBD_Vendor_Init()

sl_usbd_vendor_init()

USBD_Vendor_Add()

sl_usbd_vendor_create_instance()

USBD_Vendor_ConfigAdd()

sl_usbd_vendor_add_to_configuration()

USBD_Vendor_IsConn()

sl_usbd_vendor_is_enabled()

USBD_Vendor_IntrRd()

sl_usbd_vendor_read_interrupt_sync()

USBD_Vendor_IntrRdAsync()

sl_usbd_vendor_read_interrupt_async()

USBD_Vendor_IntrWr()

sl_usbd_vendor_write_interrupt_sync()

USBD_Vendor_IntrWrAsync()

sl_usbd_vendor_write_interrupt_async()

USBD_Vendor_MS_ExtPropertyAdd()

NA

Microsoft OS descriptors are not supported by Silicon Labs USB Device stack.

USBD_Vendor_Rd()

sl_usbd_vendor_read_bulk_sync()

USBD_Vendor_RdAsync()

sl_usbd_vendor_read_bulk_async()

USBD_Vendor_Wr()

sl_usbd_vendor_write_bulk_sync()

USBD_Vendor_WrAsync()

sl_usbd_vendor_write_bulk_async()