我在串行日志记录应用程序中使用 termios,该应用程序读取串行端口并将数据保存在文件中。它还接受来自标准输入的输入并将其发送到串行端口。
问题是,一旦应用程序退出(通过按“q”),bash 终端设置就会混乱,并且会输出奇怪的字符(见图)
将属性设置回原来的成功:resultetatr=tcsetattr(STDIN_FILENO,TCSAFLUSH,&oldstdio); 并失败:resultetatr=tcsetattr(STDIN_FILENO,TCSAFLUSH,&oldstdio);
如程序终止前所示。
该程序在带有 USB 到串行适配器的 Raspberrypi 上运行。
相关的代码是:
void setup_termios()
{ memset(&stdio,0,sizeof(stdio));
stdio.c_iflag=0;
stdio.c_oflag=0;
stdio.c_cflag=0;
stdio.c_lflag=0;
stdio.c_cc[VMIN]=1;
stdio.c_cc[VTIME]=0;
int resultsetatr;
resultsetatr=tcgetattr(STDIN_FILENO,&oldstdio); //get old settings
printf("get att stdin = %d\n",resultsetatr);
resultsetatr=tcsetattr(STDIN_FILENO,TCSANOW,&stdio);
printf("set att stdin = %d\n",resultsetatr);
fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK); // make the reads non-blocking
// This is the actual Serial Port termios structure
memset(&tio,0,sizeof(tio));
tio.c_iflag=0;
tio.c_oflag=0;
tio.c_cflag=CS8|CREAD|CLOCAL; // 8n1, see termios.h for more information
tio.c_lflag=0;
tio.c_cc[VMIN]=1;
tio.c_cc[VTIME]=5;
//Opening the serial port
tty_fd=open(DEVICE, O_RDWR | O_NONBLOCK | O_NOCTTY | O_NDELAY);
if (tty_fd < 0) {
perror(DEVICE);
printf("\ryou dont have permission to open serial port, use : sudo ./seriallog\r\n");
close(tty_fd);
tcsetattr(tty_fd,TCSANOW,&oldtio);
tcsetattr(STDIN_FILENO,TCSANOW,&oldstdio);
exit(-1);
}
cfsetospeed(&tio,BAUD); // 9600 baud
cfsetispeed(&tio,BAUD); // 9600 baud
tcgetattr(tty_fd,&oldtio); //get old settings
tcsetattr(tty_fd,TCSANOW,&tio);//set to new settings
}
int main(){
time(&t1);
setup_termios();
create_logfile();
while (rx_char!='q')
{
if (read(tty_fd,&rx_char,1)>0)
{
rx_char = rx_char & 0xff;
//if ( rx_char < 0 || rx_char > 126) rx_char =' ';
time(&t2); //take time 2
dt = difftime(t2,t1);
if (dt>1800) {tx_char ='A';write(tty_fd,&tx_char,1); t1=t2;}
putc(rx_char,stdout);
fputc(rx_char,output_file);
if (rx_char == '\r') write_date_and_time_line(1);
check_for_next_day_file();
}
if (read(STDIN_FILENO,&tx_char,1)>0) write(tty_fd,&tx_char,1);
}
puts("\r\n");
close(tty_fd);
fclose(output_file);
int resultsetatr;
//resultsetatr=tcsetattr(tty_fd,TCSANOW,&oldtio);
//printf("tty : %d\n\r",resultsetatr);
resultsetatr=tcsetattr(STDIN_FILENO,TCSAFLUSH,&oldstdio);
printf("set stdin att : %d\n",resultsetatr);
resultsetatr=tcsetattr(STDIN_FILENO,TCSAFLUSH,&oldstdio);
printf("set stdin att : %d\n",resultsetatr);
return 0;}