Нашел выход. Не очень хороший, но работает.
Код
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
/* USER CODE BEGIN 7 */
if(CDC_Stop) {return 2;} //Разрешение выдачи информации в CDC UART
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDevice_0->pClassData;
uint32_t tickstart = TimerTick; //
while (hcdc->TxState != 0) //
{
if ((TimerTick - tickstart) > 1000) //100мс
{ //
CDC_Stop = 1; //Разрешение выдачи информации в CDC UART
return 1; //
} //
}
USBD_CDC_SetTxBuffer(hUsbDevice_0, Buf, Len);
USBD_CDC_TransmitPacket(hUsbDevice_0);
/* USER CODE END 7 */
return 0;
}
Если ожидание готовности CDC UART принять данные превышает 1с, выставляется флаг CDC_Stop = 1, по которому данные с CDC UART больше не поступают. Но поскольку прием по CDC UART никто не отменял, этот флаг командой сбрасываетя. Можно выдернуть шнур, потом воткнуть обратно - ничего не виснет. Этот же флаг сбрасывается в функции static int8_t CDC_Init_FS(void). Она к счастью вызывается. Функция static int8_t CDC_DeInit_FS(void) не вызывается никогда.