UART /dev/ttyLP1 resource temporarily unavailable on read()

Hi,

I’m getting a strange behavior on my Hello World C program that writes and read from /dev/ttyLP1 serial port.
I could open and write to the serial, but I get “resource temporarily unavailable” on reading.
I’ve already tested (echo) the device with the command “microcom -X /dev/ttyLP1 -s 9600” and works fine with a short circuit on the TX and RX pins.

My code:

#include <iostream>
#include <fcntl.h>   /* File Control Definitions           */
#include <termios.h> /* POSIX Terminal Control Definitions */
#include <unistd.h>  /* UNIX Standard Definitions 	   */
#include <errno.h>   /* ERROR Number Definitions           */
#include <string.h>


int main(int argc, char** argv)
{
	int fd;
	char data,buf[100];


	/*------------------------------- Opening the Serial Port -------------------------------*/
	fd = open("/dev/ttyLP1",O_RDWR | O_NOCTTY | O_NDELAY);	/* ttyUSB0 is the FT232 based USB2SERIAL Converter   */
							/* O_RDWR Read/Write access to serial port           */
							/* O_NOCTTY - No terminal will control the process   */
							/* O_NDELAY -Non Blocking Mode,Does not care about-  */
							/* -the status of DCD line,Open() returns immediatly */

	if(fd == -1){
		printf("\n  Error! in Opening ttyUSB0  ");
		return -1;
	}

	/*---------- Setting the Attributes of the serial port using termios structure --------- */

	struct termios SerialPortSettings;	/* Create the structure                          */

	tcgetattr(fd, &SerialPortSettings);	/* Get the current attributes of the Serial port */

	cfsetispeed(&SerialPortSettings,B9600); /* Set Read  Speed as 9600                       */
	cfsetospeed(&SerialPortSettings,B9600); /* Set Write Speed as 9600                       */

	SerialPortSettings.c_cflag &= ~PARENB;   /* Disables the Parity Enable bit(PARENB),So No Parity   */
	SerialPortSettings.c_cflag &= ~CSTOPB;   /* CSTOPB = 2 Stop bits,here it is cleared so 1 Stop bit */
	SerialPortSettings.c_cflag &= ~CSIZE;	 /* Clears the mask for setting the data size             */
	SerialPortSettings.c_cflag |=  CS8;      /* Set the data bits = 8                                 */

	SerialPortSettings.c_cflag &= ~CRTSCTS;       /* No Hardware flow Control                         */
	SerialPortSettings.c_cflag |= CREAD | CLOCAL; /* Enable receiver,Ignore Modem Control lines       */

	SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY);          /* Disable XON/XOFF flow control both i/p and o/p */
	SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);  /* Non Cannonical mode                            */

	SerialPortSettings.c_oflag &= ~OPOST; /*No Output Processing*/

	if((tcsetattr(fd,TCSANOW,&SerialPortSettings)) != 0){ /* Set the attributes to the termios structure*/
		printf("\n  ERROR ! in Setting attributes");
		return -1;
	}else{
		printf("\n  BaudRate = 9600 \n  StopBits = 1 \n  Parity   = none\n");
	}

	tcflush(fd, TCIFLUSH);   /* Discards old data in the rx buffer            */

	// Write buf example
	buf[0] = 0xAA;
	buf[1] = 0xBB;

	// Write only 2 bytes
	int ret = write(fd,(char *)buf,2);
	if(ret == -1){
		printf("errno: %s\n",strerror(errno));
		return -1;
	}else{
		printf("wrote %d bytes\n",ret);
	}

	memset((void *)buf,'0',sizeof(buf));

	sleep(1);

	if (read(fd,buf,sizeof(buf)) == -1){
		printf("errno: %s\n",strerror(errno));
		return -1;
	}

	for(int i=0;i<2;i++)
		printf("0x%X ",buf[i]);

	return 0;
}

The output:

  BaudRate = 9600 
  StopBits = 1 
  Parity   = none

wrote 2 bytes
errno: Resource temporarily unavailable

Am I missing any configuration? I have already looked at
http://developer.toradex.com/knowledge-base/uart-(linux)#Configuration

Best regards,

Resource temporarily unavailable typically correspondence to -EAGAIN which is a common return value when reading on a non-blocking file descriptor. You can use O_NONBLOCK in the open call to let read wait until characters are available.

That said, with your loop back setup and the sleep you should actually read characters. Are you short circuit UART_C (SODIMM 19/21)? Also I think with cfsetispeed/cfsetospeed you are using the new serial speed handling which I think needs TCSETS2. Please check also our examples:

http://developer.toradex.com/knowledge-base/uart-(linux)#Colibri_VFxx

I found the issue. I was missing the flag “ECHONL” on the line:

SerialPortSettings.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG)

I dont know why the same code was working on my Ubuntu using a FTDI serial-usb.

Best regards

I had the similar problem, after adding .c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG)
it works.

but I am looking someway to use UART as Interrupt or SIGNALs so that I can receive byte by byte and can take decision.
Any help will be appreciated.

@neeraj.verma, Could you ask a new question, please? Thanks.

Hi Jaski.tx,
posted question in new thread. Thank you.
https://www.toradex.com/community/questions/40225/want-to-receive-byte-by-byte-data-over-uart.html

You are welcome.