I used a simple driver for serial port in Linux with success in many projects, but recently I found an issue with it.
The scenario is an embedded Linux (running on iMX6) that runs a QT application (that creates a GUI on a touch display) and a C application that communicates over a serial port.
When QT application starts some complex graphics (I see its CPU load reaching 70-80%), the serial port application stops working correctly.
After some debugging, I noticed that the bytes really transmitted on the wire aren't correct. It seems one or two bytes are re-transmitted and one-two bytes aren't completely transmitted.
I suspect my serial port driver has some errors that are triggered only when the CPU is loaded by other processes, but I don't know how to fix them.
I use O_NONBLOCK flag when opening serial port, but write() always returns a positive number, so I think the byte is correctly moved to the low-level serial port driver and really transmitted... but it isn't always the case.
If I enable debugging messagin (with DEBUG_SERIAL macro), I always see correct data on stdout, but wrong data on the wire.
Any hint?
On 05/26/2021 01:53 PM, pozz wrote:
I used a simple driver for serial port in Linux with success in many projects, but recently I found an issue with it.[I didn't read your code]
The scenario is an embedded Linux (running on iMX6) that runs a QT application (that creates a GUI on a touch display) and a C application that communicates over a serial port.
When QT application starts some complex graphics (I see its CPU load reaching 70-80%), the serial port application stops working correctly.
After some debugging, I noticed that the bytes really transmitted on the wire aren't correct. It seems one or two bytes are re-transmitted and one-two bytes aren't completely transmitted.
I suspect my serial port driver has some errors that are triggered only when the CPU is loaded by other processes, but I don't know how to fix them.
I use O_NONBLOCK flag when opening serial port, but write() always returns a positive number, so I think the byte is correctly moved to the low-level serial port driver and really transmitted... but it isn't always the case.
If I enable debugging messagin (with DEBUG_SERIAL macro), I always see correct data on stdout, but wrong data on the wire.
Any hint?
But here's what I used for transmitting.
static int
send_char (ser * d, char c)
{
if (d->fd == -1)
longjmp (d->env, 2);
ssize_t nbytes = TEMP_FAILURE_RETRY (write (d->fd, &c, 1));
return !(nbytes == 1);
}
I think the TEMP_FAILURE_RETRY may be important.
but there's about a zillion other flags and iocls wot could be at fault.
So I dont' really know if it helps.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 296 |
Nodes: | 16 (2 / 14) |
Uptime: | 20:03:03 |
Calls: | 6,646 |
Calls today: | 1 |
Files: | 12,190 |
Messages: | 5,327,383 |