現象:pc重新開機過程中,不斷發送按鍵資料,導緻pc未能應答,緻使下位機資料出現卡包現象。
MCU發送’B’,PC顯示’C’,MCU發送’E’,PC顯示’B’
原因造成如下:
- 序列槽外設優先級大于USB中斷(USBOTG_IRQn),導緻序列槽資料打斷USB,緻使PC或MCU丢包。
- 當PC請求usb裝置描述符字元串時,USB的其他通道不能發送資料,不然會導緻通道0資料異常,導緻PC丢包。
- 系統隻會請求字元串0-2,是以在此設定标志位即可。
- USB整個發送邏輯
// 此處解決PC開機過程中usb資料卡包問題。因為當pc請求字元串時,其他通道的資料發送會導緻異常。
if (get_usb_string_bus)
{
get_usb_string_bus = false;
biz_usb_queue_init();
#if BS_BLE_SUPPORT
biz_ble_queue_init();
#endif
g_key_trigger_flag = false;
g_combined_key_val = 0;
g_usb_send_delay_tick = 0;
LOG_D("<DEBUG> [USB] get_usb_string_bus\r\n");
return;
}
// 按鍵資料發送
if (g_key_trigger_flag)
{
g_free_tick = 0;
g_key_trigger_flag = false;
biz_prot_hwic_usb_send_key_data(g_combined_key_val);
sys_time_reset();
}
if (g_usb_send_delay_tick % 1400 == 0 && g_usb_send_delay_tick != 0)
{
if (get_usb_device_status())
{
// 發送USB資訊(将USB消息隊列的内容,依次發送)
if (biz_usb_data_dispose())
{
LOG_D("<DEBUG> [USB] send ok!!!\r\n");
g_free_tick = 0;
return;
}
}
}
g_free_tick++;
if (g_free_tick % 10000 == 0 && g_free_tick != 0)
{
// 判斷usb fifo是否卡包
get_usb_fifo_state();
}
/**
* @brief usb發送資料給usb自定義通道(消息入隊,非實時發送)
* @param *data: 欲發送内容
* @param len: 内容長度(位元組大小)
*/
void biz_usb_send_data(uint8_t *data, uint16_t len)
{
if (get_usb_string_bus)
{
LOG_D("<DEBUG> [biz_usb_send_data] queue bus fail\r\n");
}
if (!queue_en(&m_usb_recv_q, data, len))
{
LOG_D("<DEBUG> [biz_usb_send_data] queue full fail\r\n");
}
}
/**
* @brief 處理消息隊列中的消息,通過usb發送(放在空閑線程使用)
*/
bool biz_usb_data_dispose(void)
{
if(!get_usb_device_is_free())
{
LOG_D("<DEBUG> [USB] send Fail not free\r\n");
get_usb_fifo_state();
biz_usb_queue_init();
return false;
}
if(get_usb_tx_flag())
{
LOG_D("<DEBUG> [USB] send Fail send flag\r\n");
return false;
}
if (!queue_de(&m_usb_drive_recv_q, g_usb_recv_data))
{
if (!queue_de(&m_usb_recv_q, g_usb_recv_data))
{
return false;
}
}
if (usb_send(g_usb_recv_data, USB_RECV_Q_ITEM_SIZE) == false)
{
LOG_D("<DEBUG> [USB] send Fail BUS\r\n");
biz_usb_send_data(g_usb_recv_data, USB_RECV_Q_ITEM_SIZE);
return false;
}
return true;
}