C 字节不会发送到串行驱动程序缓冲区
我有这个计划:C 字节不会发送到串行驱动程序缓冲区,c,posix,C,Posix,我有这个计划: // C headers #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <stdint.h> // POSIX headers #include <unistd.h> #include <sys/ioctl.h> // Other headers #include &
// C headers
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdint.h>
// POSIX headers
#include <unistd.h>
#include <sys/ioctl.h>
// Other headers
#include "ZL_sleep.h"
#include "ZL_utf8.h"
#include "ZL_serial.h"
#define BS 4 // Buffer size
int main(int argc, char * argv[]){
int32_t p; // Port
int32_t r; // Read finished
uint8_t b[BS]; // Buffer
uint32_t n; // Number of bytes to be read from driver buffer
if(argc != 2){
printf("ERROR: Supply a \"serial port\" device file.");
exit(EXIT_FAILURE);
}
p = ZL_open_tty(argv[1]);
if(p < 0){
perror("ERROR: open()");
exit(EXIT_FAILURE);
}
while(1){
memset(b, '\0', BS);
r = read(p, b, BS);
if(r < 0){
if(errno == EAGAIN){
}
else{
perror("ERROR: read()");
close(p);
exit(EXIT_FAILURE);
}
}
ZL_utf8_print_bytes(b, BS);
putchar('\n');
}
close(p);
return EXIT_SUCCESS;
}
之后,我的程序进入一个无休止的while循环,read()
阻塞,直到我在键盘焦点位于/dev/pts/1
时输入任何键
我面临的问题是,有时我在/dev/pts/1
中按下一个键,使用该键注册的字节不会传输到驱动程序缓冲区?!字节只保留在/dev/pts/1
中。这发生在ASCII(1字节)字符和UTF8(多字节)字节中
我知道read()
尝试从驱动程序缓冲区读取请求的字节量(BS
)。但是,如果驱动程序缓冲区中没有可用的BS
字节,那么它读取的字节就会更少。所以如果某些字节稍后到达,它可以稍后读取它们。但由于某些原因,这些字节永远不会到达驱动程序缓冲区
是什么原因导致字节未到达驱动程序缓冲区并永久保留在/dev/pts/1
中
当虚拟终端连接到系统(通常是
ssh
)时,会创建pts
。pts
被连接为stdin
/stdout
,用于启动连接的外壳,因此您已经有一个进程连接到pts
并从中读取
一旦附加了应用程序,就可以在两个进程(应用程序和shell)之间有效地开始竞争,因此速度更快的人将收到缓冲区的内容。字符没有保留在pts
的缓冲区中,而是由连接到pts
的外壳读取
为了能够在不中断连接进程的情况下读取数据,您需要通过通知主多路复用器ptmx来拦截pts的缓冲区,请参阅中的详细信息。您可以研究如何在模式下完成,您不也需要禁用规范模式吗?我添加了
fo.c|lflag&=~(ICANON | ECHO | ECHO | ISIG)在ZL_open_tty()
中使用code>禁用规范模式,结果相同。即使我尝试只请求读取1
字节,如sor=read(p,b,1)代码>有些字节没有传输到串行驱动程序缓冲区,因此无法读取。非常感谢先生!
uint32_t ZL_open_tty(const char * terminal){
uint32_t fd; // File's descriptor
uint32_t fl; // File's flags
struct termios fo; // File's options
fd = open(terminal, O_RDWR | O_NOCTTY | O_NONBLOCK);
if(fd < 0){
return -1;
}
fl = fcntl(fd, F_GETFL, 0);
if(fl < 0){
perror("ERROR: fcntl():");
return -1;
}
fcntl(fd, F_SETFL, fl & ~(O_NONBLOCK | O_APPEND | O_DSYNC | O_RSYNC | O_SYNC));
tcgetattr(fd, &fo);
fo.c_cc[VMIN] = 1;
fo.c_cc[VTIME] = 0;
tcsetattr(fd, TCSANOW, &fo);
fputs("─────────────────────────────────────────────────── terminal settings\n", stdout);
printf("VMIN = %d\n", fo.c_cc[VMIN]);
printf("VTIME = %d\n", fo.c_cc[VTIME]);
putchar('\n');
return(fd);