Linux hangs if UART is stressed

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Linux hangs if UART is stressed

Jump to solution
2,546 Views
miguelhortelano
Contributor II

I'm using a custom board which sports an iMX6 SOLO running Yocto with Kernel version 4.9.11-02307-gb200f6d.
My application uses serial communication with RS485 transceiver attached to the serial comms.
Pin control configuration -DTS- and UART initialization are described below.

There is no problem with such configuration when frame length sent through the serial ports is below 20-30 bytes but when frame length is above these values, eventually -sometimes it takes some minutes- the whole system hangs -by 'hangs' I meant that system gets unresponsive and I can't even connect through SSH, needing to restart Linux-

A simple while(1) sending a single byte causes this problem within seconds.
The problem is not related to one specific UART as it happens on other 3 UARTs configured the same way.
If I insert a delay when sending those bytes the problem never happens but obviously, this is not a satisfactory solution.

Is there something that I'm missing that could cause this issue?


DTS configuration:

&uart2 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_uart2_3>;
    fsl,uart-has-rtscts;
    status = "okay";
};

pinctrl_uart2_3: uart2grp-3 {
    fsl,pins = <
        MX6QDL_PAD_EIM_D27__UART2_RX_DATA   0x1b0b1
        MX6QDL_PAD_EIM_D26__UART2_TX_DATA   0x1b0b1
        MX6QDL_PAD_EIM_D28__UART2_CTS_B     0x1b0b1
    >;
};

UART inicialization:

int rs485 = ::open("/dev/ttymxc1"); 
if(rs485) { 
    struct serial_rs485 rs485conf; 
    rs485conf.flags = 0x00; 
    rs485conf.flags |= SER_RS485_ENABLED;  
    rs485conf.flags |= SER_RS485_RTS_ON_SEND;
    if (ioctl (rs485, TIOCSRS485, &rs485conf) < 0) { 
        qDebug() << QString("Error writing ioctl port (%1): %2").arg(errno).arg(strerror(errno)); 
        return false; 
    } 
}‍‍


UART stress -running in a separate thread-:

char byte = 0xff;
while(1) {    
    writeData(&byte, 1);
}‍‍‍‍

Thanks in advance.

Labels (3)
Tags (2)
1 Solution
2,137 Views
igorpadykov
NXP Employee
NXP Employee

Hi Miguel

one can try with nxp releases from linux-imx - i.MX Linux kernel 

or better with latest linux L4.14.78

linux-imx - i.MX Linux kernel 

Also one can try to disable uart sdma and use polling option.

Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

View solution in original post

2 Replies
2,138 Views
igorpadykov
NXP Employee
NXP Employee

Hi Miguel

one can try with nxp releases from linux-imx - i.MX Linux kernel 

or better with latest linux L4.14.78

linux-imx - i.MX Linux kernel 

Also one can try to disable uart sdma and use polling option.

Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

2,137 Views
miguelhortelano
Contributor II

Thks Igor.

I followed your last suggestion and disabled DMA for both Tx/Rx in DTS files.

uart2: serial@021e8000 {
    compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
    reg = <0x021e8000 0x4000>;
    interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH>;
    clocks = <&clks IMX6QDL_CLK_UART_IPG>,
         <&clks IMX6QDL_CLK_UART_SERIAL>;
    clock-names = "ipg", "per";
    /*dmas = <&sdma 27 4 0>, <&sdma 28 4 0>;
    dma-names = "rx", "tx";*/
    status = "disabled";
};

This way solves the issue and now the system never hangs. Also this change increases the UART performance for short frames length -we usually transmit blocks with less than 32 bytes which is below the Tx FIFO length-.

I'll dig into this problem to find out why UART's DMA could cause such behavior.

Regards

0 Kudos