Advertisement
synthnassizer

stackOverflowDisc

Jul 11th, 2013
298
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.05 KB | None | 0 0
  1. I am developing an application for a linux embedded system and I'm trying to receive data from the serial port `/dev/ttyUSB0`. The story goes like this:
  2.  
  3. 1. I wait for 2 bytes - the opcode of the command.
  4. 2. Once I resolve a code, I wait for 4 bytes designating the `length` of data that will follow (depending on the command)
  5. 3. I create a buffer in my application of size equal to the `length` I received above.
  6. 4. I start receiving the data.
  7.  
  8. Note that I receive my data using a `for` loop, reading() one byte at time.
  9. Note also that I am using the `select(2)` mechanism as a means to timeout if I am left halfway through a reception of data (so that the read() on the serial port will not halt indefinitely in case of communication breakage).
  10.  
  11. The problem is that somewhere during transmission the `select()` on the serial port, times out. From one host pc, I constantly timeout at byte 6139. From another host pc running the same application I timeout at a byte in the range 55k-56k.
  12.  
  13. I also changed the Baud rate from 115200 on the latter pc and managed to timeout at byte 1147, 39891 and , once, to transmit the whole of ~139k of data (!) that I was aiming to transfer.
  14.  
  15. Could it be that the receive buffer fills up?? Could it be something else? The embedded system is running on an 1GHz iMX6q processor and has 32-byte half-word FIFO Rx buffer. I'd expect that the processing is done fast enough. I search for ways to alter the receive buffer size of the serial port driver in linux but did not find something relevant. Especially in http://www.tldp.org/HOWTO/Serial-Programming-HOWTO/.
  16.  
  17. I am initializing the serial port with the following settings, should that be helpful:
  18.  
  19. fd = open("/dev/ttymxc0", O_RDWR | O_NOCTTY | O_SYNC );
  20. memset(&oldtio,0,sizeof(oldtio));
  21. tcgetattr(fd,&oldtio); /* save current serial port settings */
  22. bzero(&newtio, sizeof(newtio)); /* clear struct for new port settings */
  23. newtio.c_cflag= B19200 | CS8 | CLOCAL | CREAD ;
  24. newtio.c_iflag=IGNPAR | ICRNL ;
  25. newtio.c_oflag=0;//ONLCR ;
  26. newtio.c_lflag=0; //ICANON;
  27. newtio.c_cc[VTIME]=600; /* units: deci-seconds */
  28. newtio.c_cc[VMIN]=1; /* blocking read until 1 character arrives */
  29. tcflush(fd, TCIFLUSH);
  30. tcsetattr(fd,TCSANOW,&newtio);
  31.  
  32. Thank you for your help
  33.  
  34.  
  35. **EDIT / append :**
  36.  
  37. The code used (after following the Posix guide)
  38.  
  39. int open_com_device(){
  40.  
  41. fd = open("/dev/ttymxc0", O_RDWR | O_NOCTTY | O_NDELAY );
  42.  
  43. tcgetattr(fd, &serial_opts);
  44. cfsetispeed(&serial_opts, ACM_BAUD);
  45. cfsetospeed(&serial_opts, ACM_BAUD);
  46.  
  47. serial_opts.c_cflag |= ( CLOCAL | CREAD );
  48. serial_opts.c_cflag &= ~PARENB;
  49. serial_opts.c_cflag &= ~CSTOPB;
  50. serial_opts.c_cflag &= ~CSIZE;
  51. serial_opts.c_cflag |= CS8;
  52.  
  53. serial_opts.c_lflag &= ~( ICANON | ECHO | ECHOE | ISIG );
  54. serial_opts.c_iflag &= ~( IXON | IXOFF | IXANY );
  55. serial_opts.c_iflag |= ( IGNPAR | ICRNL );
  56.  
  57. serial_opts.c_oflag &= ~OPOST;
  58.  
  59. serial_opts.c_cc[VTIME]=10*SERIAL_TIMEOUT_SEC; //in deci-seconds
  60. serial_opts.c_cc[VMIN]=1;
  61.  
  62. tcsetattr(fd, TCSANOW, &serial_opts);
  63. }
  64.  
  65. I read the opcode (2byte fixed length) and the datasize (8byte fixed length) of data that may follow with http://pastebin.com/DyLnYCVn
  66.  
  67. and if data are available (datasize>0) then I create a buffer of size datasize, to read in the data with http://pastebin.com/Bwjq3gne
  68.  
  69. While receiving data, I get a timeout on the select() function.
  70.  
  71.  
  72. **EDIT2 /append2:**
  73.  
  74. the code is in http://pastebin.com/rpU01MwB
  75.  
  76. Compared to EDIT/append 1 above, I have removed mutexes (weren't really necessary), removed select() (i fiddle around with c_cc[VMIN] at the moment. The open_com_device() fn doesn't have all the necessary error checking, but it has been working - I have verified that the settings are updated as expected with `stty`.
  77.  
  78. Basically, the readComData(const int toReadBytes, char *serDataBuf) fn is run with a pointer to a buffer that is of size "toReadBytes". The buffer has already malloc'ed enough space for the read to commence.
  79.  
  80. So initially the debug output looks like:
  81.  
  82. SERIAL: DATA will read DATA bytes 138669
  83. SERIAL: DATA read 59 bytes and a total of 0 .
  84. SERIAL: DATA read 1 bytes and a total of 59 .
  85. SERIAL: DATA read 1 bytes and a total of 60 .
  86. SERIAL: DATA read 2 bytes and a total of 61 .
  87. SERIAL: DATA read 1 bytes and a total of 63 .
  88. SERIAL: DATA read 1 bytes and a total of 64 .
  89. SERIAL: DATA read 1 bytes and a total of 65 .
  90. SERIAL: DATA read 1 bytes and a total of 66 .
  91. SERIAL: DATA read 1 bytes and a total of 67 .
  92.  
  93. then towards byte 12278
  94.  
  95. SERIAL: DATA read 1 bytes and a total of 12273 .
  96. SERIAL: DATA read 1 bytes and a total of 12274 .
  97. SERIAL: DATA read 1 bytes and a total of 12275 .
  98. SERIAL: DATA read 1 bytes and a total of 12276 .
  99. SERIAL: DATA read 1 bytes and a total of 12277 .
  100. SERIAL: No DATA have been read. Prob Timeout @ byte 12278. exiting fn
  101.  
  102. for baudrate 115200, the timeout occurs at this specific byte.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement