【发布时间】:2014-01-02 14:24:15
【问题描述】:
在尝试实现串行 IO 的一个相当简单的例程时,我遇到了一些心理障碍。
情况是我们有一个嵌入式 linux 板(想想 Pi / Beagle),它使用 standard Linux termios code 与 UART 上的另一个设备通信。
问题是我们有两个相互冲突的要求:
在传输方向上,我们希望阻止Linux messaging queue msgrcv() 函数,直到有消息到达供我们发送。
在接收方向,我们需要等待/阻止传入消息(它可以具有规范模式操作的终止字符)。
Tx 和 Rx 是异步的,并且彼此不相关 - 两者都可能随时发生。
轮询会很痛苦,因为它会引入 CPU 周期开销和响应延迟。
一种方法是将其拆分为两个线程,一个处理 Tx 并在 msgrcv() 上阻塞,另一个在 Rx 上并在规范模式下阻塞 UART read() - 但这会带来设置的痛苦在 Tx 和 Rx 进程之间增加信号量,并且都必须重复打开和关闭串行端口,并且 Rx 线程可能最终不得不轮询信号量以防 Tx 想要控制,让我们回到轮询。
我要强调的是,我对所有这些 Linux 东西都比较陌生,所以我完全准备好看到我在这里缺少的明显的解决方案/方法/调用/操作。
是否有某种方法可以阻止 UART Rx,但仍能够按需传输?
【问题讨论】:
-
'但这会带来在 Tx 和 Rx 进程之间设置信号量的痛苦,并且都必须重复打开和关闭串行端口' - 为什么有必要这样做?保持端口开放!
-
是否不能使用只读标志 (O_RDONLY) 打开 /dev/ttyx 设备文件一次,然后在另一个线程中使用只写标志 (O_WRONLY) 打开?通常你可以打开文件两次......在第一个线程中读取,在另一个线程中写入,而不打开和关闭文件描述符。
-
文件是否需要打开两次? RX 线程尝试打开端口,如果/成功,则将句柄/fd 作为 tx 线程创建参数传递。此后,rx 线程读取,tx 线程写入。 OP 似乎使本应非常简单的任务过于复杂。
-
只是一个建议:如果您可以从 sysV 消息队列切换到 POSIX 消息队列,那么(在 linux 上)mqid 是一个文件描述符。您不必阻止或投票。您可以使用
select,甚至在收到新消息时让mq_notify启动一个新线程。 -
@MartinJames - OP 不够熟悉,无法知道“显而易见”是可能的,因为我说我是 Linux 新手,所以不熟悉所有内部工作。
标签: c linux io embedded polling