0

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?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jacob Peddicord
  • 367
  • 2
  • 6
  • 15
  • 2
    Possibly this http://stackoverflow.com/questions/6029875/problem-with-eof-when-determine-stream-end/6029898#6029898 might shed some light. –  May 19 '11 at 21:10

1 Answers1

3

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.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • Hmm, I didn't really consider the buffering. I'll give this a go tomorrow and see how things go. – Jacob Peddicord May 20 '11 at 00:27
  • This ended up being a part of the problem. The other part was that the usbtmc driver in mainline doesn't set the EOF bit, so the read will always stall. Otherwise, this worked out. :) – Jacob Peddicord May 20 '11 at 20:34