在C++中读写设备

7

我该如何在C++中读写设备?设备位于/dev/ttyPA1
我考虑使用fstream,但我无法知道是否可以在不阻止应用程序的情况下读取设备的输出。
我的目标是创建一个应用程序,在其中将某些内容写入终端并将其发送到/dev/ttyPA1。如果设备有返回值,则从设备读取并显示在屏幕上。如果没有,则提示用户再次向设备写入内容。
我该如何实现这个目标?


它是什么类型的设备?也许你应该使用 open() 和相关函数吗? - Lightness Races in Orbit
如果这很重要,它是一个PWM控制器。 - Daniel
2个回答

11
使用 open(2)read(2)write(2) 来读写设备(完成后别忘了使用close(2)函数)。你也可以使用 C 标准库函数(如fopen(3)等)或 C++ 文件流类,但如果你这么做,你几乎肯定要禁用缓冲(对于标准I/O,使用setvbuf(3),对于文件流,使用outFile.rdbuf()->pubsetbuf(0, 0))。
然而,所有这些操作都将在阻塞模式下运行。你可以使用select(2)来测试是否能够从文件描述符中读取或写入而不发生阻塞(如果不可能,就不应该这样做)。或者,你可以在文件描述符上使用O_NONBLOCK标志来打开文件(或在打开后使用fcntl(2)设置标志),使其成为非阻塞的;然后,任何调用read(2)write(2)如果会阻塞,将立即失败并显示错误EWOULDBLOCK
例如:
// Open the device in non-blocking mode
int fd = open("/dev/ttyPA1", O_RDWR | O_NONBLOCK);
if(fd < 0)
    ;  // handle error

// Try to write some data
ssize_t written = write(fd, "data", 4);
if(written >= 0)
    ;  // handle successful write (which might be a partial write!)
else if(errno == EWOULDBLOCK)
    ;  // handle case where the write would block
else
    ;  // handle real error

// Reading data is similar

0

你可以使用fstream,但是你需要查找设备的规格说明以确定它希望收到数据的方式。某些设备使用ASCII数据就可以了,而其他设备则需要特定的二进制数据位/字节序列。您还可能需要编写自定义序列化对象,重载用于编写数据的operator<<operator>>函数。否则,您可以使用read()write()方法从/向程序中分配的缓冲区数组读取/编写原始二进制数据。

编辑:如果您担心阻塞行为,那么您有两个选择。您要么必须使用POSIX API,并使用poll()select()检查已打开的文件描述符以查看是否有可用数据,要么您将不得不将任何文件写入或读取调用放在一组单独的线程中,这些线程可以基本上充当异步读/写操作。因此,您基本上会向读者/编写者线程发送消息,该线程如有需要会在fstream调用上阻塞,但是您的程序的其余部分仍然可以继续运行。但是,如果您的程序没有设计用于线程,则POSIX API将是唯一的方法。


这是二进制数据,我知道协议,但它没有指定发送回多少字节,所以我需要知道是否可以读取以及有多少字节。 - Daniel
你可以使用 fstream::read() 函数获取字节并将其加载到内部分配的缓冲区中,这基本上是在 C 中使用 read() 和使用 open() 分配的文件描述符时使用的相同方法。否则,你可以创建一些对象来管理自己的内部内存缓冲区,并重载 operator>> 函数以与你的自定义读取器对象一起使用。 - Jason
问题在于如果没有可读内容,它会阻塞,我需要在没有可读内容时不进行读取。 - Daniel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接