摘要:,我正在写一个ttyUSB窥探者。该代码应该从串行端口读取(2)数据,并将(2)数据写入另一个串行端口。对/bin/cat来说,从串口读取很好,但是我的代码失败了。
硬件设置是:I制作了一个FTDI交叉电缆,并将一端放在Windows机器中作为Com2,另一端放在现代Linux机器中作为/dev/ttyUSB0 0。Linux机器有一个USB到串行电缆,显示为/dev/ttyUSB1 1。它是连接到实际的硬件单元,我正在试图窥探。我证实了,硬件工作得很好。
这一部分起作用:I将"cat /dev/ttyUSB0 0> /tmp/ data“,然后让WinXP机器发出”从Com2上的设备读取“,然后发送以下6个字节的数据。
\x02\x01\x40\x00\x0a\x9e这个“数据包”发送4次左右,延迟很小,这似乎是WinXP代码尝试了几次。如果我只重放一次,就成功了。
如果我只执行"cat /tmp/data >/dev/ttyUSB1 1“,硬件设备将正确地响应,这意味着它收到了命令。太棒了!
问题和我的代码:正在编写一些代码在Linux机器上运行,这些代码将从/dev/ttyUSB1 0读取(2)并将其写入/dev/ttyUSB1 1,反之亦然。但是,由于一些未知的原因,它只会在第一个“数据包”中接收4个字节,然后在随后的3次尝试中只接收5个字节。有时,这5个字节出现轻微的“损坏”,这意味着我看到\xffffff的最后一个或第二个字节。这是我的代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <strings.h>
void hexdump(char *data, int size) {
for (size_t i = 0; i < size; ++i)
printf("%02x ", data[i]);
putchar('\n');
}
int main() {
int fdzero;
int fdone;
int maxfd;
fd_set sockrd;
struct timeval timer;
char data[10];
int size;
char tmp;
fdzero = open("/dev/ttyUSB0", O_RDWR);
if (fdzero == -1) {
perror("Failed to open /dev/ttyUSB0");
return 1;
}
fdone = open("/dev/ttyUSB1", O_RDWR);
if (fdone == -1) {
perror("Failed to open /dev/ttyUSB1");
return 1;
}
if (fdzero > fdone)
maxfd = fdzero;
else
maxfd = fdone;
printf("Enter loop\n");
for(;;) {
bzero(data, 10);
// fflush(NULL);
FD_ZERO(&sockrd);
FD_SET(fdzero, &sockrd);
FD_SET(fdone, &sockrd);
timer.tv_sec = 60;
timer.tv_usec = 0;
select(maxfd+1, &sockrd, NULL, NULL, &timer);
if (FD_ISSET(fdzero, &sockrd)) {
size = read(fdzero, data, 10);
if (size == -1) {
perror("Failed to read /dev/ttyUSB0");
break;
}
size = write(fdone, data, size);
if (size == -1) {
perror("Failed to write to /dev/ttyUSB1");
break;
}
printf("ttyUSB0 -> ttyUSB1: %d\n", size);
}
// This portion does not trigger yet, but its a mirror
// Yes, I know...bad code :(
else {
size = read(fdone, data, 10);
if (size == -1) {
perror("Failed to read /dev/ttyUSB1");
break;
}
size = write(fdzero, data, size);
if (size == -1) {
perror("Failed to write to /dev/ttyUSB0");
break;
}
printf("ttyUSB1 -> ttyUSB0: %d\n", size);
}
// Used to monitor what is read()/write()
hexdump(data, size);
}
return 0;
}当我实际运行这段代码时,我会看到以下内容:
# cc snoop.c -o snoop
# ./snoop
Enter loop
ttyUSB0 -> ttyUSB1: 4
02 00 40 ffffff9e
ttyUSB0 -> ttyUSB1: 4
02 00 40 ffffff9e
ttyUSB0 -> ttyUSB1: 4
02 00 40 ffffff9e
ttyUSB0 -> ttyUSB1: 5
01 02 00 40 ffffff9e
ttyUSB0 -> ttyUSB1: 5
01 02 00 40 ffffff9e
ttyUSB0 -> ttyUSB1: 5
01 02 00 40 ffffff9e请注意,在任何给定的时间,只接收到4或5个字节并随后发送。另外,请注意“数据包”是扭曲的。世界上会发生什么呢?
合理性--如果您感兴趣的话:--我有只运行在Windows上的老软件,在VM中不能工作(这是一个已知的问题)。我很想捕捉通过串口的流量。我买了一台WinXP机器就是为了做这个。
发布于 2016-10-01 22:36:59
好吧,你的两个问题:
有时,这5个字节出现轻微的“损坏”,这意味着我看到\xffffff的最后一个或第二个字节。
这是因为printf如何解释输入的数据(这可能会感兴趣)。它以char的形式传入,并进行签名。在这种情况下,高阶位正在被解释。要修复这个部分,您的hexdump(char* data, int len)应该是hexdump(unsigned char* data, int len)或者使用字节大小的类型,比如uint8_t,这样您的签名看起来就像hexdump(uint8_t* data, int len)。
但是,由于一些未知的原因,它只会在第一个“数据包”中接收4个字节,然后在随后的3次尝试中只接收5个字节。
这几乎肯定是因为您没有在串口上设置任何设置。您拥有的一个字符是0x0A,它是linefeed字符。这要么被串口驱动程序忽略,要么一起转换成不同的字符。若要解决此问题,必须将串行端口设置设置为raw,而不是翻译进来的任何字符。我通常做的事情如下:
struct termios newio;
if( tcgetattr( fd, &newio ) < 0 ){ /* error handling here */ }
/* Set some default settings */
newio.c_iflag |= IGNBRK;
newio.c_iflag &= ~BRKINT;
newio.c_iflag &= ~ICRNL;
newio.c_oflag = 0;
newio.c_lflag = 0;
newio.c_cc[VTIME] = 0;
newio.c_cc[VMIN] = 1;
/* Set our baud rate */
cfsetospeed( &newio, B9600 );
cfsetispeed( &newio, B9600 );
/* Character size = 8 */
newio.c_cflag &= ~CSIZE;
newio.c_cflag |= CS8;
/* One stop bit */
newio.c_cflag &= ~CSTOPB;
/* Parity = none */
newio.c_iflag &= ~IGNPAR;
newio.c_cflag &= ~( PARODD | PARENB );
newio.c_iflag |= IGNPAR;
/* No flow control */
newio.c_iflag &= ~( IXON | IXOFF | IXANY );
/* Set our serial port settings */
if( tcsetattr( fd, TCSANOW, &newio ) < 0 ) { /* error handling code here */ }如果您不想以这种方式设置串口设置,我已经编写了一个小型图书馆,它应该为您抽象出一些小细节。
https://stackoverflow.com/questions/39809504
复制相似问题