I have a custom USB cdc-acm device which sends images to the computer thanks to serial communication. The kernel driver works fine as the device appears as /dev/ttyACM0 and I am able to send commands and get data using open, write and read functions.
As the device continuously sends data, I get this data in a separate thread in a while loop:
while (m_isListening)
{
int rd = read(m_file_descriptor, read_buffer, 512);
// Display read data
if (rd > 0)
{
std::cout << rd << " bytes read: ";
for (int i = 0; i < rd; i++)
{
printf(" %x", read_buffer[i]);
}
std::cout << " # END" << std::endl;
}
// Nothing was to be read
else if (rd == 0)
{
std::cout << "No bytes read =(" << std::endl;
}
// Couldn't acces the file for read
else
{
printf("%d %s \n", errno, strerror(errno));
}
}
std::cout << std::endl;
I manage to get data read and displayed, but I also have a lot of line like that (11 = EAGAIN error):
11 Ressource Temporarily Unavailable
So I have a couple of questions:
- How fast can I / should I access (read in) the tty file ?
- Does the EAGAIN error mean I can't read in the file while the device write into it?
- If yes, as a consequence does it mean that while I'm reading in the file, the device can't write into it? So does data get lost?
- Finally (and more subjective question), am I doing something really dirty with this kind of code? Any comments or suggestions about accessing real time data through tty file?
Thanks.
EDIT
Some more precisions: the purpose of this code is to have a C/C++ interface with the device under linux only. I know that the device is sending frames around 105 kbytes at a particular frame rate (but the code should not depend on this framerate and be smooth at 15 fps as well as at 1 fps... no lag).
As this is my first time writing this kind of code and I don't understood evrything from the man pages I found, I kept default settings from the sample I found for most of the code (opening and reading):
Opening:
// Open the port
m_file_descriptor = open("/dev/ttyACM0", O_RDWR | O_NOCTTY | O_NDELAY);
if (m_file_descriptor == -1)
{
std::cerr << "Unable to open port " << std::endl;
}
The only settings modification I did before reading was:
fcntl(m_file_descriptor, F_SETFL, FNDELAY);
... in order to set the reading non blocking (FNDELAY is equivalent as O_NONBLOCK if I understood well).