|
Boost Users : |
Subject: [Boost-users] [ASIO] Synchronous write on serial_port
From: Daniele Barzotti (daniele.barzotti_at_[hidden])
Date: 2009-04-06 04:06:16
Hi,
I'm developing a library that use ASIO Serial Port and I need to
implement a synchronous write.
The structure is:
EuroATLib.cpp : library main file
Serial.cpp : serial port class that wrap asio::serial_port
ATDispatcher.cpp : a dispatcher object
ATModem.cpp : the consumer object
The problem is that my code writes characters on serial port very slowly
(1 char every 10 seconds) and I can't understand why.
Also, when the program ends, the io_service thread seems to be already
alive: it continues to write to serial port for a while!
The implementation is like this...can someone give me some feedback?
PS: In the following code TBUFFER is std:string.
In EuroATLib.cpp :
----------------------------------------------------------
// Main io_service
static boost::asio::io_service io_service;
static boost::scoped_ptr<boost::thread> io_service_thread;
/*!
\brief Factory function for ATModem objects creation
*/
EXTERN_C EUROATLIB_API ATModem* CALL CreateATModemObj()
{
static bool thread_started;
if (!thread_started) {
try {
// run the IO service as a separate thread
io_service_thread.reset(new boost::thread(
boost::bind(&boost::asio::io_service::run, &io_service) ));
thread_started = !thread_started;
} catch (boost::thread_resource_error e) {
// Failed to create the new thread
return 0;
}
}
// create the new object
return new ATModem(io_service);
};
----------------------------------------------------------
In Serial.hpp :
----------------------------------------------------------
// the main IO service that runs this connection
boost::asio::io_service& _io_service;
// the serial port this instance is connected to
boost::asio::serial_port _serialPort;
----------------------------------------------------------
In Serial.cpp :
----------------------------------------------------------
SerialPort::SerialPort(boost::asio::io_service &_io) :
m_buffer_size(100),
_io_service(_io),
_serialPort(_io_service),
_rx_timer(_io_service),
ReadTimeOut(READ_TIMEOUT)
{
//init_dcs();
EosString = '\n';
_buf = 0;
};
BOOL SerialPort::Write(TBUFFER &buffer)
{
_io_service.post(boost::bind(&SerialPort::do_write, this, buffer));
return true;
};
void SerialPort::do_write(TBUFFER &buffer)
{
// size_t byte_written = boost::asio::write(_serialPort,
boost::asio::buffer(buffer.c_str(), buffer.size()));
size_t byte_written =
_serialPort.write_some(boost::asio::buffer(buffer.c_str(),
buffer.size()));
};
----------------------------------------------------------
In ATDispatcher.cpp simply have a SerialPort member and a function
SendCommand that start a timer and call Serial.Write(cmd)
In ATModem.cpp I have an ATDispatcher Object on which it calls
disp_obj.SendCommand("AT+CMGS"):
----------------------------------------------------------
RET_VAL ATModem::Connect(std::string DevName)
{
if (DevName.length() > 0) SetComPort(DevName);
if (!_serial_port.Open()) return -1;
//Connect the OnDataReceived event to the ATDispatcher object
_dispatcher->OnData(boost::bind(&EuroATLib::ATModem::OnDataReceived,
this));
//Register Voice Service
if ( _dispatcher->SendCommand("AT+CTSP=2,0,0") != ATDispatcher::RET_OK
) return DEV_AT_CMD_ERROR;
//Register STATUS Service
if ( _dispatcher->SendCommand("AT+CTSP=2,2,20") !=
ATDispatcher::RET_OK ) return DEV_AT_CMD_ERROR;
this->SetStatus(STATE_READY);
};
----------------------------------------------------------
Finally in the main client program:
// Create a ATModem object
boost::scoped_ptr<ATModem> _devATModem( CreateATModemObj() );
_devATModem->Connect("\\\\.\\COM1");
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net