我编写了一个与串口通信的程序,使用termios,该程序将以非阻塞模式读取串口,并在读取数据后向串口写入响应。如果没有从串口读取数据,程序将执行其他操作,在下一个循环中,程序再次读取串口。
现在的问题是,在有时消失后,可能几分钟,或者几个小时,串口不再响应我的程序。即使我执行echo 'HB\n' > /dev/ttyUSB0
(然后串口应该响应'HACK'),它不再响应了..
我什至不知道串口什么时候“死”,我没有任何线索..它“死”不合时宜。
这是我的配置:
/// set local mode options
//tminfo.c_lflag |= ICANON;
tminfo.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
/// set control mode options
tminfo.c_cflag |= (CLOCAL | CREAD);
tminfo.c_cflag |= HUPCL;
// set hardware flow control
tminfo.c_cflag &= ~CRTSCTS;
// set how many bits in a character
tminfo.c_cflag &= ~CSIZE;
tminfo.c_cflag |= CS8;
// set parity mode (default to odd validation), this option (PARENB) will both enable input and output parity checking
tminfo.c_cflag &= ~PARENB; // we don't need prity checking now
/// set input mode options
// set input parity checking
tminfo.c_iflag &= ~INPCK;
tminfo.c_cflag &= ~CSTOPB;
/// set output mode options
tminfo.c_oflag &= ~OPOST;
tminfo.c_cc[VMIN] = 1;
tminfo.c_cc[VTIME] = 1;
/// set line speed, defaults to 38400bps, both for input and output
// this call will set both input and output speed
cfsetspeed(&tminfo, B38400);
在这种情况下很难调试串行。我真的不知道是什么原因导致地球上的串口“死”。我快疯了...
可能的原因是什么?任何帮助将不胜感激!
更新:
当串口“死”时,其配置为:
speed 38400 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>;
start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 1;
-parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel
-iutf8
-opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon -iexten -echo -echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke
更新 2
/proc/tty/driver/ar933x-uart
我注意到这个tx
和rx
字段值在我的程序运行期间不会改变,即使我手动写入我的串行。
serinfo:1.0 driver revision:
0: uart:AR933X UART mmio:0x18020000 irq:11 tx:169 rx:0 RTS|DTR|CD
/proc/tty/驱动程序/串行
serinfo:1.0 driver revision:
0: uart:unknown port:00000000 irq:0
1: uart:unknown port:00000000 irq:0
2: uart:unknown port:00000000 irq:0
3: uart:unknown port:00000000 irq:0
4: uart:unknown port:00000000 irq:0
5: uart:unknown port:00000000 irq:0
6: uart:unknown port:00000000 irq:0
7: uart:unknown port:00000000 irq:0
8: uart:unknown port:00000000 irq:0
9: uart:unknown port:00000000 irq:0
10: uart:unknown port:00000000 irq:0
11: uart:unknown port:00000000 irq:0
12: uart:unknown port:00000000 irq:0
13: uart:unknown port:00000000 irq:0
14: uart:unknown port:00000000 irq:0
15: uart:unknown port:00000000 irq:0
/proc/tty/驱动程序/usbserial
usbserinfo:1.0 driver:2.0
0: module:pl2303 name:"pl2303" vendor:067b product:2303 num_ports:1 port:1 path:usb-ehci-platform-1
而且,下面是更详细的代码...
int Serial::openup(const char *devfile) {
if(-1 == (devfds = open(devfile, O_RDWR | O_NOCTTY ))) {
perror(strerror(errno));
return -1;
}
// set device file io mode to nonblock
//int oldflags = fcntl(devfds, F_GETFL);
//fcntl(devfds, F_SETFL, oldflags | O_NONBLOCK);
// get terminal's attributes
tcgetattr(devfds, &tminfo);
memset(&tminfo, 0, sizeof(struct termios));
/// set local mode options ///
//tminfo.c_lflag |= ICANON;
tminfo.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG | IEXTEN);
/// set control mode options ///
tminfo.c_cflag |= (CLOCAL | CREAD);
// disable hardware flow control
tminfo.c_cflag &= ~CRTSCTS;
// set how many bits in a character
tminfo.c_cflag &= ~CSIZE;
tminfo.c_cflag |= CS8;
// we don't need prity checking
tminfo.c_cflag &= ~PARENB;
tminfo.c_cflag &= ~CSTOPB;
/// set input mode options ///
// disable input parity checking, this
tminfo.c_iflag &= ~(INPCK | PARMRK | IGNBRK | BRKINT | ISTRIP
| INLCR | IGNCR | ICRNL | IXON);
/// set output mode options ///
//tminfo.c_oflag |= (OPOST | ONLCR);
tminfo.c_oflag &= ~OPOST; // ***
tminfo.c_cc[VMIN] = 0; // ***
tminfo.c_cc[VTIME] = 1; // ***
/// set line speed, defaults to 38400bps, both for input and output ///
// this call will set both input and output speed
cfsetspeed(&tminfo, B38400);
if(-1 == tcsetattr(devfds, TCSANOW, &tminfo)) {
perror(strerror(errno));
return -1;
}
return 0;
}
int Serial::serve() {
char buffer[256] = {0};
/*
struct timeval timeo;
timeo.tv_sec = 0;
timeo.tv_usec = 2 * 1000;
select(0, NULL, NULL, NULL, &timeo);
*/
//print_trace("ready to read data from serial port.\n");
int read_count = 0;
if((read_count = read_line(devfds, buffer, 256))) {
print_trace("read line: %d bytes, %s\n", read_count, buffer);
if(0 == strncmp(buffer, "S", 1)) {
// do some operation
} else if(0 == strncmp(buffer, "N", 1)) {
// do some operation
}
} else {
//print_trace("read no data.\n");
}
// TODO: test only, for find out the reason of serial port 'dead' problem
tcflush(devfds, TCIFLUSH);
}
其他模块还有另一个功能可以写入串口
int Serial::write_to_zigbee_co(const char *msg) {
int write_count = 0;
int len = strlen(msg);
struct timeval timeo;
timeo.tv_sec = 0;
timeo.tv_usec = 20 * 1000;
select(0, NULL, NULL, NULL, &timeo);
tcflush(devfds, TCOFLUSH);
if(len == (write_count = write(devfds, msg, len))) {
} else {
tcflush(devfds, TCOFLUSH);
}
return write_count;
}