使用 fstream 读取 Linux 设备

发布于 2024-11-08 12:44:07 字数 971 浏览 8 评论 0原文

我正在尝试从 USBTMCSCPI

我可以在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浮生未歇 2024-11-15 12:44:07

为此使用 fstream 的问题是 fstream 具有内部缓冲,设备 fileOps->read 调用和fstream 操作。

为了与设备驱动程序交互,您确实需要使用 unistd.h< 中的低级 openreadwrite 函数/code> 和 fcntl.h

The problem with using fstream for this is that fstream has internal buffering, there's no 1:1 correlation between device fileOps->read calls and fstream operations.

For interacting with device drivers, you really need to use the low-level open, read, write functions from unistd.h and fcntl.h.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文