4
votes

I'm using boost::asio::write() to write data from a buffer to a com-Port. It's a serial port with a baud rate 115200 which means (as far as my understanding goes) that I can write effectively 11520 byte/s or 11,52KB/s data to the socket.

Now I'm having a quite big chunk of data (10015 bytes) which i want to write. I think that this should take little less than a second to really write on the port. But boost::asio::write() returns already 300 microseconds after the call with the transferred bytes 10015. I think this is impossible with that baud rate?

So my question is what is it actually doing? Really writing it to the port, or just some other kind of buffer maybe, which later writes it to the port.

I'd like the write() to only return after all the bytes have really been written to the port.

EDIT with code example:

The problem is that i always run into the timeout for the future/promise because it takes alone more than 100ms to send the message, but I think the timer should only start after the last byte is sent. Because write() is supposed to block?

void serial::write(std::vector<uint8_t> message) {
  //create new promise for the request
  promise = new boost::promise<deque<uint8_t>>;
  boost::unique_future<deque<uint8_t>> future = promise->get_future();
  // --- Write message to serial port --- //
  boost::asio::write(serial_,boost::asio::buffer(message));
  //wait for data or timeout
  if (future.wait_for(boost::chrono::milliseconds(100))==boost::future_status::timeout) {
    cout << "ACK timeout!" << endl;
    //delete pointer and set it to 0
    delete promise;
    promise=nullptr;
  }
  //delete pointer and set it to 0 after getting a message
  delete promise;
  promise=nullptr;
}

How can I achieve this? Thanks!

1
Is baud rate really the same as bit rate?nurettin
1 Baud is one symbol per second. If your port uses symbols which encore more than 1 bit, the bitrate can actually go above the baudrate.Quentin
Honestly, I don't know exactly. But I don't think that I can write 10k of data in 300 microseconds.p0fi
How can I know how much bit are encoded in one symbol? The port has a configuration of char_size 8 and one stop bit.p0fi
check this out: calculator.org/property.aspx?name=data+rate. You are transfering at about 14KB/sNathanOliver

1 Answers

5
votes

In short, boost::asio::write() blocks until all data has been written to the stream; it does not block until all data has been transmitted. To wait until data has been transmitted, consider using tcdrain().

Each serial port has both a receive and transmit buffer within kernel space. This allows the kernel to buffer received data if a process cannot immediately read it from the serial port, and allows data written to a serial port to be buffered if the device cannot immediately transmit it. To block until the data has been transmitted, one could use tcdrain(serial_.native_handle()).

These kernel buffers allow for the write and read rates to exceed that of the transmit and receive rates. However, while the application may write data at a faster rate than the serial port can transmit, the kernel will transmit at the appropriate rates.