cancel
Showing results for 
Search instead for 
Did you mean: 

How to add USBX to an STM32 FreeRTOS™ project

nk1
ST Employee

Introduction 

This article is a tutorial on how to add the standalone version of USBX (without Azure RTOS) to an STM32 FreeRTOS™ project. This tutorial uses an STM32U5G9J-DK2 board and the same steps are applicable to any other STM32 MCU.

Currently in CubeMX, USBX and other Azure RTOS middleware are automatically disabled when FreeRTOS™ is activated. So, we need to create a separate "USBX only" project in CubeMX, configure only the USBX middleware + some basic project settings and generate the code. Afterwards, copy and paste the relevant generated code folders into our master project that has FreeRTOS™ and everything else our application needs (that is, NFC, UART, SPI, LCD, etc.).

For reference, see the attached STM32U5G9J-DK2 board "FreeRTOS + USBX" project (STM32U5G9J_DK2_USB_Device_HID_FreeRTOS_example_V1_project.zip file) at the end of this article. You can create your own “FreeRTOS + USBX” project by following this article.

Prerequisites

1. Create the FreeRTOS™ project

In CubeMX, create a master project for your STM32 MCU that has all your project's peripheral and middleware configurations (that is, FreeRTOS™, USB, RCC, etc.) minus the USBX middleware configurations.

For now, just configure:

  • FreeRTOS™ middleware.
  • TIM6 (or other TIMx peripheral) as the SysTick timebase.
  • RCC → LSE and RCC → HSE pins (as needed for USB).
  • USB pins & peripheral.
  • USB clock source in the CubeMX clock tree tab (if not already set correctly by default).
  • Default ICACHE settings (if applicable).
  • SWD debug pins.
  • On-board or external user LEDs and user button.

Refer to the attached "FreeRTOS + USBX" project for the specific configurations used on the STM32U5G9J-DK2 board.

nk1_0-1759871090129.png

 

Add a FreeRTOS™ USBTask and a couple other tasks for testing purposes.

2.png

 

In the NVIC configurations, make sure that you have enabled the interrupts that are necessary for your design.

nk1_2-1759871090147.png

Configure the code generation settings to NOT generate the MX_USB_..._Init() function and make sure that its visibility is NOT static. This is because we place this function call in our USB application code, which is outside of main.c.

4.png

Generate the code when finished with the configurations. Build the freshly generated project to make sure that it builds successfully.

2. Verify the FreeRTOS™ project

In app_freertos.c for example purposes: Blink the user LEDs in the Task1 and Task2 FreeRTOS™ tasks, and add osDelay() values for all three FreeRTOS™ tasks.

5.png

Build the project and launch a debug session to verify that the application runs properly on your board. You should see the on-board or external LEDs toggling accordingly depending on the osDelay() value.

3. Create a "USBX only" project

Now, we need to create a "USBX only" project that contains only the standalone USBX middleware configurations.

Create a new project in CubeMX for your specific STM32 MCU part number and configure the USB peripheral. Use the same USB peripheral configurations that you used in your FreeRTOS™ project in section 1 of this article. We are enabling and configuring the USB peripheral in this “USBX only” project only to ensure that we have all USBX middleware configuration options available to us.

Configure the USBX middleware’s mode and platform settings accordingly. The mode configurations shown below are for a USB HID mouse device. If your USB application requires something different, then make sure that you use the correct mode configurations for your specific USB application.

6.png

 

Configure the USBX middleware configurations as shown below.

nk1_6-1759871090185.png

nk1_7-1759871090193.png

 

Generate the code when finished. Build this "USBX only" project to make sure that it builds without errors.

4. Copy over USBX folders

Copy the following files/folders from the "USBX only" project into your "FreeRTOS + USBX" project.

Folder 1: USBX

  • Copy from: C:\…\<USBX only project root folder>\USBX
  • Paste into: C:\…\<FreeRTOS + USBX project root folder>

8.png

 

Folder 2: usbx

  • Copy from: C:\…\<USBX only project root folder>\Middlewares\ST\usbx
  • Paste into: C:\…\<FreeRTOS + USBX project root folder>\Middlewares\ST

9.png

Note: If your “FreeRTOS + USBX“ project does not have a Middlewares\ST folder, then create it.  

5. Update compiler include paths

In the "FreeRTOS + USBX" project, we need to add the compiler include paths for the files/folders we copied over.

Right click on the "USBX only" project→ Properties → C/C++ Build → Settings → Tool Settings → MCU/MPU GCC Compiler → Include paths. Copy all "../USBX/…" and "../Middlewares/ST/usbx/…" include paths that are listed.

10.png

 

Add them to the "FreeRTOS + USBX" project → Properties → C/C++ Build → Settings → Tool Settings → MCU/MPU GCC Compiler → Include paths.

11.png

 

For convenience, here’s a plain text version of the main compiler include paths you need to copy into your own “FreeRTOS + USBX” project:

  • ../USBX/App
  • ../USBX/Target
  • ../Middlewares/ST/usbx/common/core/inc
  • ../Middlewares/ST/usbx/ports/generic/inc
  • ../Middlewares/ST/usbx/common/usbx_stm32_device_controllers
  • ../Middlewares/ST/usbx/common/usbx_device_classes/inc

 

Click [Apply], [Rebuild Index], then [Apply and Close] when done.  

6. Update compiler preprocessor define symbols

In the "FreeRTOS + USBX" project, we need to add the USBX related compiler preprocessor define symbols.

Right click on the "USBX only" project → Properties → C/C++ Build → Settings → Tool Settings → MCU/MPU GCC Compiler → Preprocessor. Copy all USBX / UX related compiler preprocessor define symbols that are listed.

12.png

 

