如何使用 .NET Core 在 Linux 上以非规范模式打开 tty 设备
How to open a tty device in noncanonical mode on Linux using .NET Core
我在嵌入式 Linux 平台上使用 .NET Core 到目前为止取得了很好的成功。不过,我 运行 遇到了尝试以原始(非规范模式)打开 tty 设备的问题。如果我使用的是常规 C 或 C++,我会在打开设备后调用 cfmakeraw()
,但我如何从 .NET Core 应用程序执行此操作?
我需要使用的设备是用于 USB 客户端连接器的 CDC ACM 功能驱动程序,即它是一个虚拟 COM 端口。它在我的系统中显示为 /dev/ttyGS0
。我可以打开设备,然后使用以下代码读取和写入:
FileStream vcom = new FileStream("/dev/ttyGS0", FileMode.Open);
因为 tty 设备默认以规范模式打开,所以我不会收到任何字符,直到用户在文本行末尾发送回车 return 字符。我需要在发送每个字符时接收它,而不是等到发送 return 回车,即我需要为 tty 设备使用原始模式。
下面的代码不起作用,因为.NET Core没有意识到这个设备是一个虚拟串口,所以当我尝试用这种方式打开它时抛出异常。当我使用 SerialPort
打开真正的 UART 设备时,它们会按预期在原始模式下运行。
SerialPort serialPort = new SerialPort("/dev/ttyGS0);
既然你有一个终端设备,你可以在实际使用它之前尝试改变它的 termios 配置。
尝试在 运行 程序之前发出 shell 命令 stty -F /dev/ttyGS0 raw
。
raw
设置将为非规范模式进行以下 termios 更改(根据 stty 手册页):
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixany -ixoff -imaxbel
-opost
-icanon -isig -xcase -iuclc
min 1 time 0
请注意,c_cflag 属性(例如波特率、奇偶校验、字符大小)和回显属性(如您所知)都不会被 raw
设置。
为了比较,您提到的 libc cfmakeraw() 例程进行了以下 termios 设置:
t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
t->c_oflag &= ~OPOST;
t->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
t->c_cflag &= ~(CSIZE|PARENB);
t->c_cflag |= CS8;
t->c_cc[VMIN] = 1; /* read returns when one char is available. */
t->c_cc[VTIME] = 0;
您可以使用 stty -F /dev/ttyGS0 sane
将终端恢复为默认的 termios 配置。
我在嵌入式 Linux 平台上使用 .NET Core 到目前为止取得了很好的成功。不过,我 运行 遇到了尝试以原始(非规范模式)打开 tty 设备的问题。如果我使用的是常规 C 或 C++,我会在打开设备后调用 cfmakeraw()
,但我如何从 .NET Core 应用程序执行此操作?
我需要使用的设备是用于 USB 客户端连接器的 CDC ACM 功能驱动程序,即它是一个虚拟 COM 端口。它在我的系统中显示为 /dev/ttyGS0
。我可以打开设备,然后使用以下代码读取和写入:
FileStream vcom = new FileStream("/dev/ttyGS0", FileMode.Open);
因为 tty 设备默认以规范模式打开,所以我不会收到任何字符,直到用户在文本行末尾发送回车 return 字符。我需要在发送每个字符时接收它,而不是等到发送 return 回车,即我需要为 tty 设备使用原始模式。
下面的代码不起作用,因为.NET Core没有意识到这个设备是一个虚拟串口,所以当我尝试用这种方式打开它时抛出异常。当我使用 SerialPort
打开真正的 UART 设备时,它们会按预期在原始模式下运行。
SerialPort serialPort = new SerialPort("/dev/ttyGS0);
既然你有一个终端设备,你可以在实际使用它之前尝试改变它的 termios 配置。
尝试在 运行 程序之前发出 shell 命令 stty -F /dev/ttyGS0 raw
。
raw
设置将为非规范模式进行以下 termios 更改(根据 stty 手册页):
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixany -ixoff -imaxbel
-opost
-icanon -isig -xcase -iuclc
min 1 time 0
请注意,c_cflag 属性(例如波特率、奇偶校验、字符大小)和回显属性(如您所知)都不会被 raw
设置。
为了比较,您提到的 libc cfmakeraw() 例程进行了以下 termios 设置:
t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
t->c_oflag &= ~OPOST;
t->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
t->c_cflag &= ~(CSIZE|PARENB);
t->c_cflag |= CS8;
t->c_cc[VMIN] = 1; /* read returns when one char is available. */
t->c_cc[VTIME] = 0;
您可以使用 stty -F /dev/ttyGS0 sane
将终端恢复为默认的 termios 配置。