&"warning: GDB: Failed to set controlling terminal: Inappropriate
ioctl for device\n"
bool rs485::rs485ConfigPort()
{
termios portSettings;
memset(&portSettings, 0, sizeof(portSettings));
portSettings.c_cflag |= (CLOCAL | CREAD);
cfsetispeed(&portSettings, B57600);
portSettings.c_cflag &= ~PARENB;
portSettings.c_cflag |= CS8;
portSettings.c_cflag &= ~CSIZE;
portSettings.c_cflag &= ~CSTOPB; //stop bit = 1
//cfmakeraw(&portSettings);
if (tcsetattr(fd, TCSANOW, &portSettings))
{
emit logMessage("Can not adjust port settings");
close(fd);
return false;
}
tcflush(fd, TCIFLUSH);
return true;
}
I found the problem, this is because tcsetattr() gives back Input/Output Error.
the device is open with write permissions. and... when I do dmesg | grep ttyS0 or S1-3, I do not receive anything! it also follows sometimes with the error "No such device".
anybody can help solve this problem?
Related
I have an application that interfaces with serial ports. Sometimes when I close a serial port using close(int fd), the call to close() takes 30 seconds or so.
Is there a way I can configure the system to forgo this delay when closing the file descriptor?
I open my port by fd = open(addr, O_RDWR );
Most of the code configuing the port is shown below:
rc = tcgetattr(fd, &opts);
if(rc)
{
printf("TC get attr failed %d \n", errno);
return rc;
}
// Configure parity
opts.c_cflag &= ~PARENB;
if(com_port->parity_)
{
opts.c_cflag |= PARENB;
if(com_port->parity_ >1)
{
opts.c_cflag = PARODD;
}
}
// Configure stop bits
opts.c_cflag &= ~CSTOPB; // Clear stop bit for default setting
switch(com_port->stop_bit_)
{
case 1:
//default is 1 stop bit for POSIX
break;
case 2:
opts.c_cflag |= CSTOPB;
break;
default:
//Use the default setting for POSIX
printf("Warning using default stop bit\n");
break;
}
// Configure bytes size
opts.c_cflag &= ~CSIZE; // Clear byte size bit
opts.c_cflag |= (CS8); // Set byte size bit
// Configure flow control
opts.c_cflag &= ~CRTSCTS; // flow control disabled
opts.c_cflag |= CREAD | CLOCAL; // allow read and ignore ctrl lines
// Disable canonical mode
opts.c_lflag &= ~ICANON;
// Disable echoing
opts.c_lflag &= ~ECHO;
opts.c_lflag &= ~ECHOE;
opts.c_lflag &= ~ECHONL;
// Disable signal chars
opts.c_lflag &= ~ISIG;
// Disable flow control
opts.c_iflag &= ~(IXON | IXOFF | IXANY);
// Disable special handling
opts.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL);
// Configure output modes
opts.c_oflag &= ~OPOST;
opts.c_oflag &= ~ONLCR;
// Default timeouts
opts.c_cc[VTIME] = 10;
opts.c_cc[VMIN] = 0;
I close the file with this code:
int CloseSerialPort(SerComPort* com_port)
{
if(com_port->port_handle_ > 0)
{
tcflush(com_port->port_handle_ TCIOFLUSH);
}
return close(com_port->port_handle_);
}
I have faced the following problem: I wish to read data comming to my serial port on linux. Data are send from an external device with standard serial settings. I'm sure that the external device sends them, that has been already checked.
However, on linux all i can read is an empty byte. What am I setting wrong?
My settings looks like that:
serial = open(_name, O_RDWR | O_NOCTTY | O_NDELAY);
fcntl(serial, F_SETFL,0);
tcgetattr(_serial, &_options);
options.c_ispeed = _baudRate;
options.c_ospeed = _baudRate;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag &= ~PARENB;
options.c_iflag &= ~(INPCK|PARMRK|ISTRIP);
options.c_cflag &= ~CSTOPB;
options.c_cflag |= CREAD |CLOCAL ;
tcflush(serial, TCIFLUSH);
tcsetattr(serial, TCSANOW, &options);
my read function looks like that:
char byte = 'a';
int datasize = 0;
while (byte != '\n') {
datasize = read(serial, &byte, sizeof(byte));
std::cout<< "Read:"<< byte <<".\t"; // this line always prints: "Read: ."
}
I'm not sure what has happened but the following settings finally worked. I will share it with you as I got a lot of help here on Stackoverflow:
serial = open(name.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
fcntl(serial, F_SETFL,0);
tcgetattr(serial, &options);
options.c_ispeed = _baudRate;
options.c_ospeed = _baudRate;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag &= ~PARENB;
options.c_iflag &= ~(INPCK|PARMRK|ISTRIP);
options.c_cflag &= ~CSTOPB;
options.c_cflag |= CREAD |CLOCAL ;
options.c_cc[VMIN]=0;
options.c_cc[VTIME]=10;
options.c_cflag &= ~CRTSCTS; // turn off hardware flow control
options.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off sowftware flow control
options.c_lflag &= ~ICANON;
options.c_lflag &= ~ISIG;
options.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL); // Disable any special handling of received bytes
options.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
options.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
tcflush(serial, TCIFLUSH);
tcsetattr(serial, TCSANOW, &options);
I try set in c++ some serial port, but when I try function tcsetatrr, its return error -1. Port opens without problems.
char port_name[] = "/dev/ttyS1";
int port = open(port_name, O_RDWR | O_NOCTTY | O_NDELAY);
if(port < 0){
std::cout << "Cant open port" << std::endl;
return;
}
struct termios settings;
tcgetattr(port, &settings);
cfgetispeed(&settings);
//std::cout << settings.c_cflag;
//Baudrate
cfsetispeed(&settings, B115200);
cfsetospeed(&settings, B115200);
//Data bits
settings.c_cflag &= ~CSIZE;
settings.c_cflag |= CS8;
//Parity
settings.c_cflag |= ~PARENB;
//Stop bit
settings.c_cflag &= ~CSTOPB;
//Flow control
settings.c_cflag |= ~CRTSCTS;
settings.c_iflag &= ~(IXON | IXOFF | IXANY);
int er = tcsetattr(port, TCSANOW, &settings);
if (er<0) {
fprintf(stderr, "Error openinig: %s\n", strerror(errno));
}
close(port);
output:
Input/output error
How can I fix that? I was running code as root. The problem is not in the configuration of the settings structure because after commenting it out, I get the same error
The most likely answer is that you don't really have a serial device /dev/ttyS1. Try /dev/ttyS0 instead. I have the same deal on my PC.
I see a few additional problems here.
You don't check if tcgetattr() succeeds, so don't be so sure you even get to tcsetattr().
Calling settings.c_cflag |= ~PARENB; or settings.c_cflag |= ~CRTSCTS; is most likely not what you want to do (will raise all flags except the selected one).
I am having trouble selecting correct settings for the serial port to be opened.
Information I have is the following:
Synchronization: Asynchronous method
Communication method: Full duplex transmission
Communication speed: 9600 bps (bits per second)
Transmission code: 8-bit data
Data configuration: Start bit 1, data 8-bit + parity 1, stop bit 1
Error control: Horizontal (CRC) and vertical (even number) parities
1 byte configuration
PC should not use a control signal (DTR, DSR, RTS and CTS) at the time of this connection.
What I have is something like:
bool configurePort(void) {
struct termios port_settings;
bzero(&port_settings, sizeof(port_settings));
tcgetattr(fd, &port_settings);
cfsetispeed(&port_settings, B9600);
cfsetospeed(&port_settings, B9600);
port_settings.c_cflag &= ~CSIZE;
port_settings.c_cflag |= CS8;
// parity bit
//port_settings.c_cflag &= ~PARENB;
//port_settings.c_cflag &= ~PARODD;
// hardware flow
port_settings.c_cflag &= ~CRTSCTS;
// stop bit
//port_settings.c_cflag &= ~CSTOPB;
port_settings.c_iflag = IGNBRK;
port_settings.c_iflag &= ~(IXON | IXOFF | IXANY);
port_settings.c_lflag = 0;
port_settings.c_oflag = 0;
port_settings.c_cc[VMIN] = 1;
port_settings.c_cc[VTIME] = 0;
port_settings.c_cc[VEOF] = 4;
tcsetattr(fd, TCSANOW, &port_settings);
return true;
}
Tried various modifications but nothing seems to work.
The device is connected over USB-serial (ttyUSB0) and I have permissions.
It opens device, sends (?) data but never gets anything back...
Can someone point me what should be done?
Try with this:
bool configurePort(void) {
struct termios port_settings;
bzero(&port_settings, sizeof(port_settings));
if(tcgetattr(fd, &port_settings) < 0) {
perror("tcgetattr");
return false;
}
cfmakeraw(&port_settings);
cfsetispeed(&port_settings, B9600);
cfsetospeed(&port_settings, B9600);
//input
port_settings.c_iflag &= ~(IXON | IXOFF | IXANY); //disable flow control
//local
port_settings.c_lflag = 0; // No local flags
//output
port_settings.c_oflag |= ONLRET;
port_settings.c_oflag |= ONOCR;
port_settings.c_oflag &= ~OPOST;
port_settings.c_cflag &= ~CRTSCTS; // Disable RTS/CTS
port_settings.c_cflag |= CREAD; // Enable receiver
port_settings.c_cflag &= ~CSTOPB;
tcflush(fd, TCIFLUSH);
if(tcsetattr(fd, TCSANOW, &port_settings) < 0) {
perror("tcsetattr");
return false;
}
int iflags = TIOCM_DTR;
ioctl(fd, TIOCMBIC, &iflags); // turn off DTR
return true;
} //configure port
I am going to use serial port in my C++ program linux ubuntu 10.4 ,this is my open port function :
int Recorder::OpenPort()
{
int intFd ;
struct termios options;
intFd=open("/dev/ttyS0", O_RDWR | O_NOCTTY| O_NDELAY);
if (intFd==-1){
perror("open_port: Unable to open /dev/ttyS0 - ");
}
fcntl(intFd, F_SETFL, FNDELAY); /*configuration the port*/
tcgetattr(intFd, &options);
//set baud rates at 115200
cfsetispeed(&options, B115200 );
cfsetospeed(&options, B115200);
//mask the character size to 8 bit data & no parity.CHARACTER SIZE SETTING
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
//setting hardware flow control
options.c_cflag |= CRTSCTS;
//Enable the receiver and set local mode .should always be enabled (enable receiver and dont change owner of port)
options.c_cflag |= (CLOCAL | CREAD);
//flush output buffer
options.c_lflag |= FLUSHO;
//choosing raw data disable echoing
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
//not setting software flow control
options.c_iflag &= ~(IXON | IXOFF | IXANY);
options.c_oflag &= ~OPOST;
// //output changes :for mapping NL to CR-NL.
// options.c_oflag |= (OPOST | ONLCR );
//
// options.c_oflag |= (NL1 | CR1 | FFDLY);
tcsetattr(intFd, TCSANOW, &options);
return intFd;
}
and this is the sample where I check my serial number:
int serial=0;
ioctl(intFd, TIOCMGET, &serial);
//for ubuntu 7.04 and 10.04
if(serial==16390 || serial==16422 || serial==16454 || serial==16486){//no connection with serial port
i checked my program many times and serial is 16486 every times and it means I have no connection with serial port , I checked my serial cable and it was ok? so how can I Solve my problem?