How to initialize USBX ¶
This page explains USBX initialization in two integration models:
-
without STM32CubeMX2, using direct USBX APIs and the STM32 controller layers
-
with STM32CubeMX2, using the generated
mx_usbx_*files and the settings selected in the USBX panels
How to initialize USBX without STM32CubeMX2 ¶
Without STM32CubeMX2, the application drives the initialization order directly.
Common initialization sequence ¶
The common USBX startup flow is:
-
Allocate the USBX memory pool for internal objects, descriptors, queues, and transfers.
-
Call
ux_system_initialize(). -
Initialize the selected device stack, host stack, or both.
-
Register the required device classes or host classes.
-
Bind the STM32 controller layer.
-
Start the application loop, task, or callback path that uses USBX.
The core USBX entry point is:
status = ux_system_initialize(usb_memory,
usb_memory_size,
UX_NULL,
0);
This call initializes the global USBX services and prepares the middleware memory pool.
Device-mode initialization ¶
For device mode, a manual initialization flow typically looks like this:
status = ux_system_initialize(usb_memory, usb_memory_size, UX_NULL, 0);
status = ux_device_stack_initialize(high_speed_framework,
high_speed_framework_length,
full_speed_framework,
full_speed_framework_length,
string_framework,
string_framework_length,
language_id_framework,
language_id_framework_length,
device_change_callback);
status = ux_device_stack_class_register(class_name,
class_entry,
configuration_number,
interface_number,
class_parameter);
After the device stack is initialized, connect the STM32 device controller
layer. In the STM32 USBX middleware, that bridge is implemented by
interfaces/usbx_stm32_device_controllers
and uses the STM32 DCD entry
points such as
ux_dcd_stm32_initialize()
.
If the project uses STM32 reference descriptors, the device-descriptor content
comes from
interfaces/usbx_stm32_device_descriptors
.
Host-mode initialization ¶
For host mode, a manual initialization flow typically looks like this:
status = ux_system_initialize(usb_memory, usb_memory_size, UX_NULL, 0);
status = ux_host_stack_initialize(host_change_callback);
status = ux_host_stack_class_register(class_name,
class_entry);
status = ux_host_stack_hcd_register(hcd_name,
ux_hcd_stm32_initialize,
hcd_param1,
hcd_param2);
After the host stack is initialized, the STM32 HCD bridge from
interfaces/usbx_stm32_host_controllers
handles the controller-specific
attach, port-state, and transfer management path.
Dual-role projects ¶
If the project enables both roles, initialize USBX once with
ux_system_initialize()
, then initialize the device-side and host-side
stacks in the order required by the application architecture. Keep the selected
USB instances, descriptors, and memory budget coherent across both roles.
Execution model considerations ¶
In
No
OS
mode:
-
USBX runs in standalone mode.
-
The application remains responsible for the periodic processing path.
-
The generated or manual non-RTOS flow typically routes through
app_usbx_process()and the USBX task-run APIs.
In
FreeRTOS
mode:
-
USBX can use middleware threads for enumeration, class processing, and the selected controller layers.
-
Device and host application threads can be generated separately.
-
Thread priorities and stack sizes must stay aligned with the selected class mix and controller load.
How to initialize USBX with STM32CubeMX2 ¶
With STM32CubeMX2, USBX initialization is driven by the configuration panels and the generated application files.
Generated application files ¶
The generated USBX application layer is organized around a small set of common files plus optional role-specific files:
-
mx_usbx_app.c -
mx_usbx_app.h -
mx_usbx_device.candmx_usbx_device.hwhen device init-code generation is available for the selected configuration -
mx_usbx_host.candmx_usbx_host.hwhen host init-code generation is available for the selected configuration -
class-specific source files for the enabled device or host classes
These files are generated from the pack templates stored under
middleware/usbx/.config/template
. The templates themselves are not copied
into the user application. STM32CubeMX2 evaluates the template set and writes
the resulting
mx_usbx_*
source and header files into the generated project.
The common generated entry points are:
-
app_usbx_init()inmx_usbx_app.cand declared inmx_usbx_app.h -
app_usbx_deinit()inmx_usbx_app.cand declared inmx_usbx_app.h -
app_usbx_process()inmx_usbx_app.cand declared inmx_usbx_app.hforNo OSprojects
The role-specific generated entry points are:
-
app_usbx_device_init()andapp_usbx_device_deinit()inmx_usbx_device.cand declared inmx_usbx_device.h -
app_usbx_device_process()inmx_usbx_device.cand declared inmx_usbx_device.hforNo OSprojects -
app_usbx_host_init()andapp_usbx_host_deinit()inmx_usbx_host.cand declared inmx_usbx_host.h -
app_usbx_host_process()inmx_usbx_host.cand declared inmx_usbx_host.hforNo OSprojects
The generated header also carries the device and host application thread names, stack sizes, and priorities when the RTOS path is enabled.
Read the generated files in this order:
mx_usbx_app
for the common memory
pool and entry points, then
mx_usbx_device
or
mx_usbx_host
when
role-specific init code is available, then the class-specific files that carry
user callbacks, report descriptors, class-local buffers, and class-specific
helper functions. The class registration calls are emitted in
mx_usbx_device.c
or
mx_usbx_host.c
, not in the class-specific files.
Generated initialization is only a starting point, so the class callbacks,
descriptors, storage handling, and board wiring must still match the real
product behavior.
Dependencies required before generated initialization can work ¶
Before relying on generated startup code, confirm these prerequisites:
-
No OSprojects must callapp_usbx_process()regularly in the main execution path -
FreeRTOSprojects must enable the RTOS middleware and the advanced APIs checked by the UI -
device mode needs at least one enabled device class, a valid device descriptor strategy, HAL
PCDsupport, and a USB peripheral configured in device mode -
host mode needs at least one enabled host class, HAL
HCDsupport, and a USB peripheral configured in host mode -
host MSC needs either FileX integration or the no-FileX storage path
Generated initialization behavior ¶
The generated flow depends on the selected execution mode.
In
No
OS
mode:
-
the generated application layer provides
app_usbx_process()inmx_usbx_app.c -
role-specific standalone hooks such as
app_usbx_device_process()andapp_usbx_host_process()are emitted inmx_usbx_device.candmx_usbx_host.cwhen the corresponding role is enabled -
initialization remains explicit across
mx_usbx_app.cand the enabled role-specific file -
the application is still responsible for calling the process path at the required cadence
In
FreeRTOS
mode:
-
the generated application layer uses the configured thread names, priorities, and stack sizes from
mx_usbx_app.h -
the role-specific application thread settings are meaningful only for the roles that are enabled
-
the role-specific registration and controller hookup still live in
mx_usbx_device.candmx_usbx_host.cwhen those role files are generated -
the project must still satisfy the role, class, controller, and board-level prerequisites selected in the configuration pages
Initialization explained ¶
The initialization panel shown above is the part of STM32CubeMX2 that directly controls the generated initialization.
-
How to use this view: start here and confirm that the USBX middleware is enabled before reviewing the initialization settings. This is the entry point that opens the USBX configuration tree.
Role-dependent prerequisites ¶
Before relying on generated initialization, verify that:
-
device mode has a valid device descriptor strategy and a selected USB device instance
-
host mode has a valid host-controller instance
-
the selected device and host classes match the enabled controller role
-
the project memory budget covers the USBX system stack size and the selected thread stacks
Typical bring-up checks ¶
Before considering USBX initialized, verify:
-
ux_system_initialize()receives a valid memory pool -
the descriptor arrays and language tables are valid for device mode
-
the selected device classes or host classes are registered before traffic starts
-
the STM32 PCD or HCD bridge is bound to the correct USB instance
-
FreeRTOS-only generated settings are not relied on in
No OSprojects
Links ¶
-
How to configure USBX How to configure USBX
-
Getting started with USBX Getting started with USBX
-
How to port USBX on RTOS How to port USBX on RTOS