title: serial port not responding
body: <p>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.</p>
  
  <p>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 <code>echo 'HB\n' &gt; /dev/ttyUSB0</code>(then the serial port should respond 'HACK'), it doesn't respond any more..</p>
  
  <p>I even don't known when the serial port is 'dead', I don't have any clue.. it 'dead' untimed.</p>
  
  <p>here is my configuration: </p>
  
  <pre><code>/// set local mode options 
  //tminfo.c_lflag |= ICANON;                                                                       
  tminfo.c_lflag &amp;= ~(ICANON | ECHO | ECHOE | ISIG);                                             
  
  /// set control mode options                                                                   
  tminfo.c_cflag |= (CLOCAL | CREAD);                                                               
  tminfo.c_cflag |= HUPCL; 
  
  // set hardware flow control 
  tminfo.c_cflag &amp;= ~CRTSCTS;       
  
  // set how many bits in a character                                                               
  tminfo.c_cflag &amp;= ~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 &amp;= ~PARENB; // we don't need prity checking now                                                                                                                                 
  
  /// set input mode options  
  // set input parity checking
  tminfo.c_iflag &amp;= ~INPCK; 
  tminfo.c_cflag &amp;= ~CSTOPB;                                                                                                                                                                
  
  /// set output mode options                                                                                                                      
  tminfo.c_oflag &amp;= ~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(&amp;tminfo, B38400);
  </code></pre>
  
  <p>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...</p>
  
  <p>what the possible reason? Any help will be appreciated!</p>
  
  <h3>update:</h3>
  
  <p>when the serial port "dead", its configuration is: </p>
  
  <pre><code>speed 38400 baud; rows 0; columns 0; line = 0;
  intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = &lt;undef&gt;; eol2 = &lt;undef&gt;;      swtch = &lt;undef&gt;;
  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
  </code></pre>
  
  <h3>update 2</h3>
  
  <p><strong>/proc/tty/driver/ar933x-uart</strong><br>
  I have noticed that this <code>tx</code> and <code>rx</code> field value does not change during my program running, even if I write to my serial manually.</p>
  
  <pre><code>serinfo:1.0 driver revision:
  0: uart:AR933X UART mmio:0x18020000 irq:11 tx:169 rx:0 RTS|DTR|CD
  </code></pre>
  
  <p><strong>/proc/tty/driver/serial</strong></p>
  
  <pre><code>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
  </code></pre>
  
  <p><strong>/proc/tty/driver/usbserial</strong></p>
  
  <pre><code>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
  </code></pre>
  
  <p><strong>and, below is the more detailed code...</strong></p>
  
  <pre><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, &amp;tminfo);
  
      memset(&amp;tminfo, 0, sizeof(struct termios));
  
      /// set local mode options  ///
      //tminfo.c_lflag |= ICANON;
      tminfo.c_lflag &amp;= ~(ICANON | ECHO | ECHOE | ISIG | IEXTEN);
  
      /// set control mode options ///
      tminfo.c_cflag |= (CLOCAL | CREAD);
      // disable hardware flow control
      tminfo.c_cflag &amp;= ~CRTSCTS;  
      // set how many bits in a character
      tminfo.c_cflag &amp;= ~CSIZE;
      tminfo.c_cflag |= CS8;
      // we don't need prity checking 
      tminfo.c_cflag &amp;= ~PARENB; 
      tminfo.c_cflag &amp;= ~CSTOPB;  
  
      /// set input mode options  ///
      // disable input parity checking, this 
      tminfo.c_iflag &amp;= ~(INPCK | PARMRK | IGNBRK | BRKINT | ISTRIP 
          | INLCR | IGNCR | ICRNL | IXON); 
  
      /// set output mode options  ///
      //tminfo.c_oflag |= (OPOST | ONLCR);
      tminfo.c_oflag &amp;= ~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(&amp;tminfo, B38400);
  
      if(-1 == tcsetattr(devfds, TCSANOW, &amp;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, &amp;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);
  }
  </code></pre>
  
  <p><strong>there is another function for other module to write to serial port</strong></p>
  
  <pre><code>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, &amp;timeo);
  
      tcflush(devfds, TCOFLUSH);
  
      if(len == (write_count = write(devfds, msg, len))) {
      } else {
          tcflush(devfds, TCOFLUSH);
      }
  
      return write_count;
  }
  </code></pre>