This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TM4C1233E6PM:TIVAWare USB 库 HID 应用

Guru**** 661510 points
Other Parts Discussed in Thread: TM4C1233E6PM
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/618124/tm4c1233e6pm-tivaware-usb-library-hid-application

器件型号:TM4C1233E6PM

 

客户尝试实施 USB HID 并在 USB HID 帧上传输数据。 数据包长度是可变的、 实现可以随时发送或接收数据(当然在 USB HID 限制范围内)。  数据包还包括一个序列号、允许主机和/或设备注意数据包是否被丢弃。  使用 TM4C1233E6PM、他们 使用 TivaWare USB 库来处理 USB 层。  他们注意到、在两个方向上传输了大量数据、我们偶尔会收到重复的数据包。 使用调试器进行故障排除后 、他们注意到以下情况:

 

‘使用 USB 分析仪,我们注意到会出现随机的“分类错误”故障。 USB 分析仪将‘Classification Error’(分类错误)定义为‘An error occurred during class-level analysing’(分类级别解析期间发生错误) 此消息将始终具有0字节有效载荷


  • 此‘分类错误’数据包将始终在有输入报告和输出报告的帧之后出现1-2帧。

     

  • 在‘时,他们注意到,在‘分类错误’数据包之后,调用时返回‘0’的 USBDHIDReportWrite’函数(根据函数标头,这意味着失败)。

  • ‘返回‘0’的 USBDHIDReportWrite’(USBDHIDReportWrite)函数(根据函数标头,这意味着失败) 时,将看到重复的数据包被发送到主机

  •  设置代码时,如果‘USBDHIDReportWrite’返回‘0’, 它们就不会将缓冲区前移至下一个 USB HID 数据包,因为 它们将故障解释为需要 再次将其重新加载到 USB HID 驱动程序中。

  •  ‘观察结果,他们决定修改代码,使缓冲区前进,而不管从“USBDHIDReportWrite”函数返回的值如何

  •  ‘调试器运行一个快速测试,他们能够在‘USBDHIDReportWrite’返回‘0’的情况下进行捕获,并注意到没有重复的数据包(classification error’failure was still present)

  •  根据这些结果、他们决定隔夜运行测试以查看性能

    • 在该软件配置中 ,他们验证了发送和/或接收的大约500万条消息包含正确的序列号,因此不会被分析为丢失和/或重复

 

