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.

[参考译文] TM4C129XNCZAD:USBHCDControlTransfer()在64字节传输时挂起,较小的传输正常。

Guru**** 2419530 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/651986/tm4c129xnczad-usbhcdcontroltransfer-hangs-with-64-byte-transfers-smaller-is-ok

器件型号:TM4C129XNCZAD

我要将 DFU 主机支持添加到项目中。

DFU 使用控制传输进行数据传输。  USBHCDControlTransfer()支持对 USB 设备的写操作,它的工作正常,可以进行小传输。  如果我向设备写入63个或更少字节, USBHCDControlTransfer()将返回有效数据。

USBHCDControlTransfer()(在 usbhostenum.c 中) 会锁定 USB 中断、然后在 INT_EVENT_ENUM | INT_EVENT_SOF 中断位上进行引脚。  当这两个位都被置位时、它 会调用 USBHCEnumHandler()、然后调用 USBHCDEP0StateTx ()。  该例程一次最多向 器件发送64字节。  

我需要将千字节数据写入 USB 器件。  

系统设置:

USB 中断的优先级为0x20

SysTick 调用 USBHCDMain()、优先级为0x40 (低)

我正在从 main()调用 USBHCDControlTransfer()。  在我调用它之前、我禁用对 USBHCDMain()的系统调用。   我看到的一件事似乎有点奇怪、就是这个代码来自

USBHCDControlTransfer():

