LInux tty 非阻塞配置以及安全读取数据方法
-
串口配置
char read_data[10], *write_char = "abcd01234\0";
int fd_a, fd_b, read_len = 0, strcmp_result = -1;
bzero(read_data, 10);
// O_NOCTTY 就是非阻塞配置
fd_a = open(com_name_a, O_RDWR | O_NOCTTY);
if (fd_a < 0) {
goto ERR0;
}
fd_b = open(com_name_b, O_RDWR | O_NOCTTY);
if (fd_b < 0) {
goto ERR1;
}
config_uart(fd_a, 115200);
config_uart(fd_b, 115200);
static bool config_uart(int uart_fd, int speed) {
static struct termios termold, termnew;
if(tcgetattr(uart_fd, &termold) != 0)
{
return false;
}
bzero(&termnew, sizeof(termnew));
termnew.c_iflag &= ~(ICRNL | IGNCR) ;
termnew.c_cflag |= CLOCAL | CREAD; //CLOCAL:忽略modem控制线 CREAD:打开接受者
termnew.c_cflag &= ~CSIZE;
termnew.c_cflag |= CS8;
termnew.c_cflag &= ~PARENB;
switch(speed)
{
case 2400:
cfsetispeed(&termnew, B2400);
cfsetospeed(&termnew, B2400);
break;
case 4800:
cfsetispeed(&termnew, B4800);
cfsetospeed(&termnew, B4800);
break;
case 9600:
cfsetispeed(&termnew, B9600);
cfsetospeed(&termnew, B9600);
break;
case 115200:
cfsetispeed(&termnew, B115200);
cfsetospeed(&termnew, B115200);
break;
case 460800:
cfsetispeed(&termnew, B460800);
cfsetospeed(&termnew, B460800);
break;
default:
cfsetispeed(&termnew, B115200);
cfsetospeed(&termnew, B115200);
break;
}
termnew.c_cflag &= ~CSTOPB;
termnew.c_cc[VTIME] = 1; //VTIME:非cannoical模式读时的延时,以十分之一秒位单位
// 这里是没有读取数据 0.1 S 就退出读取
termnew.c_cc[VMIN] = 0; //VMIN:非canonical模式读到最小字符数
// 这个参数配置为 0 就是非阻塞
tcflush(uart_fd, TCIFLUSH);
// 改变在所有写入 fd 引用的对象的输出都被传输后生效,所有已接受但未读入的输入都在改变发生前丢弃。
if((tcsetattr(uart_fd, TCSANOW,&termnew)) != 0) //TCSANOW:改变立即发生
{
return false;
}
return true;
}
static int safety_read(int fd, char *read_data, unsigned int data_len) {
unsigned int len = 0;
//char byte_data;
// 安全读取就是一个个读取,然后合成在一起。
while(data_len) {
//bzero(&byte_data, 1);
len += read(fd, read_data + len, 1);
data_len--;
}
LOGI("%s", read_data);
LOGI("%d", len);
return len;
}
Read The Fucking Source Code