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.

[参考译文] TM4C1237E6PM:USB 输出,然后是*非常特定*数据包大小的输入,失败

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1099426/tm4c1237e6pm-usb-out-followed-by-in-of-very-specific-packet-sizes-fail

器件型号:TM4C1237E6PM

我已经为 Tiva TM4C1237编写了一个引导加载程序。  我使用 Python 程序对其进行测试。  我发现、经过专门调整的 USB 输出和输入事务组合始终如一地失败。

我正在使用小型 Python 程序 和 pyusb 通过 VID/PID 查找器件、并以交互方式发送 USB 请求以测试我的 Tiva 固件。  我可以向 EP0发送各种大小的输入和输出请求。  我发现这种交易组合始终失败:

  • 到 EP0的输出事务、恰好是 max_packet_size 字节的任何(1..n)的倍数、后跟
  • 到 EP0的输入事务、包含超过 max_packet_size 个字节。

在这些特定条件下、Out 交易成功、但随后的 In 交易将始终失败。  将任一事务大小偏离一个字节将防止发生故障。  发生故障后、后续的输入事务将经常继续失败、直到某个时候问题被清除、后续的输入事务将成功。

以下是一些特定的数值示例(max_packet_size 为64):

  • 无论输入大小如何、这些都将成功、因为输出大小不是64的倍数:
    • 输出63个字节、输入63个字节:  成功
    • 输出63个字节、64个字节:  成功
    • 输出63个字节、输入65个字节:  成功
    • 输出100个字节、输入63 个字节:  成功
    • 输出100个字节、64 个字节:  成功
    • 输出100个字节、输入65 个字节:  成功
    • 输出129个字节、输入512 个字节:  成功
  • 无论输出大小如何、这些都将成功、因为输入大小不超过64:
    • 输出64 字节、输入63字节:  成功
    • 输出64 字节、输入64字节:  成功
    • 输出128 个字节、64个字节:  成功
    • 输出512字节、64字节: 成功
  • 这些都失败了,因为输出正好是 n*64,其中 n=1、2、3、...,而输入超过64:
    • 输出64 字节、输入65字节:  失败
    • 输出64 字节、512 字节:  失败
    • 输出128 字节、输出100 字节:  失败
    • 输出512 字节、输入65 字节:  失败

经过进一步调查、我发现当发生输入故障时、是因为没有发生 USB 中断。

由于问题仅在非常特定的输出条件下发生、然后在中出现、我怀疑问题不在我的固件中。

