ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

[单片机][at32][填坑日记] [USB卡包] usb上电过程中快速发包导致卡包(终章)

[单片机][at32][填坑日记] [USB卡包] usb上电过程中快速发包导致卡包(终章) 文章目录一、问题现象二、原因分析1. 串口中断优先级高于 USB 中断USBOTG_IRQn串口数据打断 USB 导致丢包2. PC 请求 USB 设备描述符字符串时其他通道发送数据导致通道 0 异常丢包3. USB 整个发送逻辑三、解决方案四、排查步骤1. 复现 USB 卡包问题2. 定位中断优先级冲突3. 验证字符串请求标志位是否生效4. 检查 USB 发送逻辑是否合理5. 综合验证修复效果五、总结六、参考资料一、问题现象现象PC 重启过程中不断发送按键数据导致 PC 未能应答致使下位机数据出现卡包现象。MCU 发送 ‘B’PC 显示 ‘C’MCU 发送 ‘E’PC 显示 ‘B’。二、原因分析1. 串口中断优先级高于 USB 中断USBOTG_IRQn串口数据打断 USB 导致丢包2. PC 请求 USB 设备描述符字符串时其他通道发送数据导致通道 0 异常丢包系统只会请求字符串 0-2所以在此设置标志位即可。3. USB 整个发送逻辑// 此处解决PC开机过程中usb数据卡包问题。因为当pc请求字符串时其他通道的数据发送会导致异常。if(get_usb_string_bus){get_usb_string_busfalse;biz_usb_queue_init();#ifBS_BLE_SUPPORTbiz_ble_queue_init();#endifg_key_trigger_flagfalse;g_combined_key_val0;g_usb_send_delay_tick0;LOG_D(DEBUG [USB] get_usb_string_bus\r\n);return;}// 按键数据发送if(g_key_trigger_flag){g_free_tick0;g_key_trigger_flagfalse;biz_prot_hwic_usb_send_key_data(g_combined_key_val);sys_time_reset();}if(g_usb_send_delay_tick%14000g_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_tick0;return;}}}g_free_tick;if(g_free_tick%100000g_free_tick!0){// 判断usb fifo是否卡包get_usb_fifo_state();}/** * brief usb发送数据给usb自定义通道(消息入队非实时发送) * param *data: 欲发送内容 * param len: 内容长度(字节大小) */voidbiz_usb_send_data(uint8_t*data,uint16_tlen){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发送(放在空闲线程使用) */boolbiz_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();returnfalse;}if(get_usb_tx_flag()){LOG_D(DEBUG [USB] send Fail send flag\r\n);returnfalse;}if(!queue_de(m_usb_drive_recv_q,g_usb_recv_data)){if(!queue_de(m_usb_recv_q,g_usb_recv_data)){returnfalse;}}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);returnfalse;}returntrue;}下面是 USB 卡包问题的原因分析流程图是否是否否是PC 重启/枚举串口中断优先级高于 USB串口数据打断 USB 传输USB 丢包PC 请求设备描述符字符串其他通道发送数据通道 0 异常丢包发送逻辑是否合理快速发包导致 FIFO 溢出/总线繁忙正常发送卡包现象三、解决方案针对上述原因主要采取以下措施降低串口中断对 USB 的干扰调整中断优先级确保 USB 中断USBOTG_IRQn优先于串口外设中断避免串口数据打断 USB 传输导致丢包。设置字符串请求标志位当 PC 请求 USB 设备描述符字符串时通过get_usb_string_bus标志位暂停其他通道的数据发送待字符串请求完成后恢复避免通道 0 数据异常。优化 USB 发送逻辑采用消息队列 空闲线程轮询的方式发送 USB 数据避免快速发包导致的卡包问题。解决方案适用场景优点缺点注意事项调整中断优先级串口与 USB 中断频繁竞争串口数据打断 USB 传输导致丢包从根源消除中断抢占改动小、见效快需结合具体 MCU 中断向量表配置可能影响其他外设的实时性确认 USBOTG_IRQn 优先级高于串口外设中断并评估对其他中断的影响设置字符串请求标志位PC 枚举/重启时请求设备描述符字符串其他通道发送数据导致通道 0 异常精准规避枚举窗口期的通道冲突逻辑简单可靠仅覆盖字符串请求这一特定场景无法解决其他原因导致的卡包系统只会请求字符串 0-2在请求期间置位get_usb_string_bus完成后及时复位优化 USB 发送逻辑高频快速发包导致 USB FIFO 溢出或总线繁忙通过消息队列 空闲线程轮询削峰填谷发送更平稳可扩展性强引入队列与轮询机制增加一定内存与 CPU 开销合理设置队列深度与轮询周期如 1400 tick并处理队列满/发送失败的重试逻辑下面是三种解决方案的整体流程图USB 卡包问题方案一调整中断优先级方案二设置字符串请求标志位方案三优化 USB 发送逻辑确保 USBOTG_IRQn 优先于串口中断PC 请求字符串时置位 get_usb_string_bus暂停其他通道发送请求完成后复位标志位消息队列入队空闲线程轮询发送处理队列满/发送失败重试解决卡包四、排查步骤针对 USB 卡包问题建议按照以下步骤逐步复现、定位并验证避免盲目修改代码。1. 复现 USB 卡包问题操作步骤将下位机固件烧录到目标 MCU连接 USB 线到 PC。在 PC 端打开串口调试助手或按键测试工具持续向 MCU 发送按键数据。反复执行 PC 重启或热插拔 USB操作观察 PC 端接收到的数据是否出现错乱或卡包。验证方法对比 MCU 发送的原始数据与 PC 端显示的数据。预期结果在 PC 重启过程中出现 MCU 发送B而 PC 显示C、MCU 发送E而 PC 显示B等错乱现象即成功复现卡包问题。2. 定位中断优先级冲突操作步骤在串口中断服务函数和 USB 中断服务函数USBOTG_IRQn入口处分别添加调试日志或 GPIO 翻转标记。在 PC 重启过程中持续发送按键数据观察串口中断与 USB 中断的触发时序。验证方法通过逻辑分析仪抓取 GPIO 翻转波形或通过日志时间戳判断中断嵌套顺序。预期结果若串口中断频繁打断 USB 中断处理说明串口中断优先级高于 USB 中断可确认中断优先级冲突是卡包原因之一。3. 验证字符串请求标志位是否生效操作步骤在get_usb_string_bus标志位置位与复位处分别添加调试日志。在 PC 枚举/重启过程中观察标志位的置位与复位时机是否与 PC 请求设备描述符字符串的时序一致。验证方法通过串口日志观察get_usb_string_bus的置位/复位日志并对比 PC 端枚举时序。预期结果若 PC 请求字符串期间其他通道仍在发送数据说明标志位未生效或未及时复位可确认字符串请求期间通道冲突是卡包原因之一。4. 检查 USB 发送逻辑是否合理操作步骤在biz_usb_send_data入队、biz_usb_data_dispose出队发送等关键节点添加调试日志。观察消息队列的入队/出队频率、队列是否频繁满、发送失败重试次数等指标。验证方法通过日志统计队列满次数、发送失败次数以及g_usb_send_delay_tick的轮询周期是否正常。预期结果若队列频繁满或发送失败重试次数过多说明发送逻辑存在快速发包导致的 FIFO 溢出或总线繁忙问题可确认发送逻辑不合理是卡包原因之一。5. 综合验证修复效果操作步骤依次应用「三、解决方案」中的三项措施调整中断优先级、设置字符串请求标志位、优化发送逻辑。重复执行第 1 步的复现操作观察卡包现象是否消失。验证方法长时间持续发送按键数据并反复重启 PC统计卡包次数。预期结果卡包现象完全消失MCU 发送的数据与 PC 端显示的数据完全一致说明修复生效。五、总结USB 卡包问题通常由中断优先级冲突、字符串请求期间通道占用以及发送逻辑不合理等原因引起。通过调整中断优先级、设置请求标志位以及优化发送逻辑可以有效解决 PC 重启过程中的 USB 卡包现象。六、参考资料[单片机][at32][填坑日记] [USB卡包] usb快速发包导致卡包[单片机][at32][填坑日记] [USB卡包] usb快速发包导致卡包(二)[单片机][at32][填坑日记] [USB卡包] usb上电过程中快速发包导致卡包(终章)
返回列表