USB论坛
直播中

赵淑洁

8年用户 1000经验值
私信 关注
[问答]

UVC中的数据不匹配是怎么回事?

我们在使用 FX3 时遇到了一个问题。 我们正在向两个 o/p 端点发送静态数据。 这里我们面临一个问题。
如果我们将调试打印放入代码并检查,我们可以看到帧头是相同的。 但是使用 USB 分析仪,我们观察到帧头与我们发送的完全不同。

例如,如果我们发送 - 0x0C 0x8D 0x00 0x00,... USB 分析仪中的数据是 0x8D 0x7E 0xFA 0xFD。

有人知道数据是如何被替换的吗?

回帖(1)

陈秀英

2025-5-22 17:03:40

在使用FX3进行UVC数据传输时遇到数据不匹配的问题,可能由以下几个原因导致:




1. UVC头部自动插入


UVC协议要求在每个视频帧前添加UVC Header(通常为12字节)。如果固件未正确预留空间或处理头部,FX3可能自动覆盖用户数据。



  • 现象:用户发送的数据前几个字节被替换为UVC头部字段(如0x8D 0x7E 0xFA 0xFD)。

  • 解决方法

    • 检查固件代码,确保在发送数据时预留UVC头部空间(例如从缓冲区第13字节开始填充有效数据)。

    • 确认UVC头部的生成逻辑是否正确(如SCR、帧长度等字段是否动态计算)。





2. DMA缓冲区配置错误


若DMA缓冲区地址或大小配置错误,可能导致数据被截断、覆盖或重复发送。



  • 现象:DMA传输时数据错位或部分被覆盖。

  • 解决方法

    • 检查CyU3PDmaChannelSetup中的缓冲区配置,确保sizecount参数与UVC帧大小匹配。

    • 使用CyU3PDebugPrint打印DMA缓冲区内容,确认数据写入正确。





3. 端点传输模式与包大小不匹配


等时传输(Isochronous)端点需要严格匹配wMaxPacketSize,否则可能触发自动填充或分片。



  • 现象:数据末尾被填充随机值,或头部被分片错位。

  • 解决方法

    • 在USB描述符中确认端点的wMaxPacketSize是否符合UVC规范。

    • 使用CyU3PSetEpConfig配置端点时,选择正确的传输类型(如CY_U3P_USB_EP_ISO)。





4. 字节序或数据类型处理错误


FX3使用小端模式,若数据处理时未统一字节序,可能导致多字节字段反转。



  • 现象:多字节数据(如长度字段)显示异常,但此问题可能不适用于单字节数据。

  • 解决方法

    • 检查代码中是否误用了字节序转换函数(如CyU3PCpuSwap32)。

    • 确保结构体定义与UVC协议对齐(使用#pragma pack(1)避免填充)。





5. USB分析仪配置或解析错误


虽然概率较低,但需排除分析工具本身的问题。



  • 解决方法

    • 对比多个分析工具(如Wireshark、Ellisys)的结果。

    • 确认分析仪解析UVC协议时未误判数据格式。





调试步骤建议




  1. 验证UVC头部生成逻辑



    • 在发送数据前,将整个缓冲区(含UVC头部)通过CyU3PDebugPrint打印,确认头部与数据部分均正确。
      uint8_t buffer[1024];
      // 填充UVC头部
      fill_uvc_header(buffer);
      // 填充用户数据(从buffer[12]开始)
      fill_payload(&buffer[12]);
      // 打印前16字节
      CyU3PDebugPrint("Buffer: %02X %02X %02X %02X ...",
                 buffer[0], buffer[1], buffer[2], buffer[3], ...);




  2. 检查DMA传输配置



    • 确认DMA通道的缓冲区地址与大小匹配实际数据。
      CyU3PDmaChannelConfig_t dmaConfig = {
      .size = 1024,  // 缓冲区大小需包含UVC头部
      .count = 4,
      .prodSckId = CY_U3P_UIB_SOCKET_PROD_3,
      .consSckId = CY_U3P_UIB_SOCKET_CONS_3,
      };




  3. 对比FX3与USB分析仪数据



    • 若FX3固件打印的数据正确,但USB分析仪显示异常,重点检查USB协议层配置(如描述符、端点模式)。






示例修正代码


假设用户未正确处理UVC头部,正确代码应如下:


#define UVC_HEADER_SIZE 12

void send_frame() {
    uint8_t frame[UVC_HEADER_SIZE + PAYLOAD_SIZE];
    // 生成UVC头部(参考UVC规范)
    frame[0] = 0x0C;  // Header length
    frame[1] = 0x8D;  // Header info
    // ... 填充其他头部字段

    // 填充用户数据(从第13字节开始)
    memcpy(&frame[UVC_HEADER_SIZE], static_data, PAYLOAD_SIZE);

    // 发送数据
    CyU3PDmaChannelCommitBuffer(handle, UVC_HEADER_SIZE + PAYLOAD_SIZE, 0);
}

通过以上步骤排查,应能定位数据被替换的根本原因。若仍无法解决,建议提供更详细的代码片段和USB描述符配置进一步分析。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分