USBHostEndpointConfig (USB0_BASE、USB_EP_0、64、0、0、

             (USB_EP_MODE_CTRL | psDevice->ui32Speed |

              USB_EP_HOST_OUT);

这会将 ui32NAKPollInterval 设置为0。  从 USB 布线的角度来看、我知道我的 USB 器件执行 NAK 某些帧。  我看不到任何处理超时情况的代码。

 

 

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

    R Sexton、您好!

    要移回您已发布的代码行、即:

    USBHostEndpointConfig (USB0_BASE、USB_EP_0、64、0、0、
    (USB_EP_MODE_CTRL | USB_EP_SPEED_FULL |
    USB_EP_HOST_OUT);
    

    这将端点配置设置为与端点0通信(USBHCDControlTransfer 应尝试向其发送数据)、限制为64字节。 这是您看到的限制。

    现在、这里的核心问题可能是您没有为目标应用使用正确的 API。

    USBHCDControlTransfer 功能只能用于读取/写入端点0、端点0是控制端点。 您不应向控制端点写入 KB 数据。

    您可能需要将 USB 管道功能用于您的应用。 该系统要求您分配(并在完成后释放)与特定设备端点通信的管道。 您可以从此处使用用于 USBHCPepeWrite()和 USBHCPepeRad()的 API 将数据传输到端点。

    有关这些详细信息、请参阅 TivaWare USB 库用户指南的第3.2.3节、该指南位于[Install Path]\TivaWare_C_Series-2.1.4.178\docs 内、标题为"SW-TM4C-USBL-UG.2.1.4.178.pdf"、了解最新版本的 TivaWare。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我不认为管道 API 是一种解决方案。 它似乎不支持写入控制端点-我需要指定控制帧内容、并为数据阶段提供数据负载。

    USB DFU 协议可与器件控制端点一起工作、并在控制传输数据阶段传输数据。 DFU 规范(DFU_1.1.pdf)第4.1.2节对此进行了说明。 我有正常行为的 USB 分析器跟踪、我可以看到这一点。 USBHCDControlTransfer()似乎支持控制数据包中任意大小的数据传输-它保持状态、对数据包进行计数等 它不适用于超过63个字节。

    我无法告诉您、该代码是在错误条件下还是在 NAK 下执行正确的操作。 usb.h 中定义了一个似乎适用的事件- USB_HOST_EP0_NAK_TO,但它从未在 usblib 代码中使用。 从我的跟踪中可以看到很多帧在正常操作下得到 NAK 并重新传输、因此在 USBHostEndpointConfig()中将 ui32NAKPollInterval 设置为0似乎不是正确的做法。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    此外、从数据表中可以看出25.3.2.3 (作为主机的输出事务):

    ------
    如果目标设备用 NAK 响应输出令牌包、USB 主机控制器会一直重试传输、直到达到设置的 NAK 限制。 但是、如果目标设备用 STALL 握手响应、USB 控制器不会重试传输、而是通过置位寄存器 USBTXCSRLn 中的 STALLED 位来中断主处理器。 如果目标设备在所需的时间内没有响应输出令牌包、或者数据包包含 CRC 或位填充错误、USB 主机将重试传输。 如果三次尝试后目标设备仍未响应、USB 控制器将清空 FIFO 并将寄存器 USBTXCSRLn 中的 ERROR 位置位。
    ----

    我看不到任何证据表明 USB 主机代码处理了这种情况。 代码在 SOF 上旋转、并将更多数据存储到 FIFO 中、无论之前的尝试成功与否。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    更多数据:  

    问题的核心似乎是 USBHCDEP0StateTx()中的此位代码:

      //如果这正好是64,则尚未设置最后一个数据包。

      //

      if (ui32NumBytes =64)

      {

        //要发送的数据更多,或者发送的数据正好是64字节,这是

        //表示有更多的数据要发送,或者需要空数据包

        //要发送以完成事务。

        MAP_USBEndpointDataSend (USB0_BASE、USB_EP_0、USB_TRANS_OUT);

      }

      其他

      {

        //发送数据的最后一位。

        MAP_USBEndpointDataSend (USB0_BASE、USB_EP_0、USB_TRANS_OUT);

        //现在进入状态并等待传输完成。

        G_sUSBHEP0State.iState = eEP0StateStatusIN;

      }

    它错误地假定64字节传输不是最后一个字节传输。   

    其工作原理为:  

      if (g_sUSBHEP0State_ui32BytesRemaining) //尚未发送最后一个数据包。

    else //发送最后一个数据包。

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

    现在、我已经更好地了解了您的应用、我已经了解了过去需要为像您这样的应用向控制端点发送大于64字节的任何情况、并且找不到任何东西。 不能说这种需求不存在、而是我们以前没有提出这样的主题、因为看起来没有使用您共享的 DFU 1.1规范中所述的运行时 DFU 接口配置在主机模式下完成应用。

    在 usblib 的 devices 子文件夹内的文件 usbddfu-rt.c 中、对作为 USB 器件的 DFU 运行时提供固件支持、但我看不到主机模式的相同情况、因此看起来 TivaWare 的 USBlib 不提供该功能。

    就 USBHCDControlTransfer 的 USBlib API 而言、写入该字节限制也是为了实现该字节限制。 我只能假设当时编写 USBlib 的用户不需要发送更大的数据包、这可能是因为 USBlib 的文件系统中存在运行时 DFU 的明显分离。 没错、管道 API 不支持写入控制端点。

    尽管如此、我并未参与 USBlib 的开发、因此我无法自信地评论为什么会做出某些选择、或者对他们有什么理由、只能根据我看到的内容进行推测。 目前、在大多数情况下、我只需查看已编写和记录的代码、并尝试提供有关代码用途和使用方法的指导。 我只是没有详细的背景来解释做出某些决策的确切原因。

    是的、我同意您发布的代码片段在64字节的特定情况下似乎存在缺陷。

    如果您看到您认为应用需要进行进一步修改、例如扩展64字节限制或在特定情况下添加错误处理、我会说您可以根据需要进行修改、因为它不像主机模式运行时 DFU 那样受支持。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 RS、

    [引用 user="R Sexton"]我需要将千字节的数据写入 USB 设备。

    您是否可以使用 USB 大容量器件驱动  程序在器件模式下向主机传输大数据?

    Tivaware USB 大容量设备客户端示例项目 包括 一个带源 代码行的 MSVS2k 项目(Echo 客户端)、 可轻松 修改以实现  从 目标 GTO 端口到 主机 USB 达到480Kbps 的高速数据传输。