简体   繁体   中英

STM32 USB Tx Busy

I have an application running on STM32F429ZIT6 using USB stack to communicate with PC client.

MCU receives one type of message of 686 bytes every second and receives another type of message of 14 bytes afterwards with 0.5 seconds of delay between messages. The 14 bytes message is a heartbeat so it needs to replied by MCU.

It happens that after 5 to 10 minutes of continuous operation, MCU is not able to send data because hcdc->TxState is always busy. Reception works fine.

During Rx interruption, application only adds data to ring buffer, so that this buffer is later serialized and processed by main function.

static int8_t CDC_Receive_HS(uint8_t* Buf, uint32_t *Len) { 
/* USER CODE BEGIN 11 */     
/* Message RX Completed, Send it to Ring Buffer to be processed at FMC_Run()*/ 
for(uint16_t i = 0; i < *Len; i++){ 
  ring_push(RMP_RXRingBuffer, (uint8_t *) &Buf[i]); 
}     
USBD_CDC_SetRxBuffer(&hUsbDeviceHS, &Buf[0]); 
USBD_CDC_ReceivePacket(&hUsbDeviceHS);   
return (USBD_OK); 
/* USER CODE END 11 */ }

USB TX is also kept as simple as possible:

uint8_t CDC_Transmit_HS(uint8_t\* Buf, uint16_t Len) {
uint8_t result = USBD_OK;
/\* USER CODE BEGIN 12 */
USBD_CDC_HandleTypeDef hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceHS.pClassData;
if (hcdc-\>TxState != 0)
{
ZF_LOGE("Tx failed, resource busy\\n\\r"); return USBD_BUSY;
}
USBD_CDC_SetTxBuffer(&hUsbDeviceHS, Buf, Len);
result = USBD_CDC_TransmitPacket(&hUsbDeviceHS);  
ZF_LOGD("TX Message Result:%d\\n\\r", result);  
/ USER CODE END 12 \*/
return result;
}

I'm using latest HAL Drivers and software from CubeIDE (1.27.1).

I have tried expanding heap min size from 0x200 to larger values but result is the same.

Also Line Coding is set according to what recommended values:

case CDC_SET_LINE_CODING:
      LineCoding.bitrate = (uint32_t) (pbuf[0] | (pbuf[1] << 8) | (pbuf[2] << 16) | (pbuf[3] << 24));
      LineCoding.format = pbuf[4];
      LineCoding.paritytype = pbuf[5];
      LineCoding.datatype = pbuf[6];
      ZF_LOGD("Line Coding Set\n\r");
    break;

  case CDC_GET_LINE_CODING:
      pbuf[0] = (uint8_t) (LineCoding.bitrate);
      pbuf[1] = (uint8_t) (LineCoding.bitrate >> 8);
      pbuf[2] = (uint8_t) (LineCoding.bitrate >> 16);
      pbuf[3] = (uint8_t) (LineCoding.bitrate >> 24);
      pbuf[4] = LineCoding.format;
      pbuf[5] = LineCoding.paritytype;
      pbuf[6] = LineCoding.datatype;
      ZF_LOGD("Line Coding Get\n\r");
    break;

Thanks in advance, any support is appreciated.

I don't know enough about the STM32 libraries to really check your code, but I suspect you are forgetting to read the bytes transmitted by the STM32 on PC side. Try opening a terminal program like PuTTY and connecting to the STM32's virtual serial port. Otherwise, the Windows USB-to-serial driver (usbser.sys) will eventually have its buffers filled with data from your device and it will stop requesting more, at which point the buffers on your device will fill up as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM