Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 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:
- 1. I wait for 2 bytes - the opcode of the command.
- 2. Once I resolve a code, I wait for 4 bytes designating the `length` of data that will follow (depending on the command)
- 3. I create a buffer in my application of size equal to the `length` I received above.
- 4. I start receiving the data.
- Note that I receive my data using a `for` loop, reading() one byte at time.
- 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).
- 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.
- 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.
- 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/.
- I am initializing the serial port with the following settings, should that be helpful:
- fd = open("/dev/ttymxc0", O_RDWR | O_NOCTTY | O_SYNC );
- memset(&oldtio,0,sizeof(oldtio));
- tcgetattr(fd,&oldtio); /* save current serial port settings */
- bzero(&newtio, sizeof(newtio)); /* clear struct for new port settings */
- newtio.c_cflag= B19200 | CS8 | CLOCAL | CREAD ;
- newtio.c_iflag=IGNPAR | ICRNL ;
- newtio.c_oflag=0;//ONLCR ;
- newtio.c_lflag=0; //ICANON;
- newtio.c_cc[VTIME]=600; /* units: deci-seconds */
- newtio.c_cc[VMIN]=1; /* blocking read until 1 character arrives */
- tcflush(fd, TCIFLUSH);
- tcsetattr(fd,TCSANOW,&newtio);
- Thank you for your help
- **EDIT / append :**
- The code used (after following the Posix guide)
- int open_com_device(){
- fd = open("/dev/ttymxc0", O_RDWR | O_NOCTTY | O_NDELAY );
- tcgetattr(fd, &serial_opts);
- cfsetispeed(&serial_opts, ACM_BAUD);
- cfsetospeed(&serial_opts, ACM_BAUD);
- serial_opts.c_cflag |= ( CLOCAL | CREAD );
- serial_opts.c_cflag &= ~PARENB;
- serial_opts.c_cflag &= ~CSTOPB;
- serial_opts.c_cflag &= ~CSIZE;
- serial_opts.c_cflag |= CS8;
- serial_opts.c_lflag &= ~( ICANON | ECHO | ECHOE | ISIG );
- serial_opts.c_iflag &= ~( IXON | IXOFF | IXANY );
- serial_opts.c_iflag |= ( IGNPAR | ICRNL );
- serial_opts.c_oflag &= ~OPOST;
- serial_opts.c_cc[VTIME]=10*SERIAL_TIMEOUT_SEC; //in deci-seconds
- serial_opts.c_cc[VMIN]=1;
- tcsetattr(fd, TCSANOW, &serial_opts);
- }
- I read the opcode (2byte fixed length) and the datasize (8byte fixed length) of data that may follow with http://pastebin.com/DyLnYCVn
- 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
- While receiving data, I get a timeout on the select() function.
- **EDIT2 /append2:**
- the code is in http://pastebin.com/rpU01MwB
- 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`.
- 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.
- So initially the debug output looks like:
- SERIAL: DATA will read DATA bytes 138669
- SERIAL: DATA read 59 bytes and a total of 0 .
- SERIAL: DATA read 1 bytes and a total of 59 .
- SERIAL: DATA read 1 bytes and a total of 60 .
- SERIAL: DATA read 2 bytes and a total of 61 .
- SERIAL: DATA read 1 bytes and a total of 63 .
- SERIAL: DATA read 1 bytes and a total of 64 .
- SERIAL: DATA read 1 bytes and a total of 65 .
- SERIAL: DATA read 1 bytes and a total of 66 .
- SERIAL: DATA read 1 bytes and a total of 67 .
- then towards byte 12278
- SERIAL: DATA read 1 bytes and a total of 12273 .
- SERIAL: DATA read 1 bytes and a total of 12274 .
- SERIAL: DATA read 1 bytes and a total of 12275 .
- SERIAL: DATA read 1 bytes and a total of 12276 .
- SERIAL: DATA read 1 bytes and a total of 12277 .
- SERIAL: No DATA have been read. Prob Timeout @ byte 12278. exiting fn
- for baudrate 115200, the timeout occurs at this specific byte.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement