LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   over frame error in UART (https://www.linuxquestions.org/questions/programming-9/over-frame-error-in-uart-4175443225/)

answerme 12-28-2012 03:21 AM

over frame error in UART
 
Hi all

Well Iam working on UART kernel version 2.6.21 and Iam facing error called over frame error
I have my normal system(desktop) & pxa300 board communicating serially between them at baud rate 1200 ,with no h/w flow control,8bit data rate . Sending 128 bytes of data continoulsy after every 200 ms from destkop

Pxa board is reciever (always) & desktop is sender(always).


If I have open receiver thread (i.e normal serial application)from pxa board first & then transmit data from desktop there is NO overframe error its working fine. But if desktop is already transmitting data & then I open receiver thread from pxa board I am getting continuous over fram error .

One more interesting thing is I checked with baud 115200 in that case everything seems to be fine. There is no overfram error
Checked with 4800, 9600 baud rate overframe error exist.


In kernel level hardware buffer in

Code:

receive_chars(struct uart_8250_port *up, unsigned int *status)
{

do {
                ch = serial_inp(up, UART_RX);
                printk("%c \n",ch);
    }
}

Here also I am seeing garbage value which is giving to kernel buffer & then to application .
Any other question kindly let me know

theNbomr 12-28-2012 05:43 PM

Are you sure you've got the right terminology? In serial communications, there are framing errors, and there are overrun errors. What do you think is meant by 'overframe'? I've been around RS-232 for at least a couple of decades, programmed my share of UARTs, and bit-bashed serial IO more than once, and I've never heard that term. Can you post an exact copy of whatever error messages you are referring to? If it is coming from your own code, please post a copy of the relevant part(s).

--- rod.

answerme 12-28-2012 11:31 PM

Are you sure you've got the right terminology? In serial communications, there are framing errors, and there are overrun errors. What do you think is meant by 'overframe'

Code:

Ok its framing error only ,Its in the piece of kernel code that prints over fram error.That i have pasted it below .

Iam using 8250.c my board chip is "ST16654"

I think this will help u.I have highlighted BOLD code (please see printk("Over fram error \n");).That will continuously coming .With junk values


Code:

static void
receive_chars(struct uart_8250_port *up, unsigned int *status)
{
        struct tty_struct *tty = up->port.info->tty;
        unsigned char ch, lsr = *status;
        int max_count = 256;
        char flag;
#ifdef __IW_DEBUG__
        printk("%s \n",__FUNCTION__);
#endif       

        do {
                ch = serial_inp(up, UART_RX);
#ifdef __IW_DEBUG__
                printk("%c \n",ch);
#endif       
                flag = TTY_NORMAL;
                up->port.icount.rx++;

#ifdef CONFIG_SERIAL_8250_CONSOLE
                /*
                * Recover the break flag from console xmit
                */
                if (up->port.line == up->port.cons->index) {
                        lsr |= up->lsr_break_flag;
                        up->lsr_break_flag = 0;
                }
#endif

                if (unlikely(lsr & (UART_LSR_BI | UART_LSR_PE |
                                    UART_LSR_FE | UART_LSR_OE))) {
                        /*
                        * For statistics only
                        */
                        if (lsr & UART_LSR_BI) {
                                lsr &= ~(UART_LSR_FE | UART_LSR_PE);
                                up->port.icount.brk++;
                                /*
                                * We do the SysRQ and SAK checking
                                * here because otherwise the break
                                * may get masked by ignore_status_mask
                                * or read_status_mask.
                                */
                                if (uart_handle_break(&up->port)) // if a BRK has been received, and if it returns TRUE, skip to the next character
                                {
                                        //printk(" ignore_char  \n");
                                        goto ignore_char;
                                }
                        } else if (lsr & UART_LSR_PE)
                        {
                                //up->port.icount.parity++;
                                printk("Over parity  error \n");
                        }
                        else if (lsr & UART_LSR_FE)
                        {
                                //up->port.icount.frame++;
                                printk("Over fram error \n");
       
                        }

                        if (lsr & UART_LSR_OE)
                        {
                                //printk("Over run error \n");
                                up->port.icount.overrun++;
                        }

                        /*
                        * Mask off conditions which should be ignored.
                        */
                        lsr &= up->port.read_status_mask;

                        if (lsr & UART_LSR_BI) {
                                DEBUG_INTR("handling break....");
                                flag = TTY_BREAK;
                        } else if (lsr & UART_LSR_PE)
                                flag = TTY_PARITY;
                        else if (lsr & UART_LSR_FE)
                                flag = TTY_FRAME;
                }
                if (uart_handle_sysrq_char(&up->port, ch)) // with the received character,and if it returns TRUE, skip to the next character
                {
                        printk(" ignore_char  \n");
                        goto ignore_char;
                }

                uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag);

        ignore_char:
                lsr = serial_inp(up, UART_LSR);
        } while ((lsr & UART_LSR_DR) && (max_count-- > 0));
        spin_unlock(&up->port.lock);
        tty_flip_buffer_push(tty);
        spin_lock(&up->port.lock);
        *status = lsr;
}

To reslove this problem
- I tried using different cable.
- Suspect uartclk also so I used same pxa board for tranmsit side also but same framing error .
- Application level also i tried different things like enable Hw flow control (CTS/RTS) but same error.

theNbomr 12-29-2012 11:23 AM

Okay, a quick bit of arithmetic:
Code:

1200 bps X 11 bits/word (8N1 + 1 intercharacter space) = 9.17 ms per word.
128 words X 9.17 ms = 1.17 seconds.

The minimunm time to transmit 128 words at 1200 baud is 1.17 seconds, and you're trying to send every 200 ms. That would account for the failure at low bit rates, but not at higher bitrates. The code that is sending the data should probably be inspected, since it should not cause errors on the line, but rather should block or return error codes back to higher level calling code.

--- rod.

answerme 01-07-2013 10:51 PM

Hi I have found this patch for rectifying this frame error when I paste this code in serial_handle_port() function

Code:

if (UART_BUG_FSLBK & up->port.bugs && up->lsr_last &
>> UART_LSR_BI) {
>> +            up->lsr_last &= ~UART_LSR_BI;
>> +            serial_inp(up, UART_RX);
>> +            spin_unlock_irqrestore(&up->port.lock, flags);
>> +            return;
>> +    }
>> +
>> +    status = up->lsr_last = serial_inp(up, UART_LSR);

I found over frame error is not coming now ,but still not able to understand what this piece of code is doing .Please see the link below from where I got this patch

http://comments.gmane.org/gmane.linux.serial/6615


All times are GMT -5. The time now is 05:19 AM.