我需要什么: 基于usb的通信设备,从嵌入式目标(运行linux)到主机(运行Windows)
我有什么: 一个基于社区驱动程序的tty设备(u_serial.c,f_acm.c)和一个利用open / close / write / read命令的用户空间程序。
问题: 即使没有连接USB电缆,用户空间守护程序也会成功打开tty设备并从中读取。如果在发生这种情况时连接usb电缆 - 所有usb枚举都被保持,直到我取消程序(取消read(),即)。 当tty仅为open()ed而没有read()时,会发生相同的行为。
我看到了什么: 我的设备的open()函数定义为u_serial.c open()。 它看起来像这样:
static int gs_open(struct tty_struct *tty, struct file *file)
{
/*
*definitions
*/
/*
*basic error checks
*/
//check if the tty device is already open/not opened/currently being opened and deal with each
//if not open:
//<real code starts:>
/* Do the "real open" */
spin_lock_irq(&port->port_lock);
/* allocate circular buffer on first open */
if (port->port_write_buf.buf_buf == NULL) {
spin_unlock_irq(&port->port_lock);
status = gs_buf_alloc(&port->port_write_buf, WRITE_BUF_SIZE);
spin_lock_irq(&port->port_lock);
if (status) {
pr_debug("gs_open: ttyGS%d (%p,%p) no buffer\n",
port->port_num, tty, file);
port->openclose = false;
goto exit_unlock_port;
}
}
tty->driver_data = port;
port->port_tty = tty;
port->open_count = 1;
port->openclose = false;
/* if connected, start the I/O stream */
if (port->port_usb) {
struct gserial *gser = port->port_usb;
pr_debug("gs_open: start ttyGS%d\n", port->port_num);
gs_start_io(port);
if (gser->connect)
gser->connect(gser);
}
pr_debug("gs_open: ttyGS%d (%p,%p)\n", port->port_num, tty, file);
status = 0;
exit_unlock_port:
spin_unlock_irq(&port->port_lock);
return status;
}
删除了一些不相关的代码。见来源here。
请注意,即使usb没有连接(port-&gt; port_usb为0) - 我们继续并返回0,这意味着一切正常。 另请注意,如果未连接usb,我们不会执行gs_start_io(),它用于从设备进行实际读取,仅在连接usb时才有效。
这里有一个问题 - 如果内核是在open()命令没有错误的情况下构建的,而usb cable没有连接 - 为什么当我有一个开放的描述符到设备时它保持? 我会假设它无法在第一时间打开设备,或者忽略这种情况并继续正常连接USB连接。 另外,如果这是正确的行为 - 我如何处理/知道电缆是否断开?
几年前,here进行了类似的讨论,没有真正的结论。
最后的想法 - 如果在连接usb时会通知用户空间程序,可以解决这个问题,但这并不意味着当前的行为是正确的。
感谢。