I need to write a sequence of values (buffer, ~10bytes
) via UART
.
This sequence needs to start with a BREAK
delimiter, and in my case I need to decrease the baud rate to a lower value.
Details about my environment:
- Development board: BeagleBone Black.
- Linux Kernel version: 3.8.13-bone70.
- Serial driver used by the
tty
discipline: omap-serial.
What I finally get is something like this:
UARTIOHandler->setBaudRate(B9600);
unsigned char breakChar[] = { 0 };
UARTIOHandler->write(breakChar, 1);
UARTIOHandler->setBaudRate(B19200);
UARTIOHandler->write({1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
The write
method is implemented this way:
int UARTIOHandler::write(const std::initializer_list<uchar8> &data) {
uchar8 buffer[data.size()];
int counter = 0;
for(auto i : data) {
buffer[counter++] = i;
}
auto output = ::write(this->fd_write, buffer, data.size());
this->flush();
return output;
}
And finally the flush()
method:
void UARTIOHandler::flush() {
tcflush(this->fd_write, TCIOFLUSH);
}
The problem with this code is that the flushing doesn't always work, sometimes the distance between the BREAK
and the first byte of data (observed on a scope) is ~500us
(which is fine for my application), and sometimes is up to ~3ms
.
EDIT: This is the actual behavior:
For the first five seconds everything works fine (the distance between the BREAK
and the rest of the message doesn't exceed ~1ms
), then, after five seconds there are some frames that exceed this inter-byte timing (for up to ~3ms
).
There's always the code that I posted which is executed, so there's no possible way that I somehow forget flushing the buffers.
Why do this variations happen?
I have searched for relevant problems and found this, one workaround described there is to use a delay in front of the tcflush(...)
function call. I can't use this method in my application because it will affect the functionality.
Another comment in that topic suggests that this was a bug in the Linux kernel, could this also be in my case?