【发布时间】:2018-01-10 23:54:42
【问题描述】:
我在 Linux 中成功读取了 fd,但读取的字节数为 0,这意味着已达到 EOF。我应该在每次读取时读取 19 个字节。
该项目是一个电机驱动器,它发送 19 个字节的数据包来驱动 2 个直流电机,它还需要读取来自电机的相同大小的数据包,其中包含更新的位置、命令和状态信息。
我这样打开fd:
mc_fd = InitPort("/dev/ttyS1", "COM2", O_NONBLOCK | O_RDWR | O_SYNC, B115200);
这里是初始化端口的函数:
int InitPort( char *port, char *name, int oflags, speed_t baudRate ) {
int fd; // File descriptor
fd = open(port, oflags); // Open the port like a file
assert(fd > 0); // Open returns -1 on error
struct termios options; // Initialize a termios struct
tcgetattr(fd, &options); // Populate with current attributes
cfsetospeed (&options, baudRate); // Set baud rate out
cfsetispeed (&options, baudRate); // Set baud rate in (same as baud rate out)
options.c_cflag &= ~CSIZE; // Clear bit-length flag so it can be set
//8N1 Serial Mode
options.c_cflag |= CS8; // Set bit-length: 8
options.c_cflag &= ~PARENB; // Set parity: none
options.c_cflag &= ~CSTOPB; // Set stop bit: 1
options.c_cflag &= ~CRTSCTS; // Set flow control: none
options.c_iflag &= ~ICANON; // Enable canonical input
options.c_oflag &= ~OPOST; // Disables all output processing (prevents CR in output)
options.c_cflag |= (CLOCAL | CREAD);// Enable receiver, and set local mode
tcsetattr(fd, TCSANOW, &options); // Set new attributes to hardware
return fd;
}
最初,我只使用了 O_RDWR 标志,并且读取 fd 会因 EAGAIN(或 EWOULDBLOCK)而失败。我一直在尝试同步和非阻塞设置,看看我是否可以接收数据包。至少现在我阅读成功(我认为)。
我能够以 120Hz 的频率写入数据包,并且读取 fd 以相同的速率返回“成功”,尽管读取的是 0 字节。
如何让 read() 读取传入的数据包? 这是读取的代码以及终端的输出:
bytesRead = read( mc_fd, readPacket, MC_PACKET_SIZE );
printf("\npacket: %019X\n", &readPacket);
perror("error type ");
printf("bytes read = %d\n", bytesRead);
packet: 00000000000B63B4140
error type : Success
bytes read = 0
数据包最低有效部分中的 8 位十六进制数字始终与显示的相似,并且不是数据包中的预期值。
这是在嵌入式 linux SBC(单板计算机)上运行的 Debian。我能够毫无问题地读取程序中的其他文件描述符。我对 Linux 还很陌生,可能会遗漏一些明显的东西。谢谢!
【问题讨论】:
-
InitPort是什么? -
errno由read设置很可能被printf破坏。先尝试perror。
标签: c linux serial-port file-descriptor read-write