c++ – Using Full-Duplex Serial Port with ASIO (or other libraries) in a Synchronous Manner

Yes you can do it the complicated way by synchronizing multi thread access to the IO object:

(todo coming up with complicated example)

Simpler, Single-Threaded Async

#include <boost/asio.hpp>
#include <boost/asio/serial_port.hpp>
#include <deque>
#include <iomanip>
#include <iostream>

namespace asio = boost::asio;
using sp       = asio::serial_port;
using boost::system::error_code;
using namespace std::literals;

struct Example {
    Example(asio::any_io_executor ex, std::string dev) : sp_(ex, dev) {
        readLoop();
    }

    void Send(std::string cmd) {
        std::cerr << "Queue: " << quoted(cmd) << std::endl;
        outbox_.push_back(std::move(cmd));
        if (outbox_.size() == 1)
            writeLoop();
    }

    void Stop() {
        sp_.cancel();
    }

  private:
    void readLoop() {
        asio::async_read_until( //
            sp_, asio::dynamic_buffer(incoming_), "\n", [this](error_code ec, size_t len) {
                std::cerr << "Read: " << len << " (" << ec.message() << ")" << std::endl;
                if (!ec.failed()) {
                    Send("echo: "s + incoming_.substr(0, len));
                    incoming_.erase(0, len);
                    readLoop();
                }
            });
    }
    void writeLoop() {
        if (outbox_.empty())
            return;
        asio::async_write(sp_, asio::buffer(outbox_.front()), [this](error_code ec, size_t len) {
            std::cerr << "Wrote: " << len << " (" << ec.message() << ")" << std::endl;
            if (!ec.failed()) {
                outbox_.pop_front();
                writeLoop();
            }
        });
    }

    asio::serial_port       sp_;
    std::string             incoming_;
    std::deque<std::string> outbox_;
};

int main(int argc, char** argv) {
    asio::io_context ioc;
    Example          drone(ioc.get_executor(), (argc > 1 ? argv[1] : "/dev/stty0"));

    ioc.run_for(30s);

    // not really needed, but to show graceful shutdown
    drone.Stop();
    ioc.run();
}

Live Demo:

enter image description here

Read more here: Source link