C 如何使用termios.h配置串行端口以传递原始字节?
我需要通过USB虚拟串行设备与硬件进行通信。我所需要的只是在正确的UART设置下快速地来回传递原始字节,我永远不想使用终端。使用termios的概念验证软件没有配置正确的位,除非在运行之前在stty上输入一个神奇的配置字符串,否则无法工作 我试图复制出现在termios.h的POSIX手册页中的stty的每个设置,但它仍然不起作用,现在有一个满是样板标记设置代码的屏幕 使用termios.h获得无终端串行端口的最低配置应该是什么?如果有专门针对Linux的任何补充,我需要知道这些C 如何使用termios.h配置串行端口以传递原始字节?,c,linux,unix,serial-port,C,Linux,Unix,Serial Port,我需要通过USB虚拟串行设备与硬件进行通信。我所需要的只是在正确的UART设置下快速地来回传递原始字节,我永远不想使用终端。使用termios的概念验证软件没有配置正确的位,除非在运行之前在stty上输入一个神奇的配置字符串,否则无法工作 我试图复制出现在termios.h的POSIX手册页中的stty的每个设置,但它仍然不起作用,现在有一个满是样板标记设置代码的屏幕 使用termios.h获得无终端串行端口的最低配置应该是什么?如果有专门针对Linux的任何补充,我需要知道这些 #includ
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <termios.h>
int serial_open(char *port, int baud)
{
int fd;
struct termios tty;
if((fd = open(port, O_RDWR | O_NOCTTY | O_SYNC)) < 0)
{
return -1;
}
if(tcgetattr(fd, &tty) < 0)
{
return -1;
}
cfsetospeed(&tty, (speed_t)baud);
cfsetispeed(&tty, (speed_t)baud);
tty.c_cflag |= (CLOCAL | CREAD);
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_cflag &= ~PARENB;
tty.c_cflag |= CSTOPB;
tty.c_cflag &= ~CRTSCTS;
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
tty.c_oflag &= ~OPOST;
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 1;
if(tcsetattr(fd, TCSANOW, &tty))
{
return -1;
}
return fd;
}
/* example usage */
int fd = serial_open("/dev/ttyUSB0", B9600);
#包括
#包括
#包括
#包括
#包括
#包括
int串行_打开(字符*端口,int波特)
{
int-fd;
结构termios tty;
如果((fd=打开(端口,O|RDWR | O|NOCTTY | O|U SYNC))<0)
{
返回-1;
}
如果(tcgetattr(fd和tty)<0)
{
返回-1;
}
cfsetospeed(&tty,(速度)波特);
cfsetispeed(速度和波特率);
tty.c|u cflag |=(CLOCAL | CREAD);
tty.c_cflag&=~CSIZE;
tty.c|u cflag |=CS8;
tty.c_cflag&=~PARENB;
tty.c|u cflag |=CSTOPB;
tty.c_cflag&=~CRTSCTS;
tty.c|u iflag&=~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
tty.c|lflag&=~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
tty.c_of lag&=~OPOST;
tty.c_cc[VMIN]=1;
tty.c_cc[VTIME]=1;
中频(tcsetattr(fd、TCSANOW和tty))
{
返回-1;
}
返回fd;
}
/*示例用法*/
int fd=串行开放(“/dev/ttyUSB0”,B9600);
在Linux上,至少函数
cfmakeraw()
将在struct termios
串行设置blob中为原始IO设置标志。在这种情况下,已删除错误检查的工作流如下所示:
int fd = open(portname, O_RDWR | O_NOCTTY);
struct termios portSettings;
tcgetattr(fd, &portSettings);
cfsetispeed(&portSettings, B115200);
cfsetospeed(&portSettings, B115200);
cfmakeraw(&portSettings);
tcsetattr(fd, TCSANOW, &portSettings);
我的代码仍然不起作用,所以很明显有一些主要的东西我不明白。即使程序处于活动状态,stty也不会报告相同的设置(例如,它显示0波特和CS6,这可能不正确)。我不知道不同的进程是否会看到不同的设置,或者我的二进制文件在根目录下运行时是否无法设置端口。在我分解了一些变量之后,我会回到这个问题上。谢谢你。我会尽量保持问题和答案的概括性。我最终不得不使用
cfmakeraw()
,然后它就成功了。