USBX FAQ

Frequently asked questions about USBX on STM32

This FAQ answers common questions when getting started with USBX or when USB does not behave as expected on STM32.

General questions

Q1. What is USBX and what is it used for?

USBX is the USB stack from Azure RTOS.

It helps you add USB device and/or USB host features to your STM32, for example:

  • Virtual COM port

  • USB mass storage (USB flash drive)

  • USB keyboard or mouse

  • Other standard USB classes

USBX runs on STM32 together with:

  • The STM32 HAL USB drivers (PCD/HCD)

  • Either an RTOS (for example Azure RTOS) or bare-metal (standalone) mode

  • Optional components like FileX if you need a file system on a USB disk

Q2. What is the difference between USB device mode and USB host mode?

  • USB device mode

    The STM32 behaves like a USB device connected to a PC or another host.

    Examples: virtual COM port, USB mouse, USB memory stick.

  • USB host mode

    The STM32 behaves like a USB host, similar to a PC.

    Examples: read a USB flash drive, connect a USB keyboard.

USBX supports both modes. You must configure the STM32 USB peripheral and USBX for the mode you want to use.

Q3. USBX is running but nothing is detected on the USB bus. Where do I start?

If “nothing happens” when you plug the USB cable:

  1. Check hardware and power

    • USB peripheral clock is enabled.

    • USB pins (DM/DP) and VBUS/ID pins are correctly configured.

    • The board is powered and VBUS is present when expected.

  2. Check PHY selection

    • The correct FS (Full Speed) or HS (High Speed) PHY is selected.

    • If you use an external HS PHY, ensure it is powered and correctly initialized.

  3. Check interrupts

    • The correct USB IRQ is enabled in the NVIC.

    • The STM32 HAL IRQ handler for USB calls the USBX ISR hook (through the STM32 USBX interface layer).

  4. Check USBX initialization

    • ux_system_initialize() returns UX_SUCCESS.

    • Host or device stack initialization also returns UX_SUCCESS.

    • Class registration calls return UX_SUCCESS.

    • Configuration options like UX_MAX_DEVICES and UX_MAX_HCD are set to realistic values.

Enumeration / detection issues

Q4. My USB device is not detected by the PC. What should I check?

If the PC does not detect your STM32 USB device at all:

  • Cable and port

    • Try another USB cable and another PC port.

    • Make sure you are using the correct connector (FS vs HS port) on the board.

  • Device mode configuration

    • Ensure the STM32 USB peripheral is configured in device mode, not host mode.

    • Check that the correct speed and pins are configured.

  • USB descriptors

    • Check that device, configuration, interface, and endpoint descriptors are valid.

    • Verify VID, PID, and class codes.

    • Confirm endpoint types and packet sizes match the hardware configuration.

  • Pull-ups and VBUS sensing

    • Confirm the D+ pull-up is enabled to signal the USB host (for Full Speed).

    • Make sure VBUS sensing settings match your hardware design (VBUS pin or self-powered mode).

  • PC logs

    • On Windows: open Device Manager and look for unknown devices or error codes.

    • On Linux: use dmesg and lsusb to view enumeration messages and errors.

Q5. My STM32 USB host does not detect any connected device. What could be wrong?

If your STM32 is configured as USB host and does not see a USB device:

  • Verify that the USB peripheral is configured in host mode.

  • Ensure that VBUS (5 V) is provided to the USB port (through a switch or power IC if required).

  • Confirm the following calls return UX_SUCCESS:

    • ux_system_initialize()

    • USB host stack initialization

    • USB class registration (MSC, HID, etc.)

  • Check that configuration values such as UX_MAX_HCD and UX_MAX_DEVICES are high enough for at least one device and one host controller.

Memory and configuration

Q6. USBX reports memory or allocation errors. How can I fix this?

Typical signs: USBX functions return UX_MEMORY_INSUFFICIENT or similar errors.

  • Increase the USBX memory pool

    • The buffer passed to ux_system_initialize() must be large enough.

    • Increase this pool size if you add more classes, endpoints or features.

  • Simplify configuration

    • Reduce: * UX_MAX_DEVICES, UX_MAX_CLASSES, UX_MAX_HCD * UX_MAX_SLAVE_CLASS_DRIVER, UX_MAX_SLAVE_INTERFACES

    • Reduce large buffers such as UX_HOST_CLASS_STORAGE_MEMORY_BUFFER_SIZE if they are larger than needed.

  • Check system heap and stack

    • Ensure your linker script reserves enough RAM for heap and stack.

    • If you use an RTOS, confirm the RTOS heap is large enough for all threads and USBX usage.

Q7. Which USBX configuration options are the most important when starting on a new board?

