In an embedded Linux system, I am coding the project which tests serial port in a pyhsically loopback environment. It means I am connecting rx-tx.The peripheral output is RS-232
In order to test the port I am sending 1 byte then I read the sent byte. I repeat this cycle from 0x00 to 0XFF. I am using raw input type for UART.
It looks fine if I run my code on Linux-desktop PC.
However on my embedded Linux system, I can not read from RS-232 connection properly. At the end, I got read return zero.
What do you think about the possible problem?
I am checking my termios configuration referenced to the Serial Programming Guide for POSIX Operating Systems
StatusResult UartInterface::openComPort() { m_fileDesc = open(m_device.c_str(), O_RDWR | O_NOCTTY ); if (m_fileDesc == -1) { retStatus.type = COMM_ERROR; } configureUART(); return retStatus; } void UartInterface::configureUART(){ struct termios options; tcgetattr(m_fileDesc, &options); cfsetispeed(&options, B9600); cfsetospeed(&options, B9600); options.c_cflag |= (CLOCAL |CREAD); tcsetattr(m_fileDesc, TCSANOW, &options); options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CRTSCTS; /*=============================================*/ options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*=============================================*/ options.c_iflag &= (IXON | IXOFF | IXANY); /*=============================================*/ options.c_oflag &= ~OPOST; /*=============================================*/ options.c_cc[VMIN] = 0; options.c_cc[VTIME] = 10; tcsetattr(m_fileDesc, TCSANOW, &options); }
Here is my main test loop
std::cout<<"-----------UART DEBUG-------------n"; while( int(write_data) < 255 ){ n = write(m_fileDesc, &write_data, 1); if( n != 1) { std::cout << "UART write failed!n"; res=false; return res; } n = read(m_fileDesc, &read_data, 1); if ( n == 1){ if(read_data != write_data) { std::cout << "UART mismatch error!t data_read:0x" << int(read_data)<<" data write:0x"<<int(write_data)<< std::endl; res=false; //return res; } std::cout<<std::hex<<"Byte: 0x"<<int(read_data) <<" is OK!"<<std::endl; } else { std::cout << "UART read failed! Res: "<<n<<"Errno"<< strerror(errno)<<std::endl; res=false; return res; } write_data++; } (res) ? (std::cout<<"Uart interface test OK!"<<std::endl) : ((std::cout<<"UART FAILED!!"<<std::endl)); return res; }
Here is the output for embedded linux system.As you see read and write data are completely different. After an amount of repetation it ends with zero read?
-----------UART DEBUG------------- Byte: 0x0 is OK! UART mismatch error! data_read:0x0 data write:0x1 Byte: 0x0 is OK! UART mismatch error! data_read:0x0 data write:0x2 Byte: 0x0 is OK! UART mismatch error! data_read:0x0 data write:0x3 Byte: 0x0 is OK! UART mismatch error! data_read:0x0 data write:0x4 Byte: 0x0 is OK! UART mismatch error! data_read:0x0 data write:0x5 Byte: 0x0 is OK! UART mismatch error! data_read:0x0 data write:0x6 Byte: 0x0 is OK! UART mismatch error! data_read:0x0 data write:0x7 Byte: 0x0 is OK! UART mismatch error! data_read:0x0 data write:0x8 Byte: 0x0 is OK! UART mismatch error! data_read:0x0 data write:0x9 Byte: 0x0 is OK! UART mismatch error! data_read:0x1 data write:0xa Byte: 0x1 is OK! UART mismatch error! data_read:0x2 data write:0xb Byte: 0x2 is OK! UART mismatch error! data_read:0x3 data write:0xc Byte: 0x3 is OK! UART mismatch error! data_read:0x4 data write:0xd Byte: 0x4 is OK! UART mismatch error! data_read:0x5 data write:0xe Byte: 0x5 is OK! UART mismatch error! data_read:0x6 data write:0xf Byte: 0x6 is OK! UART mismatch error! data_read:0x7 data write:0x10 Byte: 0x7 is OK! UART mismatch error! data_read:0x8 data write:0x11 Byte: 0x8 is OK! UART mismatch error! data_read:0x9 data write:0x12 Byte: 0x9 is OK! UART mismatch error! data_read:0xa data write:0x13 Byte: 0xa is OK! UART mismatch error! data_read:0xb data write:0x14 Byte: 0xb is OK! UART mismatch error! data_read:0xc data write:0x15 Byte: 0xc is OK! UART mismatch error! data_read:0xd data write:0x16 Byte: 0xd is OK! UART mismatch error! data_read:0xe data write:0x17 Byte: 0xe is OK! UART mismatch error! data_read:0xf data write:0x18 Byte: 0xf is OK! UART mismatch error! data_read:0x10 data write:0x19 Byte: 0x10 is OK! UART mismatch error! data_read:0x12 data write:0x1a Byte: 0x12 is OK! UART read failed! Res: 0 Errno: No such file or directory
Advertisement
Answer
Solved the problem with 3 corrections:
First, I found a mistake about termios configuration. Here my hw. flow control must be closed and a Tildy looks missing.
options.c_iflag &= (IXON | IXOFF | IXANY); //FALSE options.c_iflag &= ~(IXON | IXOFF | IXANY); //CORRECT
After all, it figured out read return with zero problem. I can complete my test data up to 255. However, read and write data still mismatch!
Second I cleared all the termios flags instead of reading from the system.This provides me independency from the operating environment.
Then I added the following 2 lines after tcsetattr() in order to flush first data. And sleep() is necessary because the ioctl syscall can’t find any data to flush unless you wait for a while.
.... //tcgettattr(m_fileDesc, &options); //Ignore default system data memset(&options, 0, sizeof options); . . tcsetattr(m_fileDesc, TCSANOW, &options); sleep(2); tcflush(m_fileDesc, TCIOFLUSH);
sleep() looks like a workaround but I couldn’t find a better solution. Additionally, the following topics are very helpful. Clearing the serial port’s buffer