使用 fstream 读取 Linux 设备
我可以在 C++ [io]fstream 中使用 /dev/usbtmc0
读取和写入设备,交替通过读取和写入来发送和接收消息。大多数命令都以单个换行符终止,因此很容易判断何时收到响应结束。我为此使用的简化代码是:
fstream usb;
usb.open("/dev/usbtmc0", fstream::in);
if (usb.good())
{
string output;
getline(usb, output);
usb.close();
// Do things with output
}
// Additional cleanup code...
然而,有一件事我没有注意到,它在 SCPI/IEEE 规范中定义为“*LRN?”。发送时,连接的设备将发回任意数据(规范中的实际措辞),这些数据可用于稍后在设备进入奇怪状态时重新编程。
该 LRN 命令的响应消息的问题在于它包含一个或多个换行符。它确实用换行符正确地终止了整个消息,但嵌入换行符的事实使其使用起来非常棘手。有些硬件会在有效负载前加上长度前缀,但有些则不会。
从硬件读取数据时,Linux usbtmc 内核驱动程序中内置了 5 秒超时,如果您尝试读取超过可用数据,该超时将阻止任何读取调用。
使用 fstream::eof 似乎没有返回任何有用的东西。它的作用很像一个套接字。有没有一种方法可以让我在不知道设备长度、终止的情况下读取设备上的所有数据,同时避免内核超时?
I'm attempting to get feedback from some hardware that is used over USBTMC and SCPI.
I can read and write to the device using /dev/usbtmc0
in a C++ [io]fstream, alternating by reading and writing to send and receive messages. Most commands are terminated by a single newline, so it's easy to tell when the end of a response is received. The simplified code I'm using for that is:
fstream usb;
usb.open("/dev/usbtmc0", fstream::in);
if (usb.good())
{
string output;
getline(usb, output);
usb.close();
// Do things with output
}
// Additional cleanup code...
There is, however, one thing that is escaping me, and it's defined in the SCPI/IEEE specification as "*LRN?". When sent, the connected device will send back arbitrary data (actual wording from the specification) that can be used to later reprogram the device should it get into a weird state.
The issue with the response message of this LRN command is that it contains one or more newlines. It does properly terminate the entire message with a newline, but the fact that there are newlines embedded makes it really tricky to work with. Some hardware will prefix the payload with a length, but some don't.
When reading data from the hardware, there is a 5 second timeout built into the Linux usbtmc kernel driver that will block any read calls if you try to read past what's available.
Using fstream::eof doesn't seem to return anything useful. It acts much like a socket. Is there a way that I can read all data on the device without knowing about its length, termination, and while avoiding a kernel timeout?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
为此使用
fstream
的问题是fstream
具有内部缓冲,设备fileOps->read
调用和fstream
操作。为了与设备驱动程序交互,您确实需要使用
unistd.h< 中的低级
open
、read
、write
函数/code> 和fcntl.h
。The problem with using
fstream
for this is thatfstream
has internal buffering, there's no 1:1 correlation between devicefileOps->read
calls andfstream
operations.For interacting with device drivers, you really need to use the low-level
open
,read
,write
functions fromunistd.h
andfcntl.h
.