我使用带有 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 打开端口时,会出现一阵中断,因此似乎在此事件上发生了一些通信;我想知道是否可以检测主机是否打开了端口。
我可能需要两件事之一:
- 防止 USB 代码首先卡在 ISR 中
- 判断主机端是否有设备端开放的端口,开放时才推送数据发送。
最佳答案
第 (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/