Boost logo

Boost Users :

Subject: Re: [Boost-users] [ASIO] Synchronous write on serial_port
From: Daniele Barzotti (daniele.barzotti_at_[hidden])
Date: 2009-04-07 11:55:55


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_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