Skip to main content
Visitor II
September 26, 2025
Question

STM32C0 USBX CDC send data un-stoppable

  • September 26, 2025
  • 3 replies
  • 573 views

Hello, I am using STM32C071 in my project, the main work is to receive data from PC, then do some controls, then send data to PC.

However, during the send data to PC step, sometimes the data will be sent continuously, it doesn't meet my requirements, sometimes it working well, this is very unusual. please provide some advise.

After I send the data and proceduce the 'handleRecvData()' func, the data I received from PC is not un-stoppable.

I have checked several days and I can't find what caused this ab-normal.

thomas123_0-1758849792661.png

I follow the steps from @B.Montanari , this link:https://community.st.com/t5/stm32-mcus/how-to-implement-the-usb-device-cdc-vcom-in-stm32-using-the/ta-p/599170

the write and read threads code shows as below:

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
uint8_t resultCode = 0;
extern TX_MUTEX mutexCode;
/* USER CODE END PFP */

 

VOID usbx_cdc_acm_write_thread_entry(ULONG thread_input)
{
 /* Private Variables */
 ULONG tx_actual_length;
 uint8_t initGoodMsg[] = "Init Good!";
 uint8_t opGoodMsg[] = "Operate Good!";
 uint8_t opErrorMsg[] = "Operate Error!";
 uint8_t headerErrorMsg[] = "Header Error!";
 uint8_t flameErrorMsg[] = "Flame Error!";
 uint8_t msgToSend[15];

 while(1)
 {
 	if(tx_mutex_get(&mutexCode, TX_WAIT_FOREVER) == TX_SUCCESS){
 	 while(resultCode != 0){
 	 	 switch(resultCode){
 	 	 case initGood:
 	 	 memcpy(msgToSend, initGoodMsg, sizeof(initGoodMsg));
 	 	 	break;
 	 	 case opGood:
 	 	 	memcpy(msgToSend, opGoodMsg, sizeof(opGoodMsg));
 	 	 	break;
 	 	 case opError:
 	 	 	memcpy(msgToSend, opErrorMsg, sizeof(opErrorMsg));
 	 	 	break;
 	 	 case headerError:
 	 	 	memcpy(msgToSend, headerErrorMsg, sizeof(headerErrorMsg));
 	 	 	break;
 	 	 case flameError:
 	 	 	memcpy(msgToSend, flameErrorMsg, sizeof(flameErrorMsg));
 	 	 	break;
 	 	 default:
 	 	 	break;
 	 	}
 	 	resultCode = 0;
 	 ux_device_class_cdc_acm_write(cdc_acm, (UCHAR *)(msgToSend), sizeof(msgToSend), &tx_actual_length);
 	 }
 	}
 	tx_mutex_put(&mutexCode);
 	tx_thread_sleep(150);
 }
}

 

VOID usbx_cdc_acm_read_thread_entry(ULONG thread_input)
{
 /* Private Variables */
 ULONG rx_actual_length;
 uint8_t UserRxBuffer[10];

 /* Infinite Loop */
 while(1)
 {
 if(cdc_acm != UX_NULL)
 {
 ux_device_class_cdc_acm_read(cdc_acm, (UCHAR *)UserRxBuffer, 10, &rx_actual_length);
 if(rx_actual_length != 0){
 	 if(tx_mutex_get(&mutexCode, TX_WAIT_FOREVER) == TX_SUCCESS){
 		//handle receive data
 	 	handleRecvData((uint8_t *)UserRxBuffer, rx_actual_length);
 	 tx_mutex_put(&mutexCode);
 	}
 }else{
 	 tx_thread_sleep(100);
 }
 }
 tx_thread_sleep(100);
 }
}
VOID handleRecvData(uint8_t *RecvRxBuffer, ULONG bufferLength)
{
	if((RecvRxBuffer[0] == 0xAA) && (RecvRxBuffer[1] == 0xCC) && (RecvRxBuffer[bufferLength-2] == 0xAA) && (RecvRxBuffer[bufferLength-1] == 0x55))
	{
		// 帧头帧尾 OK
		if(RecvRxBuffer[2] == (bufferLength - 4)){
			// 帧长确认OK
			switch(RecvRxBuffer[3]) // 功能位
			{
			case 0x00:
				resultCode = 1;
				HAL_NVIC_SystemReset();
				break;
			case 0x01:
				if(boardInit() == HAL_OK){
					resultCode = initGood;
				}
				else{
					resultCode = opError;
				}
				break;
			case 0x02:
				if(setFingerCh(RecvRxBuffer[4], RecvRxBuffer[5], RecvRxBuffer[6]) == HAL_OK){
					resultCode = opGood;
				}
				else{
					resultCode = opError;
				}
				break;
			default:
				resultCode = flameError;
				break;
			}
		}else{
			// 帧长错误
			resultCode = flameError;
		}
	}else{
		// 帧头帧尾 error
		resultCode = headerError;
	}
}

 

 

 

    This topic has been closed for replies.

    3 replies

    ST Employee
    September 26, 2025

    Hello @thomas123 , 

    Please kindly check the USBX application provided by ST for the NUCLEO-C071RB board. You can find it at the link below:

    STM32CubeC0/Projects/NUCLEO-C071RB/Applications/USBX at main · STMicroelectronics/STM32CubeC0 · GitHub

    thank you

    Br

     

    thomas123Author
    Visitor II
    September 28, 2025

    Hi, @MOBEJ 

    I checked the demo example, and checked my code, the read thread and write thread can work very well respectively. My point is, when I use Mutex or Semaphore to make the parameter "resultCode" change in two thread, the write thread working ab-normal.

    or could you demo the mutex or semaphore 's usage for two thread, thank you very much.

    thomas123Author
    Visitor II
    September 28, 2025

    Does it acceptible to use ' HAL_NVIC_SystemReset() ' in thread for reset the STM32 MCU?

    HAL_NVIC_SystemReset();

     

    Technical Moderator
    September 30, 2025

    Hi @thomas123 

    • Make sure you only call tx_mutex_put() if tx_mutex_get() succeeded.