Hi, I've isolated the problem (I think). But I can't understand why it works in this manner!! I've posted a working code in attach (made with VS2008 EXP), if someone could give me some feedback I will grate to him! In the code there are two wrapper classes for the asio::serial_port, one that works well and the other (mine) that has the issue! Thanks in advance. Daniele. Daniele Barzotti wrote:
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_ptrboost::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");