cancel
Showing results for 
Search instead for 
Did you mean: 

Is there a known fix or patch for blocked USB communication caused by stuck USBD_BUSY?

LHaze
Associate II

This concerns the USB programming on on STM32F7 using the HAL libraries. The output for the USB transmission randomly goes blocked with USBD_BUSY. Nothing I have done so far has unblocked it. It would appear that this is not a new problem, as I have found comments on it as far back as four years ago. The suggestion for a "fix" is to switch from using HAL to the Standard Peripheral Libraries. Is there a fix or a patch for HAL libraries, or is the SPL suggestion still the only route to a working program? If the SPL is the only option, what is the procedure for accomplishing this? Is there some documentation to which I should refer?

6 REPLIES 6
JoniS
Senior

Can you show your USB code which hangs? USB cdc mode? If possible smallest possible sample of the project which behaves like you descripe.​

Here is the CDC_Receive_FS routine. If you want the Transmit, I can provide that, too. Thank you for looking at this.

-Lyman

static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)

{

   uint8_t i;               // counter

   uint8_t bHaveEOL = 0;

 /* USER CODE BEGIN 6 */

   for(i=0;i<*Len;i++)

   {

      if(Buf[i] == '\n')

      {

         /*while(CDC_Transmit_FS(Buf, *Len) == USBD_BUSY);*/

         USB_IN_BUF[uiUSB_In_CharCount] = Buf[i];

         bHaveEOL = 1;

         break;

      }

      else               // copy sent chars to real buffer

      {

         while(CDC_Transmit_FS(Buf, *Len) == USBD_BUSY);

         USB_IN_BUF[uiUSB_In_CharCount] = Buf[i];

         uiUSB_In_CharCount = uiUSB_In_CharCount + 1;

      }

   }

   if(bHaveEOL)

   {

      sprintf(USB_OUT_BUF, "Count = %i\r\n", 10);

      while(CDC_Transmit_FS((uint8_t *)USB_OUT_BUF, 10) == USBD_BUSY);

      USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);

      USBD_CDC_ReceivePacket(&hUsbDeviceFS);

      memset(USB_OUT_BUF, 0, strlen(USB_OUT_BUF));

      strcpy(USB_OUT_BUF, USB_IN_BUF) ;

      while(CDC_Transmit_FS((uint8_t *)USB_OUT_BUF, uiUSB_In_CharCount) == USBD_BUSY);

      uiUSB_In_CharCount = 0;

      USB_IN_BUF[0] = '\0';

   }

 USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);

 USBD_CDC_ReceivePacket(&hUsbDeviceFS);

 return (USBD_OK);

Have you modified the other functions in that file? Mainly the one which sets linecoding parameters? I did have similar behaviour before implementing that.​

Besides that, I don't think you should transmit directly from the receive function since it's interrupt/callback context and should exit rather quickly so the processor can serve other interrupts, copy the data to other buffer and set a flag and exit, then do what needs to be done with the data somewhere else.

Line encoding parameters? OK. First I have heard of these. I'll get some education. Probably the issue, as you say. Also, I'll change where the echo and the replies are sent. I'll get back here after implementing all that and let you all know my results.

Thank you!

JoniS, Thank you very much for your insights. Both of your concerns were spot-on. I now understand that essentially nothing needs to be done in usbd_cdc_if.c. I do have one question, though. While the target string UserRXBufferFS is defined in usbd_cdc_if.c and I can simply refer to it as an extern in main.c, I have not been able to determine what variable is being sent to CDC_Receiver_FS(uint8_t* Buf, uint32_t *Len) as the length parameter. Clearly, something is being assigned this value, but I have not been able to determine what it is. Any clue? I can see it in the debugger if I set a breakpoint, but I have not been able to look at where it comes from.

Thank you for helping me.

OK, I dug around in the code and found the current receive buffer length buried in the pClassData substructure of hUsbDeviceFS. Essentially, what I am learning is that the documentation of things like how to use the USB with ST Micro is the code it generates. Perhaps, when I finish up this project, I'll write up a document describing how the USBD works so others won't have to repeat this process.

In any event, I think we can label this question answered. Thank you, again, for your valuable assistance!