行缓冲发生在哪里?在哪个流上?

Where is the line buffering occuring? On which stream?

我正在通过蓝牙在我的 smartphone 和 Raspberry Pi 之间传输字节。 Pi 运行 raspbian 并在其 GPIO 头上附加了一个蓝牙串口。在 smartphone 上,我使用各种 android 蓝牙控制台应用程序。

要在 Pi 中查看来自 phone 的数据,在我使用的终端上:

socat /dev/ttyAMA0 -

这工作正常,字符双向流动,一切正常。

但是 - 当我通过蓝牙从 phone 应用程序向 Pi 发送一个字符串时,只有在换行之后我才能在 Pi 终端上看到该字符串。 Pi->phone也是如此。所以行缓冲正在进行中。

使用示波器我可以看到我从蓝牙应用程序发送的每个字符都会产生 RS232 数据,因此在 phone 的输出路径上没有缓冲。缓冲在 Pi 的某个地方,换行符正在刷新它。

谁能描述一下这是哪里? (我熟悉 none/line/block 缓冲方案 - 只是不 where (我认为))

他 富有

--- 更多详情 ---

因此,为了解决我 Raspberry Pi 上本地终端的问题,我编写了最小的 java 应用程序,以使用 [=11] 读取来自 /dev/ttyAMA0 的字符的紧密循环=].从字面上等待一个字节,将其打印到控制台(使用 println())然后再次等待 read()

在通过蓝牙发送 0x0A 之前,我无法读取任何字符,此时所有先前缓冲的字符都会被输出。

这使 socat 脱离了循环,并且不需要在那里关闭行缓冲。

行缓冲似乎仍在运行 - 但它在哪里?

富有

来自 socat 的手册页:

" ... when data is available on one side and can be written to the other side, socat reads it, performs newline character conversions if required, and writes the data to the write file descriptor of the other stream, then continues waiting for more data in both directions."

我猜 socat 写入 stdout 是行缓冲的,因此您只会在换行符之后在终端上看到该行.

我没用过socat,不过好像see/set文件描述符有几个选项,比如CW-DCWFD:<fdnum>,参考man page .我会尝试将其更改为 stderr,看看会发生什么。

好吧,我终于解决了我的问题,足够深入,我可以继续我原来的发展道路。

我的解决办法是发出这个 TTY 设置: stty -F /dev/ttyAMA0 raw

其中 raw 是其他选项的合并 - 参见 http://linux.die.net/man/1/stty

组合选项很多,但最明显的是 min 1

所以现在当我使用蓝牙控制台通过蓝牙从 phone 发送字符时,我的 Java 程序 运行ning 中实时显示字符 运行ning Raspberry Pi.

我的 java 从 uart-connected 蓝牙东西读取的程序正在使用 jSSC 库。仅此一项对线路缓冲没有帮助。我必须先 运行 stty ... raw 然后 运行 我自己的应用程序。

我的 Java 程序中的示例:

readBytes() read 1 char 'h value 104 End of readBytes() readBytes() read 1 char 'e value 101 End of readBytes() readBytes() read 3 char 'l value 108 char 'l value 108 char 'o value 111 End of readBytes() readBytes() read 1 char ' value 10 End of readBytes()

最后会看到LF。所有其他 "hello" 在发送时被接收,而不是与 LF 一起在一个 readBytes() 中接收。

希望这对某人有所帮助!我不明白为什么这对 Pi 开发人员来说不是一个更常见的问题!