I wrote a program that communicate with serial port, using termios, this program will read serial port in non-blocking mode and write response to serial port once it read data. If there is no data read from serial port, the program will do other thing, on next loop, the program read serial port again.
now the question is, after sometimes gone, maybe several minutes, or maybe several hours, the serial port don't respond to my program any more. Even I execute echo 'HB\n' > /dev/ttyUSB0
(then the serial port should respond 'HACK'), it doesn't respond any more..
I even don't known when the serial port is 'dead', I don't have any clue.. it 'dead' untimed.
here is my configuration:
/// 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);
It's hard to debug the serial in this situation. I really can't figure out what cause the serial port 'dead' on earth. I'm nearly crazy...
what the possible reason? Any help will be appreciated!
update:
when the serial port "dead", its configuration is:
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
update 2
/proc/tty/driver/ar933x-uart
I have noticed that this tx
and rx
field value does not change during my program running, even if I write to my serial manually.
serinfo:1.0 driver revision:
0: uart:AR933X UART mmio:0x18020000 irq:11 tx:169 rx:0 RTS|DTR|CD
/proc/tty/driver/serial
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/driver/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
and, below is the more detailed code...
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);
}
there is another function for other module to write to serial port
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;
}