他们 认为 他们找到了重复消息的权变措施、但根据函数头、 他们 不能确认他们 以正确的方式使用库。  他们认为‘分类错误’数据包是可以接受的,因为它将被丢弃,但 不会将其视为‘预期的’。

 ‘担心的是,如果他们做了不正确的操作,导致“USBDHIDReportWrite”函数报告失败,但仍会发出消息。


 


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Lawrence、

    为了真正深入了解并找出报头说明是否误导人或是否错误使用 API、我需要能够以可以对其进行全面调试的方式观察问题。 这意味着我需要源代码、理想情况下、它位于已知良好的 TI 硬件设置中、例如 LaunchPad。

    不过、我想说的是、这不是第一次 TivaWare 头不是100%精确。 听起来、他们遇到的情况并不常见、因此可能尚未通过测试或观察来查看确切的函数行为。 此外、如果通信通道未因此而中断、可能只是在测试过程中从未注意到。

    查看 API 的详细信息、有两个可能返回错误的点。 我想看看他们是否可以在出现该问题时跟踪这两个问题中的哪一个。  我最想知道他们是否成功的是这个:

    //
    //我们可以发送提供的数据吗?
    //
    if (psInst->iHIDTxState!= eHIDStateIdle)
    {
    //
    //我们正在发送另一份报告。 将0返回到
    //指出我们直到上一个报告才发送此报告
    //完成。
    //
    psInst->bSendInProgress = false;
    返回(0);
    } 

    他们应该能够在那里设置某种标志或计数器。 如果他们做了计数器、他们甚至可以计算计数器增量的次数与所得到的重复数据包的次数。

    在我们的 TivaWare 示例中、似乎示例设置为与标头匹配、并且返回0被视为 false、 但同样、不确定器件和库是否曾在输入和输出报告都位于同一帧的情况下进行过测试、或者是否发生了这种情况、是否会注意到这种事件。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    拉尔夫

    客户将计数器放置在 USB 库中、它永远不会命中您引用的 if 语句。 每当出现问题时、他们都会注意到以下情况:

    -在 USBDHIDReportWrite 函数中,ScheduleReportTransmission 函数始终返回-1
    -在 ScheduleReportTransmission 函数中,MAP_USBEndpointDataPut 函数始终返回-1

    不确定这是否有用。 有什么建议吗?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Lawrence、

    好的、这一点很有帮助、因为我们现在至少可以将故障跟踪到源。

    在 DriverLib 中、USBEndpointDataPut 函数只有以下将返回-1的块:

    //
    //如果 TxPktRdy 位已置位,则不允许发送数据。
    //
    IF (HWREGB (ui32Base + USB_O_CSRL0 + ui32Endpoint)和 ui8TxPktRdy)
    {
    return(-1);
    } 

    因此、这表示根据 DriverLib 函数指示的内容、USB 数据从未在该函数调用中实际传输... 我觉得这与他们的观察结果不一致。 尽管如此、我还不确定 ROM API 的功能是什么、因此 ROM API 和最新的 DriverLib API 之间可能存在差异。

    我将查看我是否可以找到 ROM API 调用的详细信息、但也许他们可以尝试映射到 DriverLib USBEndpointDataPut 调用、而后者位于 usb.c 中、并查看结果是否相同或是否完全更改。

    此外、进一步详细查看 ScheduleReportTransmission 函数时、会显示以下注释:"该函数确保报告作为完整数据包序列发送、后跟单个 Int16_t 数据包或无数据的数据包、以指示事务结束。" 我想知道这是否是他们看到的0字节有效载荷数据包...?

    虽然函数表明它确保了这一点、但我在 ScheduleReportTransmission 或 USBDHIDReportWrite 中看不到任何种类的多个发送序列、以指示"完整数据包的序列后跟..." 无需更高层的帮助即可执行。 所有这些 都不符合上述有关返回-1的 ROM API 调用的陈述、而只是我在结尾时想到的另一种思维方式。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Lawrence、

    我确认了 API 的功能是相同的。 我想了解 MAP_USBEndpointDataPut 函数在看到以任何方式传输 USB 数据包时是否返回-1。 这是他们可以检查的吗?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    客户更新:

    他们 能够验证前一封电子邮件中的代码是事务失败的地方。 ‘re使用逻辑分析仪并中断“Turn (-1)”代码行,它会显示出最后一个要发送的数据包是0字节数据包。 代码暂停后 、它们在调用 USBDHIDReportWrite 上放置了一个断点、该断点应在发送另一个数据包之前暂停代码。 当这个断点被命中时、逻辑分析仪显示一个数据包已经被发送到主机。 我确认这是事务失败的最后一次发送的数据包。

     

     作为一个在跟踪此信号时想到的西信号、 它们实际上正在实施一个 USB 复合设备(端点1上为 HID、端点2上为 DFU)

     

     此时,它们删除了除 USBEndpointDataPut 内的‘ret(-1)"行之外的所有断点。 一旦这个断点被命中、 他们在 USBEndpointDataPut 函数的开头添加了另外一个断点、希望了解下一个消息传输的来源。  他们能够在这上面进行捕获、下面是该意外数据包的来源:

     

    • 触发 USB0DeviceIntHandler 中断

    • USB0DeviceIntHandler 中断调用 USBDeviceIntHandlerInternal

    • USBDeviceIntHandlerInternal 调用端点处理程序(g_ppsDevInfo[0]->psCallbacks->pfnEndpointHandler (pvInstance、ui32Status))

      • 我认为 ui32Status = 0x20002

    • 复合端点处理程序(usbdcomp.c 中的 HandleEndpoints)调用 HID 端点处理程序(usbdhid.c 中的 HandleEndpoints)

    • HandleEndpoints 调用 ProcessDataToHost

      • 根据 ui32Status 和(1 << USBEPToIndex (psInst->ui8INEndpoint))为 true 输入

      • Ui32Status = 0x20002且 PsInst->ui8INPoint = 0x10、因此(0x20002 &(1 <<((0x10)>> 4)= true

    • ProcessDataToHost 调用 ScheduleReportTransmission

      • (psInst->ui16InReportSize (23)=psInst->ui16InReportIndex (0))

      • 23是要发送的失败消息的长度

    • ScheduleReportTransmission 使用错误消息的 pui8Data 和 ui32NumBytes 调用 USBEndpointDataPut。

     

    根据库中的注释、问题可能出在 ProcessDataToHost 函数中是否能够调用 ScheduleReportTransmission? 这是我们首先看到失败请求的剩余部分。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Lawrence、

    "ScheduleReportTransmission 使用错误消息的 pui8Data 和 ui32NumBytes 调用 USBEndpointDataPut。"
    "根据库中的注释、问题可能出在  ProcessDataToHost 函数中是否能够调用  ScheduleReportTransmission?"

    • 我不确定我是否跟随这里。 ui32NumBytes 的计算方法如下:
    ui32NumBytes =(uint32_t)(psHIDInst->ui16InReportSize -
    psHIDInst->ui16InReportIndex); 
    • 如果该变量不正确、则 HID 器件数据指针是故障源。 请注意、仅当以下 if 语句为 false 时才调用 ScheduleReportTransmission API:
    if (psInst->ui16InReportSize =psInst->ui16InReportIndex) 
    • 这些是用于计算 ui32NumBytes 的相同变量、因此如果它们不正确、问题不在 ProcessDataToHost 中 、而是在从更远的线路向其馈送数据包的情况下。 基于此示例、我看不到不允许 ProcessDataToHost API 调用 ScheduleReportTransmission API 的原因。

    话虽如此、我在 USB 库的任何开发中都没有任何作用、我可以根据 API 的功能和留下的评论来解释 API。 因此、我不清楚实例数据问题的来源。

    如果他们能更清楚地说明 ProcessDataToHost 函数是其 API 调用的错误的推理、那么我大家都在听、并将深入研究它、但根据他们提供的内容、我认为目前情况并非如此。

    我想回到原来的话题、就是询问他们是否滥用了 API、现在我还没有看到任何让我认为特定 API 被滥用的东西。 相反、我认为谨慎的做法是跟踪23字节长数据包正被馈入实例数据的位置、并确定是否正确加载和/或是否被告知转至正确的端点处理程序。 USB 堆栈好像沿线路的某个位置没有预料到数据包会进入。 此外、我还会注意到、我对复合器件不太熟悉、因此我不确定是否有任何额外的复杂问题、这些问题可能会导致这些问题。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Richard、

    其他信息如下。  在收到您的最新反馈之前、请注意以下客户提供的信息:

    我对代码的期望是,对于每个成功的 USBDHIDReportWrite 调用,我们将收到一个状态为‘USB_EVENT_TX_COMPLETE’的 USB TX 回调调用。 我们的设计使用这些函数调用来锁定和解锁我们的互斥体、这将在意外情况下限制对 USBDHIDReportWrite 的多次调用。 我使用了一个断点来查看是否在接收 TX 回调而未锁定互斥的情况下。 该断点已命中,USB 分析器显示在0字节‘分类错误’消息后立即收到该断点。 ‘ProcessDataToHost 函数,“psInst->ui16InReportSize”函数会报告38,它与0字节消息之前的消息长度一致。 我无法进一步跟踪0字节消息的来源。 尽管发送此消息不应导致主机端出现任何故障、但了解我们为什么看到并可能解决此消息的原因仍不失为一种好方法。

     

    ‘重复的消息问题,我要测试的一个解决方案是,如果我们从‘S日程传输’接收到-1,则在‘USBDHIDReportWrite’(USBDHIDReportWrite)中将 psInst->ui16InReportSize’(ui16InReportSize)设置为0。 我‘S的是,‘我们已经在进入‘调度报告传输’之前确认我们处于‘eHIDStateIdle’状态,如果调度数据包失败,我们应该重置报告大小,使其看起来没有数据包被装载到 FIFO 中。 我正在运行一个长期测试、以查看这是否可以解决我们的问题、但是在使用断点和逻辑分析仪收集几个数据点时、它看起来很有希望。