Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

"I prefer the blunted cudgels of the followers of the Serpent God." -- Sean Doran the Younger


devel / comp.arch.embedded / Re: Embedded linux serial port

SubjectAuthor
* Embedded linux serial portpozz
`* Re: Embedded linux serial portJohann Klammer
 `- Re: Embedded linux serial portpozz

1
Embedded linux serial port

<s8lcsm$56b$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=478&group=comp.arch.embedded#478

  copy link   Newsgroups: comp.arch.embedded
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: pozzu...@gmail.com (pozz)
Newsgroups: comp.arch.embedded
Subject: Embedded linux serial port
Date: Wed, 26 May 2021 13:53:59 +0200
Organization: A noiseless patient Spider
Lines: 200
Message-ID: <s8lcsm$56b$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=iso-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Wed, 26 May 2021 11:53:59 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="4f2ad62cf5f74dc9f9b37b8da5ae03c1";
logging-data="5323"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/27BafbwmP4qsuDRP+/k7qDhsTpxFtHC4="
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.10.2
Cancel-Lock: sha1:4RHPXYBGbtc63ceuW8/htNXvbcM=
Content-Language: it
X-Mozilla-News-Host: news://news.eternal-september.org:119
 by: pozz - Wed, 26 May 2021 11:53 UTC

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?

#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <time.h>
#include "serial.h"

//#define DEBUG_SERIAL

#ifdef DEBUG_SERIAL
static bool debug_tx;
#endif

SERIAL_HANDLE
serial_open(const char *serial_name, int baudrate)
{ if (serial_name == NULL) return INVALID_SERIAL_HANDLE_VALUE;

speed_t speed;
if (baudrate == 57600)
{
speed = B57600;
}
else if (baudrate == 115200)
{
speed = B115200;
}
else
{
return INVALID_SERIAL_HANDLE_VALUE;
}

int hSerial;

hSerial = open(serial_name, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (hSerial != -1)
{
int oldflags = fcntl (hSerial, F_GETFL, 0);
if (oldflags == -1) return -1;
oldflags &= ~O_NONBLOCK;
if (fcntl(hSerial, F_SETFL, oldflags) == -1)
{
return INVALID_SERIAL_HANDLE_VALUE;
}

struct termios options;
tcgetattr(hSerial, &options);

cfsetispeed(&options, speed);
cfsetospeed(&options, speed);

/* Input mode flags */
options.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF |
IXON | INPCK );
options.c_iflag |= IGNBRK;

/* Output mode flags */
options.c_oflag &= ~OPOST;

/* Control mode flags */
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~( CSTOPB | PARENB);
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;

/* Local mode flags */
options.c_lflag &= ~(ICANON | ECHO | ISIG);
options.c_lflag = NOFLSH;
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 1;

tcsetattr(hSerial, TCSANOW, &options);

#ifdef DEBUG_SERIAL
debug_tx = 1;
printf("-> ");
#endif
}

return (SERIAL_HANDLE)hSerial;
}

void
serial_close(SERIAL_HANDLE hSerial)
{ close(hSerial);
}

int
serial_getdata(SERIAL_HANDLE hSerial, void *data, size_t data_len,
unsigned int timeout_sec)
{ size_t bytes_read = 0;
uint8_t *d = data;
time_t t_begin = time(NULL);

while(bytes_read != data_len)
{
if ((timeout_sec > 0) && (time(NULL) - t_begin > timeout_sec)) {
break;
}
int ret;
ret = read(hSerial, d, data_len - bytes_read);
if (ret < 0) return -1; // Error
if (ret > 0) {
#ifdef DEBUG_SERIAL
if (debug_tx) {
printf("\n<- ");
fflush(stdout);
debug_tx = 0;
}
for (unsigned int i = 0; i < ret; i++) {
printf("%02X", ((unsigned char * ) d)[i]);
fflush(stdout);
}
#endif

d += ret;
bytes_read += ret;
}
}

return bytes_read;
}

