Skip to main content
Visitor II
December 8, 2025
Question

USB device not recognized with RNDIS using USBX

  • December 8, 2025
  • 0 replies
  • 80 views

Hello,

I am trying to get Ethernet-over-USB working on a STM32U585. I want to be able to use both RNDIS and CDC-ECM, but I decided to start with RNDIS first. After a lot of trial and error and research, I am running out of ideas as to why my PC does not show any devices in USB Viewer on the port where I connected the circuit board. I am developing on a B-U585I-IOT02A.
I based my work on the following example: https://github.com/STMicroelectronics/stm32-usbx-examples/tree/main/Projects/STM32H735G-DK/Applications/USBX/Ux_Device_RNDIS

I provide my code here (if not mentioned it is generated by CubeMX). I did not touch files if code is not shown here:

main.c: 

int main(void)
{
 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();

 /* Configure the System Power */
 SystemPower_Config();

 /* Configure the system clock */
 SystemClock_Config();

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_ICACHE_Init();
 
 // HINT: this function is called later as in the example project
 // MX_USB_OTG_FS_PCD_Init();

 MX_ThreadX_Init();
 while(1);
}

app_usbx_device.c:

#include "app_usbx_device.h"

/* Private define ------------------------------------------------------------*/
extern PCD_HandleTypeDef hpcd_USB_OTG_FS;

/* Private variables ---------------------------------------------------------*/
static ULONG rndis_interface_number;
static ULONG rndis_configuration_number;
static UCHAR rndis_local_nodeid[UX_DEVICE_CLASS_RNDIS_NODE_ID_LENGTH];
static UCHAR rndis_remote_nodeid[UX_DEVICE_CLASS_RNDIS_NODE_ID_LENGTH];
static UX_SLAVE_CLASS_RNDIS_PARAMETER rndis_parameter;
static TX_THREAD ux_device_app_thread;

/* Private function prototypes -----------------------------------------------*/
static VOID app_ux_device_thread_entry(ULONG thread_input);

UINT MX_USBX_Device_Init(VOID *memory_ptr)
{
 UINT ret = UX_SUCCESS;
 UCHAR *device_framework_high_speed;
 UCHAR *device_framework_full_speed;
 ULONG device_framework_hs_length;
 ULONG device_framework_fs_length;
 ULONG string_framework_length;
 ULONG language_id_framework_length;
 UCHAR *string_framework;
 UCHAR *language_id_framework;

 UCHAR *pointer;
 TX_BYTE_POOL *byte_pool = (TX_BYTE_POOL*)memory_ptr;

 /* Allocate the stack for USBX Memory */
 if (tx_byte_allocate(byte_pool, (VOID **) &pointer,
 USBX_DEVICE_MEMORY_STACK_SIZE, TX_NO_WAIT) != TX_SUCCESS)
 {
 return TX_POOL_ERROR;
 }

 /* Initialize USBX Memory */
 if (ux_system_initialize(pointer, USBX_DEVICE_MEMORY_STACK_SIZE, UX_NULL, 0) != UX_SUCCESS)
 {
 return UX_ERROR;
 }

 /* Get Device Framework High Speed and get the length */
 device_framework_high_speed = USBD_Get_Device_Framework_Speed(USBD_HIGH_SPEED,
 &device_framework_hs_length);

 /* Get Device Framework Full Speed and get the length */
 device_framework_full_speed = USBD_Get_Device_Framework_Speed(USBD_FULL_SPEED,
 &device_framework_fs_length);

 /* Get String Framework and get the length */
 string_framework = USBD_Get_String_Framework(&string_framework_length);

 /* Get Language Id Framework and get the length */
 language_id_framework = USBD_Get_Language_Id_Framework(&language_id_framework_length);

 /* Install the device portion of USBX */
 if (ux_device_stack_initialize(device_framework_high_speed,
 device_framework_hs_length,
 device_framework_full_speed,
 device_framework_fs_length,
 string_framework,
 string_framework_length,
 language_id_framework,
 language_id_framework_length,
 UX_NULL) != UX_SUCCESS)
 {
 return UX_ERROR;
 }

 /* Initialize the rndis class parameters for the device */
 rndis_parameter.ux_slave_class_rndis_instance_activate = USBD_RNDIS_Activate;
 rndis_parameter.ux_slave_class_rndis_instance_deactivate = USBD_RNDIS_Deactivate;

 /* Get RNDIS local MAC address */
 USBD_RNDIS_GetMacAdd((uint8_t *)RNDIS_LOCAL_MAC_STR_DESC, rndis_local_nodeid);

 /* Define RNDIS local node id */
 rndis_parameter.ux_slave_class_rndis_parameter_local_node_id[0] = rndis_local_nodeid[0];
 rndis_parameter.ux_slave_class_rndis_parameter_local_node_id[1] = rndis_local_nodeid[1];
 rndis_parameter.ux_slave_class_rndis_parameter_local_node_id[2] = rndis_local_nodeid[2];
 rndis_parameter.ux_slave_class_rndis_parameter_local_node_id[3] = rndis_local_nodeid[3];
 rndis_parameter.ux_slave_class_rndis_parameter_local_node_id[4] = rndis_local_nodeid[4];
 rndis_parameter.ux_slave_class_rndis_parameter_local_node_id[5] = rndis_local_nodeid[5];

 /* Get RNDIS local MAC address */
 USBD_RNDIS_GetMacAdd((uint8_t *)RNDIS_REMOTE_MAC_STR_DESC, rndis_remote_nodeid);

 /* Define RNDIS remote node id */
 rndis_parameter.ux_slave_class_rndis_parameter_remote_node_id[0] = rndis_remote_nodeid[0];
 rndis_parameter.ux_slave_class_rndis_parameter_remote_node_id[1] = rndis_remote_nodeid[1];
 rndis_parameter.ux_slave_class_rndis_parameter_remote_node_id[2] = rndis_remote_nodeid[2];
 rndis_parameter.ux_slave_class_rndis_parameter_remote_node_id[3] = rndis_remote_nodeid[3];
 rndis_parameter.ux_slave_class_rndis_parameter_remote_node_id[4] = rndis_remote_nodeid[4];
 rndis_parameter.ux_slave_class_rndis_parameter_remote_node_id[5] = rndis_remote_nodeid[5];

 rndis_parameter.ux_slave_class_rndis_parameter_vendor_id = USBD_VID;
 rndis_parameter.ux_slave_class_rndis_parameter_driver_version = USBD_RNDIS_DRIVER_VERSION;

 ux_utility_memory_copy(rndis_parameter.ux_slave_class_rndis_parameter_vendor_description,
 USBD_PRODUCT_STRING, sizeof(USBD_PRODUCT_STRING));

 /* Get rndis configuration number */
 rndis_configuration_number = USBD_Get_Configuration_Number(CLASS_TYPE_RNDIS, 0);

 /* Find rndis interface number */
 rndis_interface_number = USBD_Get_Interface_Number(CLASS_TYPE_RNDIS, 0);

 /* Initialize the device RNDIS */
 if (ux_device_stack_class_register(_ux_system_slave_class_rndis_name,
 ux_device_class_rndis_entry,
 rndis_configuration_number,
 rndis_interface_number,
 &rndis_parameter) != UX_SUCCESS)
 {
 return UX_ERROR;
 }

 /* Perform the initialization of the network driver. This will initialize the
 USBX network layer */

 ux_network_driver_init();

 /* Allocate the stack for device application main thread */
 if (tx_byte_allocate(byte_pool, (VOID **) &pointer, UX_DEVICE_APP_THREAD_STACK_SIZE,
 TX_NO_WAIT) != TX_SUCCESS)
 {
 return TX_POOL_ERROR;
 }

 /* Create the device application main thread */
 if (tx_thread_create(&ux_device_app_thread, UX_DEVICE_APP_THREAD_NAME, app_ux_device_thread_entry,
 0, pointer, UX_DEVICE_APP_THREAD_STACK_SIZE, UX_DEVICE_APP_THREAD_PRIO,
 UX_DEVICE_APP_THREAD_PREEMPTION_THRESHOLD, UX_DEVICE_APP_THREAD_TIME_SLICE,
 UX_DEVICE_APP_THREAD_START_OPTION) != TX_SUCCESS)
 {
 return TX_THREAD_ERROR;
 }

 return ret;
}

