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.

[参考译文] TM4C129CNCPDT:使用"Always On & quot 重新启动 PC;USB 电源导致 USB 串行卡在不良状态

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/802749/tm4c129cncpdt-pc-reboot-with-always-on-usb-power-causes-usb-serial-to-get-stuck-in-a-bad-state

器件型号:TM4C129CNCPDT

我们使用 TI 提供的 USBLib 来创建 USB CDC 串行器件(基于 TI-RTOS 的示例代码)。  该器件由 USB 总线供电、我强制 USB 外设在设备模式下运行。  当我们在具有"始终开启" USB 电源的 PC 上使用此器件时、USB 堆栈似乎在 PC 重新启动后陷入不良状态、器件将枚举为 USB 串行器件、但它不会发送或接收任何数据。  当设备从 USB 中物理卸下并重新插入时、所有设备都能正常工作、而无需在 PC 上重新启动。  上周我花了整整一个时间来调试这个、运气不好。

Tiva USB 生态系统是否支持像这样重新启动的 PC 的重新连接/重新枚举?  如果是、我缺少什么?  我想这将得到支持、因为自供电设备(如3D 和2D 打印机)很常见、但我可能会错。

谢谢、

David

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 David:
    很抱歉、我不是 USB 专家。 我们的 USB 专家正在出差、下周同一时间再见。
    我希望 PC 在重新启动后向器件发送某种类型的 USB 重置命令。 收到 RESET 命令后、器件将再次与主机进行枚举握手过程。 如果调试代码、您是否看到这种情况发生了。 您能否告诉您主机是否正确发送了 RESET 命令以及器件是否已接收到该命令。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    当器件重新枚举时、一个复位命令被从 PC 发送到 Tiva、而挂起中断也在 PC 关闭时被触发。 但是、在调试期间深入探究之后、我发现 USB 复位中断回调函数指针被设置为 NULL (0x00000000)。 我没有找到用于设置该回调的 USBLib API、因此我假设在使用 USBCDCD 库时不应该触摸该 API。

    为了澄清这一点、我确实看到当 USB 设备进入不良状态时、器件在 Windows 和 Linux PC 上进行枚举。 但是、我还没有找到处理枚举的代码。 我还知道(根据数据表)一些 USB 外设详细信息受 NDA 保护、因此我可能无法调试该过程。

    感谢您的快速回复。 但愿这有所帮助。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    当您从主机接收 RESET 命令时、是否还会重置串行器件(即 UART)? 这会产生影响吗?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我不确定您的串行设备是指哪种设备、但我没有重置任何硬件 UART。 我还尝试重置(终止和重新初始化) USB 串行器件、但这会导致 CPU 冻结、看门狗在2秒后将其复位。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    由于您使用 CDC 类、我的印象是您可能会创建一个 USB 到 UART 转换器类型的应用、因此建议您在从 USB 主机接收到 RESET 命令时也执行 UART 的外设复位。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    哦、我明白您的意思。  该器件的众多功能之一是生成其自己的 USB 串行输出。  即使内部生成的数据在重新启动后也会停止正确传输。  我编写的 USB 串行包装程序使用邮箱来排队等待数据、我在该代码中没有看到任何不良情况(除了 USB 串行驱动程序没有报告最后一条消息的成功传输)。

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

    尊敬的 David:

    我一直在尝试提出一些关于可能发生的事情的想法、但我还不太确定自己的情况。 不过、我希望获得更平放的基线来工作。

    您提到过使用 TI-RTOS 示例、是否可以使用基于 TivaWare 的非 RTOS 示例对此进行进一步测试? 我不熟悉 RTOS、虽然大部分情况下应该让 USB 保持独立、但我必须挖掘不熟悉的代码来确认枚举发生在何处以及枚举传递到何处。

    我有一个用于单个 CDC 器件的 TivaWare 示例、您可以改用它、如果可以的话: e2e.ti.com/.../1882.usb_5F00_dev_5F00_cdcserial.zip

    如果问题再次出现、我可以尝试看看是否可以以某种方式重现问题。 您是否知道是否可以将 BIOS 设置为使 PC 始终打开 USB? 或者、这是通过 Windows 设置"允许计算机关闭此设备以节省电源"来完成的吗? 我很容易就能测试到后者!

    我希望这不是一个 Windows 问题、因为当设备保持插入时、PC 未运行操作系统、枚举导致 Windows 无法正确识别。

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

    感谢您的回答。 我导入了您提供的代码、并进行了必要的调整、使其适用于我的设置。  我将 TM4C129C 系列与不同的外部晶体搭配使用、而不是 TM4C1294。 我也不使用 VBus 检测 USB 连接、因此我添加了:

    USBStackModeSet (0、eUSBModeForceDevice、0); 

    在尝试重新启动与以前相同的设置后、我都能够重现问题并避免出现问题。 在测试 PC 正在重新启动过程中、我在调试器运行的情况下在单独 PC 上的 UART0控制台键入了命令。 如果我在电脑重启时键入的内容太多(超过100个字符、不确定具体数量)、USB 设备将停止闪烁 RX 活动指示灯、并且 USB 串行功能不允许文本来回切换来。 不过、器件仍会枚举。 但是,如果在重新启动过程中只键入几个字符或根本没有字符,则在系统启动时 USB 设备将正常工作。


    上述步骤只是为了重现问题、与我们的软件使用 USB 串行器件的方式不完全相似。 但是、这确实有助于我得出两个结论:TI-RTOS 示例存在一些导致问题的差异、或者我的代码未阻止在 PC 重新启动时尝试传输。 我将在明天更深入地探究代码。 我将在找到更多详细信息后发布这些信息。

    至于在您的终端上测试 PC 的"始终开启"功能、这实际上取决于您使用的主板。 有些 PC 通过 BIOS 支持它、有些甚至不提供它、而另一些 PC 只是以这样的方式进行布线、以至于 PC 无法控制总线电压。 但是、在任何计算机上测试此情况的最简单方法是使用外部电源(在我的情况下、我可以使用调试 PC 为器件供电、同时使用另一台 PC 执行重新启动)。

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

    成功!!!

    在比较您发送给我的代码与 TI-RTOS 示例中的代码之间的差异后、我发现了这个问题。  非 RTOS 和 RTOS 示例处理 TX 数据的方式之间存在主要差异。  非 RTOS 示例不处理传输数据时的任何数据丢失。  如果新数据适合、它只会将数据放入 TX 缓冲区、否则数据会被丢弃、代码会移动。  但是、RTOS 示例会缓冲数据并等待 TX 中断发出信号量。  当 PC 重新启动时、此信标未发布。

    修复程序:

    我的代码在 RTOS USB 串行示例中从 USBCD.c 调用以下函数:  

    USBCDCD_sendData (packet、length、BIOS_wait_forever); 

    由于我没有使用超时、代码会在那里阻止执行、并永远生成任务。

    通过向函数调用添加超时并处理返回状态、我可以将传出数据排队、直到计算机重新连接到 USB CDC 设备。  下面是一个有关如何使其正常工作的快速且肮脏的示例:

    执行{ while (!USBCDCDCD_sendData (packet、length、5000L)); 

    这会导致任务在取消尝试并重试之前最多等待5秒钟。

    这个解决方案没有我想要的那么优雅、在 USBLib 中有一些东西可以处理比这个更好的系统断开和重新连接、这将是很好的。  但是、这让我现在可以恢复并运行。  感谢您发送该示例。  它可以更轻松地找到差异。

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

    很高兴听到您能够解决大部分问题! 我不是 RTOS 专家、因此我不确定是否有更巧妙的解决方案、但如果您愿意、我可以尝试联系 RTOS 团队专家、看看是否有人想提出有关如何更好地处理该问题的想法。

    我会将您的帖子标记为建议的解决方案、以便社区了解如果任何其他用户遇到类似问题、该怎么办。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我认为这应该为我们提供我们目前所需的一切、但我有兴趣在将来找到更好的方法来实现这一点、因为我们将使用 USB 作为其他器件。 如果有更好的解决方案、社区更新 USB 示例也会有所帮助。

    提前感谢您的讲解!
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    已经有几年了、但我似乎还记得我们在第一次尝试使用 TI-RTOS 运行 USB 堆栈时遇到了类似的问题。 我们与原始 TivaWare 软件工程师在这方面进行了合作、但在没有对其 USB 堆栈进行重大修改的情况下、超时时间是我们可以做的最好的。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢您的反馈。 这至少让我知道我的发展方向是正确的。