int
serial_putchar(SERIAL_HANDLE hSerial, unsigned char c)
{ #ifdef DEBUG_SERIAL
if (!debug_tx) {
printf("\n-> ");
debug_tx = 1;
}
printf("%02X", c);
#endif
int bytes_written;

bytes_written = write(hSerial, &c, 1);
if (bytes_written != 1) return -1;

return 0;
}

int
serial_putdata(SERIAL_HANDLE hSerial, const void *data, size_t size)
{ const unsigned char *d = data;
while(size--) {
int ret;
ret = serial_putchar(hSerial, *d++);
if (ret < 0) return -1;
}
return 0;
}

int
serial_putstr(SERIAL_HANDLE hSerial, const char *s)
{ if (s == NULL) return -1;
return serial_putdata(hSerial, s, strlen(s));
}

#endif

Re: Embedded linux serial port

<s8mfup$18ct$1@gioia.aioe.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=479&group=comp.arch.embedded#479

  copy link   Newsgroups: comp.arch.embedded
Path: i2pn2.org!i2pn.org!aioe.org!gd6VLGmEDkbXyWfDVQPPbw.user.gioia.aioe.org.POSTED!not-for-mail
From: klamm...@NOSPAM.a1.net (Johann Klammer)
Newsgroups: comp.arch.embedded
Subject: Re: Embedded linux serial port
Date: Wed, 26 May 2021 23:52:16 +0200
Organization: Aioe.org NNTP Server
Lines: 34
Message-ID: <s8mfup$18ct$1@gioia.aioe.org>
References: <s8lcsm$56b$1@dont-email.me>
NNTP-Posting-Host: gd6VLGmEDkbXyWfDVQPPbw.user.gioia.aioe.org
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-15
Content-Transfer-Encoding: 7bit
X-Complaints-To: abuse@aioe.org
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:24.0) Gecko/20100101 Icedove/24.5.0
X-Notice: Filtered by postfilter v. 0.9.2
 by: Johann Klammer - Wed, 26 May 2021 21:52 UTC

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.
>
> 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?
>
>
>
[I didn't read your code]
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.

Re: Embedded linux serial port

<s8nmsn$13q$1@dont-email.me>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=480&group=comp.arch.embedded#480

  copy link   Newsgroups: comp.arch.embedded
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: pozzu...@gmail.com (pozz)
Newsgroups: comp.arch.embedded
Subject: Re: Embedded linux serial port
Date: Thu, 27 May 2021 10:56:55 +0200
Organization: A noiseless patient Spider
Lines: 57
Message-ID: <s8nmsn$13q$1@dont-email.me>
References: <s8lcsm$56b$1@dont-email.me> <s8mfup$18ct$1@gioia.aioe.org>
Mime-Version: 1.0
Content-Type: text/plain; charset=iso-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Thu, 27 May 2021 08:56:55 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="5d753d9509a829ec3d6b36414053d406";
logging-data="1146"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+zMSzYauEkf99JOe3trUXLaDH+EBPXhtc="
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.10.2
Cancel-Lock: sha1:Y4CcDKrRRLtkqd4WDEdzdp7IYNk=
In-Reply-To: <s8mfup$18ct$1@gioia.aioe.org>
Content-Language: it
 by: pozz - Thu, 27 May 2021 08:56 UTC

Il 26/05/2021 23:52, Johann Klammer ha scritto:
> 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.
>>
>> 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?
>>
>>
>>
> [I didn't read your code]
> 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.
>

I don't think TEMP_FAILURE_RETRY could help in my case. It simply retry
forever the write() while it returns -1 and errno==EINTR.

My function for writing is:

int
serial_putchar(SERIAL_HANDLE hSerial, unsigned char c)
{ int bytes_written;

bytes_written = write(hSerial, &c, 1);
if (bytes_written != 1) return -1;

return 0;
}

If write() returned -1, serial_putchar() would have returned -1 and the
caller would have detected this situation.

However in my case, when the problem arises, write() and read() never
return a negative number.

1
server_pubkey.txt

rocksolid light 0.9.8
clearnet tor