M
Muffinman
Hello all,
I'm not sure whether this is the appropriate place for this question,
but I couldn't find a better place. So here it goes:
I have an application that needs to receive some data via a serial port.
The data is received, however, it breaks down in multiple packets. So
sending 18 bytes often results in two packets of 8 bytes and one of 2
(but sometimes also 8,9&1). Setting VMIN allows me to push it up to how
many bytes I want. However, sometimes I need to receive 4 bytes, other
times 25. It is not consistent, so that's no option.
I need to process commands.
- Processing each packet at a time would not work because it can break
down commands.
- I could fill my own buffer, but timing is quite crucial...
1) So, can I solve this? Is there anything I can do with my
configuration (see below)?
2) Why does this happen? The only thing I can think of is that the
sending device skips a opportunity to send data every so bytes...
I hope someone can help.
Thanks in advance, Maarten
################# serial port polling #################
if(poll_fds[0].revents & POLLIN)
{
bytes_read = read(serial_fd, device_status_message,
sizeof(device_status_message));
if(bytes_read <= 0)
continue;
[...]
############# serial port configuraton #################
/* c_cflag
* setting all the variables according to the configuration file
* and some default settings */
serial_new_attr.c_cflag |= (CLOCAL | CREAD);
if(common_data.serial_parity == 0)
serial_new_attr.c_cflag &= ~PARENB;
else
{
serial_new_attr.c_cflag |= PARENB;
/* enable parity check and strip it from output */
serial_new_attr.c_iflag |= (INPCK | ISTRIP);
if(common_data.serial_even == 0)
serial_new_attr.c_cflag |= PARODD;
else
serial_new_attr.c_cflag &= ~PARODD;
}
if(common_data.serial_2stop == 0)
serial_new_attr.c_cflag &= ~CSTOPB;
else
serial_new_attr.c_cflag |= CSTOPB;
serial_new_attr.c_cflag &= ~CSIZE;
serial_new_attr.c_cflag |= common_data.serial_bits;
/* c_lflag
* enable raw input */
serial_new_attr.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
/* Disabling hardware flow control */
serial_new_attr.c_cflag &= ~CRTSCTS;
/* Disabling software flow control */
serial_new_attr.c_iflag &= ~(IXON | IXOFF | IXANY);
/* Disabling any postprocessing */
serial_new_attr.c_oflag &= ~OPOST;
/* Minimum characters to read (non-canonical) */
serial_new_attr.c_cc[VMIN] = 1;
/* Wait indefinitely for input (non-canonical) */
serial_new_attr.c_cc[VTIME] = 3;
cfsetospeed(&serial_new_attr, common_data.serial_speed);
cfsetispeed(&serial_new_attr, common_data.serial_speed);
I'm not sure whether this is the appropriate place for this question,
but I couldn't find a better place. So here it goes:
I have an application that needs to receive some data via a serial port.
The data is received, however, it breaks down in multiple packets. So
sending 18 bytes often results in two packets of 8 bytes and one of 2
(but sometimes also 8,9&1). Setting VMIN allows me to push it up to how
many bytes I want. However, sometimes I need to receive 4 bytes, other
times 25. It is not consistent, so that's no option.
I need to process commands.
- Processing each packet at a time would not work because it can break
down commands.
- I could fill my own buffer, but timing is quite crucial...
1) So, can I solve this? Is there anything I can do with my
configuration (see below)?
2) Why does this happen? The only thing I can think of is that the
sending device skips a opportunity to send data every so bytes...
I hope someone can help.
Thanks in advance, Maarten
################# serial port polling #################
if(poll_fds[0].revents & POLLIN)
{
bytes_read = read(serial_fd, device_status_message,
sizeof(device_status_message));
if(bytes_read <= 0)
continue;
[...]
############# serial port configuraton #################
/* c_cflag
* setting all the variables according to the configuration file
* and some default settings */
serial_new_attr.c_cflag |= (CLOCAL | CREAD);
if(common_data.serial_parity == 0)
serial_new_attr.c_cflag &= ~PARENB;
else
{
serial_new_attr.c_cflag |= PARENB;
/* enable parity check and strip it from output */
serial_new_attr.c_iflag |= (INPCK | ISTRIP);
if(common_data.serial_even == 0)
serial_new_attr.c_cflag |= PARODD;
else
serial_new_attr.c_cflag &= ~PARODD;
}
if(common_data.serial_2stop == 0)
serial_new_attr.c_cflag &= ~CSTOPB;
else
serial_new_attr.c_cflag |= CSTOPB;
serial_new_attr.c_cflag &= ~CSIZE;
serial_new_attr.c_cflag |= common_data.serial_bits;
/* c_lflag
* enable raw input */
serial_new_attr.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
/* Disabling hardware flow control */
serial_new_attr.c_cflag &= ~CRTSCTS;
/* Disabling software flow control */
serial_new_attr.c_iflag &= ~(IXON | IXOFF | IXANY);
/* Disabling any postprocessing */
serial_new_attr.c_oflag &= ~OPOST;
/* Minimum characters to read (non-canonical) */
serial_new_attr.c_cc[VMIN] = 1;
/* Wait indefinitely for input (non-canonical) */
serial_new_attr.c_cc[VTIME] = 3;
cfsetospeed(&serial_new_attr, common_data.serial_speed);
cfsetispeed(&serial_new_attr, common_data.serial_speed);