我正在编写一个C程序,它将从串口读取和写入。每次写入之后都会有一个读取,其中包含基于写入的数据。我将执行大约16种不同的写操作,每次写入后都会进行读取。
我仍然是串口编程的新手,我正在尝试确定如何处理这个问题。程序是否应该在每次写入/读取期间阻塞(基本上有大量的写入和读取循环)?
是否有可能让一个线程发送写入而另一个线程执行读取?是否可以创建回调以允许线程知道何时可以从串行端口读取数据?
感谢您的帮助。
编辑:
操作系统:Linux
答案 0 :(得分:1)
这听起来像一个带有读取和写入的简单循环就足够了。如果你想要更多控制(比如在没有输入X秒后写一个保持活动状态),请使用select
或poll
;它们允许您“感知”数据是否可用,因此read
不会阻塞(但是,如果在select和read之间发生了某些事情,您仍然应该读取非阻塞)。在这种情况下,多线程没有意义。
select
和poll
也允许您测试写入是否会阻止;再次,写非阻塞只是为了确定。除了select
或poll
之外,您通常不希望您的流程挂在某个阻止系统调用中。 (至少,我没有)
使用ioctl
在串行线上设置各种参数。使用
$ strace -o /tmp/strace.minicom -f minicom
启动minicom(或任何其他终端程序)并查看他们如何使事情正常工作,如果你遇到困难。与往常一样,请参阅man select/poll/read/ioctl
以获取更多信息。
答案 1 :(得分:0)
总的来说,有几种方法可以解决这个问题。最佳选择可能取决于您在阅读串行端口时所查看的数据类型以及您希望如何处理该数据中的错误。
第一种方法是打开串行文件以阻止IO并执行:
while (question) {
write(ser_fd, question.data, question.len);
sleep(1);
ioctl(ser_fd, FIONREAD, &answer.len);
answer.data = realloc(answer.data, answer.len);
read(ser_fd, question.answer, question.answer_len);
question = next(question);
answer = next(answer);
}
虽然我没有在此处进行任何错误处理。
如果您希望能够超时等待回复进入串口,那么这会改变很多事情。您应该考虑使用select,pselect,poll,ppoll或epoll系列调用。这些允许你的程序阻塞(睡眠)直到有数据准备好被读入。然后你可以循环一个民意调查并阅读,直到你完成答案或没时间用完。
另一个选择是尝试使用SIGIO,但我不建议这样做。要做到这一点并且难以调试并不容易。
此外,您可以使用SIGALRM将您从读取呼叫中解脱出来作为超时。
如果您尝试使用stdio输入和输出例程,那么这将更加困难。你将会遇到类似第一种方法的问题而无法询问有多少数据准备就绪。