我已经准备了一个最小 CCS 项目和 Python 程序来演示该问题、但该论坛不允许我附加这些文件、因此我不知道如何将它们提供给其他人。  我使用的是 CCS 版本11和 TivaWare_C_Series-2.2.0.295。

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

    您好!

     您可以将文件拖动到编辑窗口中。 我还会将您的问题转交给我们的 USB 专家。  

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

    我没有意识到拖放文件与菜单命令插入图像/视频/文件不同。

    这是一个包含项目、python 程序的 zip 文件和一个自述文件、其中包含重现问题的指令和一些指示事务失败时不会发生 Tx 中断的调试输出。

    e2e.ti.com/.../USBProblem.zip

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

    您好、Douglas、

    感谢您提供有关此问题的详细文档。 我今天刚回到办公室、由于它的复杂性、我可能需要几天时间来查看所有这些细节并提供一些反馈-我将尝试在星期三获得一些反馈。

    在我进行调查时、两人澄清了以下问题:

    1. 您是否仅在 EP0上看到过这种情况?或者您是否刚刚在 EP1或其他地方测试过?
    2. 器件是否以 USB DFU 模式运行?

    此致、

    Ralph Jacobi

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

    您好、Ralph、

    我没有使用任何其他端点对其进行测试。  该程序仅使用端点0、因此不配置其他端点。

    我不确定 DFU 模式是什么意思。  它不会实现 USB DFU 规范、如果这是您的意思、但它确实会从主机应用接收二进制映像、将其写入闪存、然后跳转到该映像。

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

    您好、Douglas、

    更需要了解堆栈使用的 USB 层。 DFU、CDC、批量等

    此致、

    Ralph Jacobi

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

    您好、Douglas、

    已经有一些时间深入研究您的代码、我发现您的大部分实现方案没有像利用 USBDCDStallEP0这样的低级 API 那样使用特定的 USB 协议。

    [引用 userid="520842" URL"~/support/microcontrollers/arm-based microcontrollers-group/arm -based microcontrollers/f/arm based microcontrollers-forum/1099426/tm4c1237e6pm -usb-out-fer-the-specific-package-size-faile"]所有这些都失败,因为它们完全是64、2、4、4、2、4、4、4、2、4、4、1、2、4、2、4、4、4、2、4、4、4、4、1、2、4、4、2

    首先想到的是、您如何将其缩小到这个精确的情况、以及您的 Python 程序和 USB 示例的设置、您没有发送零长度数据包(ZLP)来指示传输结束。 对于恰好是64字节的数据包或以64字节数据包结尾的一系列数据包(因此长度= 128、192等)、典型的过程是发送一个 ZLP、指示数据包已完成、然后准备接收下一个数据包。

    这种情况只与输出管隔离,专门针对 n*64大小的数据包,并且仅使用+/- 1字节,这一事实解决了这一问题,它确实是因为没有发送零长度的数据包。

    此 E2E 主题前后介绍了一些内容、包括 USB 分析器捕获的屏幕截图: https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/535829/64-byte-usb-packet

    同时、以下内容充分说明了 ZLP 是什么以及它为何重要: https://stackoverflow.com/questions/48975323/what-is-zero-length-packet

    这是一种 ZLP 处理、它是我们 USB 堆栈中特定于协议的文件的一部分、但由于您仅使用底层端点 API 就将一层从这些文件中抽象出来、因此我可以看到、实施中现在缺少了这种处理。

    请告诉我这种解释是否合理、或者我错过了实现 ZLP 的代码的一部分。

    此致、

    Ralph Jacobi

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

    不、这不是问题。

    >这是一种 ZLP 处理、它是我们 USB 堆栈中特定于协议的文件的一部分、但由于您只是使用底层端点 API 将一层从这些文件中抽象出来、我可以看到、现在实现中缺少了这种处理。

    TivaWare USB 库用户指南在第2.23节的开头部分指出、如果现有的 USB 器件类驱动程序不适合我的应用、我可以改用更低级的 USB 器件 API 进行开发。 现有的驱动程序不适合,所以我做了手册所说的。

    我的代码中缺少 ZLP 处理不是问题。 第2.23和2.24节介绍了低级 API。 这些部分从未提到过零长度数据包。 在有关环形缓冲器的一节中、仅提到了 ZLP 四次。 驱动程序库手册提到使用较低级 API 这一事实表明较低级 API 并不被视为不完整、并且要求程序员添加代码来发送或接收零长度数据包。

    此外、使用 USB 协议分析器、我可以看到所有输入和输出事务上的零长度数据包成功、因此 ZLP 处理不会从实现中丢失。

    经过更多调查、我现在看到的是输入和输出事务都将在输入或输出64字节后失败、因此它不仅限于我最初指示的输出条件。

    n*max 字节的输入或输出不会失败,但它会设置下一个事务失败的条件(取决于其大小)。

    这就是我在64位输入事务中看到的情况、紧接着是65位输入:

    • 状态从01开始、表示 RxRdy。
    • 接收到 Setup 包、64字节被复制到 FIFO、TxRdy 位被置位。
    • EP0中断产生。 状态为 Tx。 标志为01、表示 RxRdy 置1、TxRdy 已清零、这表示主机已接收发送的64个字节。
    • 当仍处于中断上下文中时、没有字节会像预期的那样被复制到 FIFO 中、以结束 Tx、因为最后一个数据包已满。 TxRdy 和 DataEnd 位被置位。 在该 ISR 调用结束时、该状态变为1B (SetEnd、DataEnd、TxRdy、RxRdy)、表示 SetEnd 标志现已生效。 我不认为应该是这样。
    • 下一个 EP0中断发生。 状态为状态。 状态位仍为1B (SetEnd、DataEnd、TxRdy、RxRdy)、表示主机尚未获取数据、清除 TxRdy 和 DataEnd 标志、SetEnd 仍为 true。 状态更改为空闲。

    下一个事务(65中的一个)从等于19 (SetEnd、DataEnd、RxRdy)的标志开始、指示 SetEnd 和 DataEnd 标志仍然为 true。 此事务失败。

    此时、USB 分析器显示输入65结果:

    • 输入令牌
    •   传输64字节
    • 输入令牌
    •   失速

    我认为 DateEnd 位仍然为 true、会导致此事务在完成之前结束。

    此外、一旦 SetEnd 标志变为 true、在我复位 MCU 之前它永远不会变为 false。

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

    您好、Douglas、

    我将在 AM 中查看您的帖子的完整详细信息、但 我想 快速回复、 询问您是否可以提供 USB 分析器捕获。  由于 ZLP 不是根本原因、查看 USB 分析仪捕获将是  在 我的末尾尝试和调试此问题的后续步骤的一部分

    此致、

    Ralph Jacobi

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

    是否要从 USB 协议分析器捕获数据?  还是仅仅是屏幕截图?  协议分析器是 Total Phase Beagle USB 480。  您能读取这种类型的文件吗?

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

    您好、Douglas、

    我 想获取完整的分析仪捕获文件-我进行了双重检查、看起来我可以获取该分析仪的软件来查看该文件。 我很确定我之前已经看过 Beagle USB 的总捕获数据、从几年前我所做的事情来看、GUI 看起来很熟悉。

    此致、

    Ralph Jacobi

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

    好的。  为您准备一些内容需要一些时间、因为我认为您需要一个"解码"版本的加密调试输出。

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

    也许吧?

    我主要想看看数据包是如何流动的、就像您描述的那样:

    [~ userid="520842" URL"μ C/support/microcontrollers/arm-based microcontrollers-group/arm -based-microcontrollers/f/arm -based-microcontrollers-forum/1099426/tm4c1237e6pm -usb-out-hex-and-by-y-the-specific package-sizs-fail/4082368#4082368"

    下一个事务(65中的一个)从等于19 (SetEnd、DataEnd、RxRdy)的标志开始、指示 SetEnd 和 DataEnd 标志仍然为 true。 此事务失败。

    此时、USB 分析器显示输入65结果:

    • 输入令牌
    •   传输64字节
    • 输入令牌
    •   失速
    [/报价]

    我对 USB 有很好的了解、但我对协议分析器查看器的深入了解不够、无法真正可视化您的描述、也无法手动插入文件。

    此致、

    Ralph Jacobi

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

    我附加了一个 zip 文件、其中包含 USB 协议分析器数据(65、64、65.TDC、总相位 Beagle USB 480中的数据)、以及一个长文件(USB 问题#2.rtf)、其中提供了所有测试的详细信息。

    对于不想阅读所有详细信息的人员、下面是一个快速摘要:

    我执行了以下 USB 控制传输测试:

    1. 在65中
    2. 在64中
    3. 在65中

    1和2成功。  3、虽然与#1相同、但失败。

    64中的状态标志看起来很糟糕、但传输仍然成功。  65次传输(#3)中的第二次传输开始时状态不佳: USB 控制寄存器 USBCSRL0中的 SetEnd、DataEnd、RxRdy)。  此传输失败。

    (总结结束。)

    协议分析器输出显示、表示传输的整体成功或失败的零长度数据包出现在前两次传输中。  第三个传输停止。

    我认为第3位、即第65位中的第二位失败的原因是  DataEnd 位仍然是在前一个传输中设置的、即在64位中。  我不明白状态标志如何在64内传输期间执行它们的操作。

    也许解决方案就是简单地向 TI USB 库添加代码、以清除我认为会导致问题的状态位。   不过、最好是真正了解导致问题的原因。

    e2e.ti.com/.../USB-Problem-_2300_2.zip

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

    您好、Douglas、

    这个报告的问题是 一 个很难 调查的请求、因为您确实使用了这里 USB 库中的一组拆线命令。 对于 使用库的任何人来说、这不是问题、对于给定的层、例如 CDC/HID 等、也不是问题

    我查看了 USB 分析器捕获和代码、 但实际上、我需要了解一点、以便能够比较您在实施中唯一完成的操作与 USB 库应如何处理相同情况、以确定是应用代码问题还是 USB 库问题 (如果是后者、为什么它不会影响其他应用程序)。

    遗憾的是、调查级别是我未能抽出足够的时间深入研究的问题、 当我能够这样做时、我实际上没有电流估计值、因为这超出了我们通常为 USB 库提供的支持级别、因为这是独特的实现方式。

    很抱歉,我不能尽快回复,我应该至少在上周的这个时候提供该状态报告。

    此致、

    Ralph Jacobi

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

    我不明白我有什么替代方案、也不明白这是如何对库进行如此独特的使用、这是您以前从未见过的。

    除非我有误解、否则任何人将库原样用于 CDC/HID 等、都是制作串行转 USB 适配器、鼠标和键盘(或声音设备或大容量存储设备等)。  这些器件都是如此常见、以至于它们有自己的 USB 规范中定义的类。  从我在 TivaWare USB 库用户指南中所读出的内容来看、我的选项似乎是为不属于这些类别的器件使用现有类、或使用低级 API。  具体来说、它说 "如果现有的 USB 器件类驱动程序不适合您的应用、您可以选择
    请改用较低级别的 USB 器件 API 来开发您的器件。"  正如我看到的、我唯一的选择是使用低级 USB API。  

    您必须有成千上万的客户没有生产已经定义了类别的器件、因为我和我的雇主没有。  他们是从事什么工作?  他们是否还必须使用这组已去除符号的命令,因为现有的类驱动程序都不适合其应用程序? 或者我是唯一的人吗?  如果我应该使用一些替代方法、这是什么?

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

    您好、Douglas、

    自2017年以来、我一直在支持 USB 库、这是我第一次让客户在 应用层中使用 USBDCDRequestDataEP0 / USBDCDSendDataEP0 / USBDCDStallEP0等 API。

    在少数情况下、我看到了不属于库的模式请求、它是针对 USB 定义类的、他们采用了现有的 TivaWare 类、如 CDC 或 HID 类、并将其修改为省略的 USB 定义类。

    我以前不支持 USB 规范中缺少的自定义类。 这并不是说它尚未完成、但这些客户尚未在 E2E 上发布请求、我在处理此类应用方面也没有经验。

    此致、

    Ralph Jacobi