static VOID app_ux_device_thread_entry(ULONG thread_input)
{
	MX_USB_OTG_FS_PCD_Init();

	HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x200);
	HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x80);
	HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80);

	ux_dcd_stm32_initialize((ULONG)USB_OTG_FS, (ULONG)&hpcd_USB_OTG_FS);

	if (HAL_PCD_Start(&hpcd_USB_OTG_FS) != HAL_OK) Error_Handler();

 while(1);
}

app_usbx_device.h:

* Includes ------------------------------------------------------------------*/
#include "ux_api.h"
#include "ux_device_rndis.h"
#include "ux_device_descriptors.h"
#include "app_azure_rtos_config.h"
#include "ux_dcd_stm32.h"
/* Private includes ----------------------------------------------------------*/
#include "usb_otg.h"
#include "ux_dcd_stm32.h"

/* Exported constants --------------------------------------------------------*/
#define USBX_DEVICE_MEMORY_STACK_SIZE 35840

#define UX_DEVICE_APP_THREAD_STACK_SIZE 2048
#define UX_DEVICE_APP_THREAD_PRIO 10

/* Exported functions prototypes ---------------------------------------------*/
UINT MX_USBX_Device_Init(VOID *memory_ptr);

#ifndef UX_DEVICE_APP_THREAD_NAME
#define UX_DEVICE_APP_THREAD_NAME "USBX Device App Main Thread"
#endif

#ifndef UX_DEVICE_APP_THREAD_PREEMPTION_THRESHOLD
#define UX_DEVICE_APP_THREAD_PREEMPTION_THRESHOLD UX_DEVICE_APP_THREAD_PRIO
#endif

#ifndef UX_DEVICE_APP_THREAD_TIME_SLICE
#define UX_DEVICE_APP_THREAD_TIME_SLICE TX_NO_TIME_SLICE
#endif

#ifndef UX_DEVICE_APP_THREAD_START_OPTION
#define UX_DEVICE_APP_THREAD_START_OPTION TX_AUTO_START
#endif

I would be very grateful for any hints and tips.

Thank You!

K.S.

    This topic has been closed for replies.