embedded - 从 USB 虚拟 Com 端口设备检测打开的 PC COM 端口

标签 embedded usb device cdc stm32

我使用带有 STM32_USB-FS-Device_Lib_V3.2.1 USB 库的 STM32F105 微 Controller ,并根据我们的目的(与 RTOS 和串行 API 集成)调整了 VCP 示例。

问题是,如果连接了 USB 电缆,但 Windows 主机上的端口未打开,几分钟后设备最终会永久重新进入 USB ISR,直到端口打开,然后一切都会启动工作正常。

我已经检测了中断处理程序,可以看到当故障发生时,ISR 处理程序退出然后立即重新进入。发生这种情况是因为退出中断时 OTG_FS_GINTSTS 中的 IEPINT 标志未清除。此时的 OTG_FS_DAINT 包含 0x00000002(IEPINT1 设置),而 DIEPINT1 包含 0x00000080(TXFE)。调用 OTGD_FS_Handle_InEP_ISR() 中用于清除 TXFE 的行,但该位要么不清除,要么立即重新置位。当主机上的COM端口重新打开时,中断结束时OTG_FS_GINTSTS和OTG_FS_DAINT的状态始终为零,并且进一步的中断以正常速率发生。请注意,仅当正在输出数据但主机没有打开端口时才会出现该问题。如果端口打开或没有数据输出,系统将无限期运行。我相信输出的数据越多,问题就越早出现,但目前这还只是传闻。

VCP 代码有一个状态变量,它采用以下枚举值:

  UNCONNECTED,
  ATTACHED,
  POWERED,
  SUSPENDED,
  ADDRESSED,
  CONFIGURED

我们使用CONFIGURED状态来决定是否将数据放入驱动程序缓冲区中进行发送。然而,CONFIGURED 状态是在连接电缆时设置的,而不是在主机打开端口并连接应用程序时设置的。我看到当 Windows 打开端口时,会出现一阵中断,因此似乎在此事件上发生了一些通信;我想知道是否可以检测主机是否打开了端口。

我可能需要两件事之一:

  1. 防止 USB 代码首先卡在 ISR 中
  2. 判断主机端是否有设备端开放的端口,开放时才推送数据发送。

最佳答案

第 (1) 部分 - 防止中断锁定 - 由 ST 支持的 USB 库错误修复促进;它没有正确清除 TxEmpty 中断。

经过 ST 支持的一些研究和帮助,我确定了第 (2) 部分的解决方案 - 检测主机端口是否打开。按照惯例,当端口打开时,DTR 调制解调器控制线将被置位。此信息被传递到 CDC 类设备,因此我可以使用它来实现我的目标。应用程序可以更改 DTR 的行为,但在这种情况下,任何可能连接到此设备的客户端应用程序都不应发生这种情况。然而,有一个备份计划,如果设置了线路编码(波特率、帧),则隐式假定端口打开。在这种情况下,无法检测关闭情况,但至少不会阻止非常规应用程序在我的设备上运行,即使它会导致设备在断开连接时崩溃。

具体针对 ST 的 VCP 示例代码,我对 usb_prop.c 进行了以下更改:

1) 新增以下功能:

#include <stdbool.h>
static bool host_port_open = false ;
bool Virtual_Com_Port_IsHostPortOpen()
{
    return bDeviceState == CONFIGURED && host_port_open ;
}

2) 修改 Virtual_Com_Port_NoData_Setup() 对 SET_CONTROL_LINE_STATE 的处理:

else if (RequestNo == SET_CONTROL_LINE_STATE)
{
  // Test DTR state to determine if host port is open
  host_port_open = (pInformation->USBwValues.bw.bb0 & 0x01) != 0 ;
  return USB_SUCCESS;
}

3) 为了允许与通常不操作 DTR 的应用程序一起使用,我还修改了 Virtual_Com_Port_Data_Setup() 对 SET_LINE_CODING 的处理:

  else if (RequestNo == SET_LINE_CODING)
  {
    if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
    {
      CopyRoutine = Virtual_Com_Port_SetLineCoding;

      // If line coding is set the port is implicitly open 
      // regardless of host's DTR control.  Note: if this is 
      // the only indicator of port open, there will be no indication 
      // of closure, but this will at least allow applications that 
      // do not assert DTR to connect.
      host_port_open = true ;

    }
    Request = SET_LINE_CODING;
  }

关于embedded - 从 USB 虚拟 Com 端口设备检测打开的 PC COM 端口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5338875/

相关文章:

linux - 嵌入式 Linux shell (BusyBox) 检查文件列表是否存在并运行命令

unit-testing - 如何在交叉编译器中使用 gcov?

c++ - 对所有 USB 设备使用 RegisterDeviceNotification()

c# - 如何从通过 USB 连接的相机读取文件

ios - 如果我从我的开发者帐户中删除设备,它会影响配置文件吗?

android - Android 设备上是否需要 Adob​​e Air 才能运行 Flash 创建的 APK?

c++ - 如何编写 CanOpen 堆栈?

embedded - 在哪里可以找到有关编程 TI TMS320C64xx DMA Controller 的信息

USB转SPI转换器

Android Studio 3.5.2 找不到 USB 连接设备(但通过 adb 终端找到)