When you port USBX to a new STM32 board, focus first on:

  • Core limits

    • UX_MAX_DEVICES

    • UX_MAX_CLASSES

    • UX_MAX_HCD

  • Device-side limits

    • UX_MAX_SLAVE_CLASS_DRIVER

    • UX_MAX_SLAVE_INTERFACES

  • Storage / MSC

    • UX_HOST_CLASS_STORAGE_MEMORY_BUFFER_SIZE

    • UX_MAX_HOST_LUN

    • UX_MAX_SLAVE_LUN

  • Thread stack sizes (if using an RTOS)

    • UX_THREAD_STACK_SIZE

    • UX_HOST_ENUM_THREAD_STACK_SIZE

    • UX_HOST_HCD_THREAD_STACK_SIZE

A good approach is to start from a working STM32 USBX example and keep the same configuration, then adjust only when you hit limits.

Class-specific questions

Q8. The CDC virtual COM port appears on the PC, but no data is transferred. What should I do?

If the CDC (virtual COM port) is visible on the PC but there is no data:

  • Check endpoints

    • CDC needs: * 1 interrupt IN endpoint (notification) * 1 bulk IN endpoint (device → host) * 1 bulk OUT endpoint (host → device)

    • Confirm endpoint types and packet sizes in the descriptors.

  • Check application logic

    • Verify that your application: * Reads data from the CDC OUT endpoint (or the CDC receive API). * Sends data through the CDC IN endpoint (or the CDC transmit API).

    • Ensure the main application loop or RTOS threads are running and not blocked.

  • PC side

    • Open the correct COM port in a terminal program.

    • Send simple text and check if the device receives it.

    • Try another PC or another terminal tool to rule out host-side issues.

Q9. USB Mass Storage (MSC) enumerates, but the disk does not mount or looks corrupted. Why?

If the USB mass storage device is detected but cannot be used:

  • Storage initialization

    • Make sure your Flash, SD card, or other storage medium is fully initialized before MSC reports it as ready.

    • Any error in the low-level storage driver can prevent correct mounting.

  • Block size and capacity

    • Check that: * Block size * Number of blocks

    • are reported correctly and consistently in: * The low-level storage driver * USBX MSC layer * File system layer (for example FileX)

  • File system

    • If you use FileX, verify: * The media driver is correctly implemented. * The storage is properly formatted with a supported file system.

  • SCSI commands

    • Ensure that basic SCSI commands (INQUIRY, READ CAPACITY, READ, WRITE, etc.) are correctly implemented and do not return invalid sense data.

Q10. HID keyboard or mouse enumerates, but nothing happens on the PC. What may be wrong?

If the HID device is visible in the OS but there are no key presses or mouse movements:

  • HID report descriptor

    • Verify that the HID report descriptor matches your device type: * Keyboard: usage pages, key codes, modifiers. * Mouse: X/Y movement, buttons, wheel.

    • If the descriptor does not match the data you send, the host may ignore the reports.

  • Sending reports

    • Check that your application: * Sends reports when keys are pressed or released, or when the mouse moves. * Uses the correct report length (same as described in the HID descriptor).

  • Endpoints and polling

    • Make sure the HID IN endpoint is of interrupt type and has a valid polling interval.

    • Check for stalls or transfer errors using host logs or a USB analyzer.

Standalone vs RTOS mode

Q11. Can I use USBX without an RTOS (bare-metal)? How?

Yes. USBX supports standalone (bare-metal) mode on STM32:

  1. Enable standalone mode

    • Add UX_STANDALONE to your project preprocessor definitions.

  2. Use the STM32 USBX standalone port

    • Use the STM32-specific USBX port and interface files provided in the project or package.

    • Start from the STM32 USBX standalone examples when possible.

  3. Replace RTOS threads

    • Instead of RTOS threads, call the USBX processing functions regularly in: * The main loop, or * A periodic timer/interrupt.

    • Follow the scheduling model shown in the standalone examples.

Troubleshooting flow

Q12. I have a problem with USBX and do not know where to start. What is a simple checklist?

  1. Confirm the mode

    • Are you using device or host mode?

    • Is the peripheral configured accordingly?

  2. Check hardware

    • Correct USB connector (FS or HS) is used.

    • Power and VBUS are correctly provided.

    • Clocks and pins are configured.

  3. Check USBX initialization

    • ux_system_initialize() returns UX_SUCCESS.

    • Host/device stack initialization and class registrations return UX_SUCCESS.

  4. Check descriptors

    • VID/PID, class codes, endpoints, and packet sizes are valid.

  5. Inspect the host side

    • On Windows, check Device Manager.

    • On Linux, use dmesg and lsusb.

    • Use a USB protocol analyzer if available.

  6. Reduce complexity

    • Start from a known working STM32 USBX example (CDC, MSC, HID).

    • Modify only one element at a time and test again.