2013-02-10 77 views
4

我希望能够检测到Linux中串行端口的BREAK条件。这是如何完成的?Linux串行端口接收/读取BREAK条件

我想要检测何时停止BREAK条件开始

我希望,如果我这样做:

int serial_status; 
ioctl(serial_fd, TIOCMGET, &serial_status); 

则会有呈现出BREAK位值条件,但它似乎没有这样的事情。

我发现tcsendbreak()termios.h发送休息。我还发现了描述如何发送休息的tty_ioctl man page。但是如何获得休息?

注意:BRKINT已被建议(它产生中断发生时的信号SIGINT)。但是,让SIGINT是不是这样一个有用的API,有几个原因:

  • 我不能告诉它来自哪个串口从,在多串口方案。
  • 在终端运行程序时,我也可以从用户按Ctrl-C获得SIGINT
  • 如果我将我的程序作为守护程序运行,那么条件“如果终端是前台进程组的控制终端”将不是真的,是吗?
  • 不可能知道BREAK条件持续多久,何时停止。
+0

看看你连接到的'termios'手册中的'BRKINT'。 – 2013-02-10 22:44:08

+1

@AntonKovalenko:我为我的问题添加了一个注释,说明为什么我不认为'BRKINT'(生成'SIGINT')是有用的。 – 2013-02-10 22:52:13

+1

查看USART/UART驱动程序的源代码,标志为'TTY_BREAK',当异常接收条件(例如奇偶校验错误,成帧错误,溢出或中断)发生时,标志通常填充到接收缓冲区中。然而,*行规则*(userland获取Rx数据之前的下一个处理阶段)通常会过滤掉Rx数据中的标志。我隐约想起一个* line的*版本,它插入了20个NUL作为休息条件。或者可能是3个字节的'0xff'和'0x00'和'0x00' - http://lxr.free-electrons.com/source/drivers/char/n_tty.c?v=2.6.36#L1002 – sawdust 2013-02-11 00:07:14

回答

1

最佳答案我已经能够到目前为止发现是从IGNBRKBRKINT常数在termios结构tcsendbreak() man page描述为c_iflag。它说:

当既不IGNBRK也不BRKINT被设置时,一个BREAK读取作为一个空字节('\0')中,当PARMRK设置除,在这种情况下读出作为序列\377 \0 \0

(即0xFF 0x00 0x00

所以我想我应该设置PARMRK,并准备做读取的字节很少的处理。这提供了有关奇偶校验/帧错误的明确信息(尽管0xFF 0x00 0x00代表BREAK或其他一些奇偶校验/帧错误仍然不完全清楚)。

但是请注意,我发现this patch for PARMRK,这似乎意味着旧版内核中存在危险,即在使用PARMRK时可能会丢弃串行字节。

只要BREAK条件持续,或者只在BREAK条件开始时发送一次,这些字节是否连续发送也不清楚。所以目前尚不清楚BREAK条件的端是否可以通过这种方法检测到。

+1

这是有点晚了,但万一有人想知道同样的事情......接收硬件也不明确是否中断或帧错误。休息的电气语义非常简单:线路长时间保持低电平。 (需要多长时间?IIRC足够长的时间,以给定的波特率支持2+正常字节传输,可能会被误解)。还没有好的方法可以知道中断何时开始,因为它只是低线条件。这只是一个休息时间,如果它足够长时间才能晋级为休息而不是低下。 – SirNickity 2016-12-09 23:09:37