【发布时间】:2014-11-22 03:25:58
【问题描述】:
我一直致力于通过学习使用 boost::asio::basic_serial_port 的基本串行终端示例来实现半双工串行驱动程序: http://lists.boost.org/boost-users/att-41140/minicom.cpp
我需要异步读取,但仍会检测到处理程序何时在主线程中完成,因此我使用 boost:bind 在 lambda 函数中传递了一个带有多个附加引用参数的 async_read_some 回调。处理程序永远不会被调用,但如果我用 read_some 函数替换 async_read_some 函数,它会毫无问题地返回数据。
我相信我满足了该函数调用处理程序的所有必要要求,因为它们对于 asio::read 一些返回的函数是相同的:
- 缓冲区保持在范围内
- 串行设备接收到一个或多个字节
- io 服务正在运行
- 端口已打开并以正确的波特率运行
有谁知道我是否遗漏了异步读取特有的另一个假设,或者我没有正确设置 io_service?
以下是我如何将代码与 async_read_some (http://www.boost.org/doc/libs/1_56_0/doc/html/boost_asio/reference/basic_serial_port/async_read_some.html) 一起使用的示例:
void readCallback(const boost::system::error_code& error, size_t bytes_transfered, bool & finished_reading, boost::system::error_code& error_report, size_t & bytes_read)
{
std::cout << "READ CALLBACK\n";
std::cout.flush();
error_report = error;
bytes_read = bytes_transfered;
finished_reading = true;
return;
}
int main()
{
int baud_rate = 115200;
std::string port_name = "/dev/ttyUSB0";
boost::asio::io_service io_service_;
boost::asio::serial_port serial_port_(io_service_,port_name);
serial_port_.set_option(boost::asio::serial_port_base::baud_rate(baud_rate));
boost::thread service_thread_;
service_thread = boost::thread(boost::bind(&boost::asio::io_service::run, &io_service_));
std::cout << "Starting byte read\n";
boost::system::error_code ec;
bool finished_reading = false;
size_t bytes_read;
int max_response_size = 8;
uint8_t read_buffer[max_response_size];
serial_port_.async_read_some(boost::asio::buffer(read_buffer, max_response_size),
boost::bind(readCallback,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred,
finished_reading, ec, bytes_read));
std::cout << "Waiting for read to finish\n";
while (!finished_reading)
{
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
}
std::cout << "Finished byte read: " << bytes_read << "\n";
for (int i = 0; i < bytes_read; ++i)
{
printf("0x%x ",read_buffer[i]);
}
}
结果是回调没有打印出任何内容,并且 while !finished 循环永远不会结束。
这是我使用阻塞 read_some 函数的方法(boost.org/doc/libs/1_56_0/doc/html/boost_asio/reference/basic_serial_port/read_some.html):
int main()
{
int baud_rate = 115200;
std::string port_name = "/dev/ttyUSB0";
boost::asio::io_service io_service_;
boost::asio::serial_port serial_port_(io_service_,port_name);
serial_port_.set_option(boost::asio::serial_port_base::baud_rate(baud_rate));
boost::thread service_thread_;
service_thread = boost::thread(boost::bind(&boost::asio::io_service::run, &io_service_));
std::cout << "Starting byte read\n";
boost::system::error_code ec;
int max_response_size = 8;
uint8_t read_buffer[max_response_size];
int bytes_read = serial_port_.read_some(boost::asio::buffer(read_buffer, max_response_size),ec);
std::cout << "Finished byte read: " << bytes_read << "\n";
for (int i = 0; i < bytes_read; ++i)
{
printf("0x%x ",read_buffer[i]);
}
}
此版本打印我发送的 1 到 8 个字符,阻塞直到至少发送一个。
【问题讨论】:
标签: boost serial-port boost-asio