Add them to the "FreeRTOS + USBX" project → Properties → C/C++ Build →  Settings → Tool Settings → MCU/MPU GCC Compiler → Preprocessor.

13.png

 

For convenience, here is a plain text version of the main compiler preprocessor define symbol you need to copy into your own “FreeRTOS + USBX” project:

  • UX_INCLUDE_USER_DEFINE_FILE

Click [Apply], [Rebuild Index], then [Apply and Close] when done.  Build the "FreeRTOS + USBX" project to make sure that it builds without errors.

7. Update source folders on build path list

In the "FreeRTOS + USBX" project, we need to add the USBX folder to the source folders on the build path list.

Right click on the "FreeRTOS + USBX" project → Properties → C/C++ General → Paths and Symbols → Source Location. Add the /<FreeRTOS + USBX project root folder>/USBX folder.

14.png

 

Click [Apply], [Rebuild Index], then [Apply and Close] when done. Build the "FreeRTOS + USBX" project to make sure that it builds without errors.

8. Add USBX includes

In the "FreeRTOS + USBX" project, we need to add the USBX related includes to main.h and main.c.

In the "USBX only" project, copy all USBX related includes in main.h. Paste them into the "FreeRTOS + USBX" project → main.h file between the "USER CODE BEGIN Includes" and "USER CODE END Includes" labels.

15.png

Note: The app_usbx_device.h header file shown above is specific to USBX configured as a USB device. So if your USBX configurations are different, you may have different header file names. Make sure you copy all USBX related includes from your main.h file, not just the one shown above.

In the "USBX only" project, copy all USBX related includes in main.c. Paste them into the "FreeRTOS + USBX" project → main.c file between the "USER CODE BEGIN Includes" and "USER CODE END Includes" labels. Note: If a specific include is already in main.h, there is no need to put it in main.c.

Save and build the "FreeRTOS + USBX" project to make sure that it builds without errors. 

9. Add the USB application code

Now, you need to add your USB application code to the "FreeRTOS + USBX" project.

In the "FreeRTOS + USBX" project, add your USB application code to the following files between "USER CODE BEGIN" and "USER CODE END" labels:

  • main.h
  • main.c
  • ux_device_mouse.h
  • ux_device_mouse.c
  • app_usbx_device.h
  • app_usbx_device.c

Note: Aside from main.h and main.c, these files are specific to USBX configured as a USB HID mouse device. So, if your USBX configurations are different, you will have different file names.

In main.c, you need to place the MX_USBX_Device_Init() function between the "USER CODE BEGIN 2" and "USER CODE END 2" labels.

16.png

Note: The MX_USBX_Device_Init() function is specific to USBX configured as a USB device. So if your USBX configurations are different, you may have a different MX USBX initialization function name.

Note: Aside from the MX_USBX_Device_Init() function, the rest of the code shown in main() is auto generated and is STM32 device specific and configuration specific. You may see different auto generated code in your main() function. Do not modify it with the auto generated code from the screenshot above.

When done, build the "FreeRTOS + USBX" project to make sure that there are no errors.

10. Move the USB process start function

In the “FreeRTOS + USBX” project, we need to move the USBX_Device_Process(NULL) function from main() to the FreeRTOS USB task in app_freertos.c.

  • Delete from main.c → main(): USBX_Device_Process(NULL);
  • Add to app_freertos.c → StartUSBTask(): USBX_Device_Process(NULL);

17.png

Note: The USBX_Device_Process(NULL) function is specific to USBX configured as a USB device. So, if your USBX configurations are different, you may have a different USB process start function name.

Note: StartUSBTask() is the name of the USB FreeRTOS task created in section 1 of this article. If you are using a different USB task start function name, then your StartUSBTask() function will have a different name.

When done, build the "FreeRTOS + USBX" project to make sure that there are no errors.

11. Run the FreeRTOS + USBX application

In the “FreeRTOS + USBX” project, launch a debug session and click Run / Resume to run the application on your board. Make sure that your second USB Type-C® cable is plugged into your PC and the application / user USB connector on your board (CN2 on the STM32U5G9J-DK2 board).

18.jpeg

 

You should see the on-board or external LEDs toggling accordingly depending on the osDelay() values of the FreeRTOS tasks Task1 and Task2.

Every time you press the on-board or external user push button, your computer's mouse cursor moves.

FreeRTOS and USBX are now working together in the same STM32 project. At the end of this article, see the attached STM32U5G9J-DK2 board "FreeRTOS + USBX" project as an example. (STM32U5G9J_DK2_USB_Device_HID_FreeRTOS_example_V1_project.zip file)

12. Warnings

WARNING 1

Before you re-generate code in your "FreeRTOS + USBX" project, ALWAYS backup / make copies of the following in case they get deleted or overwritten by the code generator:

  • Folder 1: C:\…\<FreeRTOS + USBX project root folder>\USBX
  • Folder 2: C:\…\<FreeRTOS + USBX project root folder>\Middlewares\ST\usbx
  • Your entire "FreeRTOS + USBX" project.

WARNING 2

Every time you need to change your USBX configurations, you will have to do so in your "USBX only" project. Afterwards, copy over those newly generated USBX folders into your “FreeRTOS + USBX” project as instructed in Section 4 of this article. This overwrites all your “FreeRTOS + USBX” project files and application code in these folders. Make sure you back up or make copies of the following before copying over those newly generated USBX folders.

  • Folder 1: C:\…\<FreeRTOS + USBX project root folder>\USBX
  • Folder 2: C:\…\<FreeRTOS + USBX project root folder>\Middlewares\ST\usbx
  • Your entire "FreeRTOS + USBX" project.

Related links

Version history
Last update:
‎2025-10-23 12:45 PM
Updated by:
Contributors