LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   Why serial port /dev/ttyS1 after a while only send data and doesn't receive? (https://www.linuxquestions.org/questions/linux-software-2/why-serial-port-dev-ttys1-after-a-while-only-send-data-and-doesnt-receive-4175563391/)

webquinty 01-08-2016 04:21 AM

Why serial port /dev/ttyS1 after a while only send data and doesn't receive?
 
Hello,

I have kernel 3.6.11 with real time support (ingo molnar patch) and my app use serial port to connect access door control.
When app start, all works fine, but after a while ( 1 day or one week ) serial port doesn't receive anything but it is possible to send data.

Code:

n_bytes = read(fd_485, &byte_485, 1);
The function above always return me -1 and interrupt doesn't increase.
This is very strange, it's like driver doesn't reset flag interrupt, but I can't check or I don't known how to check it from user space.

This is init function where configure and open port:

Code:

int openserial(char *devicename)
{
int fd;
struct termios attr;
struct serial_struct serial;

        if ((fd = open(devicename, O_RDWR | O_NOCTTY | O_NDELAY)) == -1)
        perror("openserial(): open()");

    if (tcgetattr(fd, &oldterminfo) == -1)
        perror("openserial(): tcgetattr()");

    attr = oldterminfo;
    attr.c_oflag = 0;

    //**************************************************************************************
    //**************************************************************************************

    cfsetispeed(&attr, B19200);
        cfsetospeed(&attr, B19200);

        cfmakeraw(&attr);                                                        //--> OBTENER LOS DATOS EN RAW

        attr.c_cflag |= PARENB;                                                //--> HABILITAMOS LA PARIDAD
        attr.c_cflag &= ~PARODD;                                        //--> HABILITAMOS LA PARIDAD PAR
        attr.c_cflag &= ~CSTOPB;                                        //--> UN BIT DE STOP
        attr.c_cflag &= ~CSIZE;                                                //--> ACTIVAMOS 8 BITS DE DATOS
        attr.c_cflag |= CS8;

        attr.c_cflag &= ~CRTSCTS;                                        //--> NO HAY CONTROL DE FLUJO DE HARDWARE
        attr.c_iflag &= ~(IXON | IXOFF | IXANY);        //--> NO HAY CONTROL DE FLUJO DE SOFTWARE

        attr.c_cflag |= (CLOCAL | CREAD);                        //--> ENABLE RECEIVER AND SET LOCAL MODE

        attr.c_cc[VMIN]  = 1;                                                //--> LECTURA MINIMA DE CARACTERES DEL BUFFER
        attr.c_cc[VTIME] = 10;                                                //--> TIMEOUT DE LECTURA DE CARACTERES, EN PASOS DE 0.1 SEG

        ioctl(fd, TIOCGSERIAL, &serial);
        serial.flags |= ASYNC_LOW_LATENCY; // (0x2000)
        ioctl(fd, TIOCSSERIAL, &serial);

//**************************************************************************************
//**************************************************************************************

    if (tcflush(fd, TCIOFLUSH) == -1)
        perror("openserial(): tcflush()");

    if (tcsetattr(fd, TCSANOW, &attr) == -1)
        perror("initserial(): tcsetattr()");

    return fd;
}

And this is a function where I read all data avaible in serial port:

Code:

        while (1)
        {
                n_bytes = read(fd_485, &byte_485, 1);

                if (n_bytes < 0)
                {
                        error_rs485_negative = n_bytes;
                }
                else if (n_bytes == 0)
                {
                        error_rs485_zero ++;
                }
                else
                {
                        buffer_485[commEnd] = byte_485;

                        commEnd = ( commEnd + 1 )  BUFFER_RS485;
                        commItems ++;
                }

                // Tiempo de espera para no dejar la CPU tostada
                //********************************************************
                usleep(2000);  // Se ejecuta cada 1 ms, si no , peta la CPU con carga al 100%

                counter_rs485 ++;
        }

and cat /proc/tty/driver/serial

Code:

0: uart:16550A port:000003F8 irq:4 tx:0 rx:0
1: uart:16550A port:000002F8 irq:3 tx:336 rx:540 fe:6 pe:60 DTR
2: uart:unknown port:000003E8 irq:4
3: uart:unknown port:000002E8 irq:3

I suppose that parity error or frame error isn't the problem because I don't use software and hardware flow control, but now I am not sure.

any advice??

Best reagards.

webquinty 01-08-2016 07:53 AM

I just check linux driver for UART and I have some doubts.
My hardware is old ( Geode LX800 ), and interrupts are edge trigger.

In Linux driver ( linux-3.6.11/drivers/tty/serial/8250/8250.c ), there is a comment:

/*
* Configuration:
* share_irqs - whether we pass IRQF_SHARED to request_irq(). This option
* is unsafe when used on edge-triggered interrupts.
*/

By default, serial port driver use shared interrupts. Perhpas this is my problem. I am going to disabled shared interrupts and test it.

If somebody has other idea..........

Best regards.

jefro 01-11-2016 05:43 PM

I'd think it is the real time stuff. It's never really worked like it should in my opinion.

Anyway to test with near real time or standard kernel?

webquinty 01-13-2016 05:06 AM

Real time kernel

jefro 01-13-2016 07:37 PM

Can you see if use some other ways to test. Put in a different kernel or distro?


All times are GMT -5. The time now is 10:12 PM.