cancel
Showing results for 
Search instead for 
Did you mean: 

Application gets stuck when sending string in USB_CDC

SSmit.13
Senior

Hi

  I am using a STML4xx processor and use HAL for system initialising, and sending strings through the USB port. It works most of the time. I call the below function SendString(...) to send string through the USB port , never within an interupt. I have a volatile variable as a timeout and decremented within the System timer. Sometimes the system sticks inside the CDC_Transmit_FS command, when stuck the System timer doesnt get called. Seems to stick within the routine.

I cant see whay it doesnt break the loop , if it cant send the string. Anyone any idea?

Best Regards

Scott

 

 

 

extern volatile short int USBTimeout;
void SendString(char *Data)
{
   int Length=strlen(Data);
   USBTimeout=500;
   while(CDC_Transmit_FS(Data,Length)==USBD_BUSY && USBTimeout)
	 ;
}
void SysTick_Handler(void)
{
   if(USBTimeout)
	USBTimeout--;
}

 

 

 

3 REPLIES 3
FBL
ST Employee

Hi @SSmit.13 

Consider using a non-blocking approach to send data and check your USB configuration.

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.


tjaekel
Lead

No idea, just thoughts...

OK, you use volatile. Very important here to use volatile (a shared variable modified outside the loop code - compiler should not optimize to ignore USBTimeout if no changes seen in code).

Operator precedence:
==USBD_Busy && USBTimeout should be OK, even, personally: I would write as: == (USBD_Busy && USBTimeout))

What can happen behind the scene:
? is it really your SysTick_Hander() implementation, with intention of removing this HAL_Delay feature (so that HAL_Delay() would be broken)?

  • even you do not use INT in your code - still possible, that the USB stack (and functions) need and use INT:
    So, if the USB gets stuck inside an INT handler, e.g. with an error, and the prios are set so that SysTick has lower prio as USB INT used - it will not update USBTimeout
  • But actually, if USB gets stuck in its USB INT handler - your code should not be executed anymore.
    One reason could be:
    if USB stack sees an issue, e.g. it could not send, it does not complete, ... and it wants to use HAL_Delay() in order to try again after a short time elapsed...
    But there is not any handling for the HAL_Delay() variable used anymore - the USB stack might hang forever.

Where is your code running when never leaving this endless while-loop?
Where is the PC? Press "Pause" in debugger mode and check where it is looping forever.

Check what was the original SysTick_Handler():

  • if there was originally something like "HAL_IncTick();" - KEEP IT!
    (if you use an RTOS, there can be other code for RTOS done in SysTick_Handler: do not remove it)

Often, HAL drivers use HAL_Delay() and wait for a period of time to try again, after an error, something busy, ... If this is broken - they never progress (on low-level driver functions), if SysTick_Handler() would not decrement anymore the delay variable.

Another concern:
USB_CDC, which is "USB VCP", can send just max. 64bytes per transmission. So, if you send a longer string - the USB stack has to split it into several chunks.
Maybe this one fails. Maybe the USB stack waits for HAL_Delay(1), e.g. 1ms later to try again for next chunk...
(often, 1ms later for the next chunk).

Try to send shorter strings (< 64bytes), wait 1ms and send the next chunk.
Send larger strings (>64bytes) without to wait.
What is the difference in behavior or "crash" you see?

Try to "pause" debugger when it hangs: where (in which piece of code) does it hang?
(I think, not here in this "endless loop" - somewhere else, e.g. deep inside the USB stack code.)
Check also the INT prios assigned to SysTick and USB interrupts. It would just explain why USBTimeout does not decrement anymore, not why it hangs, what is the root cause.

gbm
Principal

The problem was discussed many times.

- Do not try to send anything until the connection is established.

- Call CDC_Transmit only from the interrupt routine of the same priority as USB interrupt.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice