?
Ich glaube ich habe das Problem eben behoben. Ich verwende die cancel Methode nicht mehr, um read Vorgänge abzubrechen, statt dessen läuft nun immer ein Read Vorgang und startet sich dann quasi neu wenn er beendet wurde.
#ifndef BOOSTCOMPORT_HPP_
#define BOOSTCOMPORT_HPP_
#include <boost/asio.hpp>
#include <string>
#include <iostream>
#include <boost/timer.hpp>
#define BUFFER_SIZE 1000000
using namespace std;
class BoostComPort
{
public:
BoostComPort();
~BoostComPort();
int open(std::string port, int baud);
int close();
bool isOpended();
int write(char* Data, unsigned int Length);
int read(char* data, int length, bool blocking=false, int timeout=-1 /* timeout in ms */);
boost::system::error_code& getLastError();
private:
void onPortRead(const boost::system::error_code& error, std::size_t bytes_transferred);
char* buffer;
int currentContent;
bool executed;
boost::asio::io_service io_service;
boost::asio::serial_port serialPort;
boost::system::error_code ec;
boost::system::error_code lastError;
protected:
};
#endif
#include "BoostComPort.hpp"
#include <boost/bind.hpp>
BoostComPort::BoostComPort():
currentContent(0),
serialPort(io_service)
{
lastError.clear();
buffer=new char[BUFFER_SIZE];
}
BoostComPort::~BoostComPort()
{
serialPort.close();
delete[] buffer;
}
int BoostComPort::open(std::string port, int baud)
{
if(serialPort.is_open())
serialPort.close();
serialPort.open(port);
boost::asio::serial_port_base::baud_rate baudRate(baud);
serialPort.set_option(baudRate);
serialPort.async_read_some(boost::asio::buffer(buffer+currentContent, BUFFER_SIZE-currentContent), boost::bind(&BoostComPort::onPortRead, this, _1, _2));
char* tmp=new char[100]; // 5MBi of temporary buffer to clean the system buffers
int read;
do
{
read=this->read(tmp, 100, false);
} while(read>0);
delete[] tmp;
return 0;
}
boost::system::error_code& BoostComPort::getLastError()
{
return lastError;
}
int BoostComPort::close()
{
serialPort.close();
return 0;
}
bool BoostComPort::isOpended()
{
return serialPort.is_open();
}
int BoostComPort::write(char* data, unsigned int length)
{
size_t written=boost::asio::write(serialPort, boost::asio::buffer(data, length), boost::asio::transfer_all(), ec);
if(written!=length)
return -1;
return 0;
}
int BoostComPort::read(char* data, int length, bool blocking, int timeout)
{
boost::timer time;
do
{
executed=false;
io_service.poll(); // read new data
if(executed)
serialPort.async_read_some(boost::asio::buffer(buffer+currentContent, BUFFER_SIZE-currentContent), boost::bind(&BoostComPort::onPortRead, this, _1, _2));
if(timeout>0)
{
if((int)(time.elapsed()*1000)>timeout || !serialPort.is_open())
return -1;
}
} while(blocking && currentContent<length);
int toCopy;
if(length<currentContent)
toCopy=length;
else
toCopy=currentContent;
memcpy(data, buffer, toCopy);
memcpy(buffer, buffer+toCopy, currentContent-toCopy);
currentContent-=toCopy;
return toCopy;
}
void BoostComPort::onPortRead(const boost::system::error_code& error, std::size_t bytes_transferred)
{
//cout<<"BoostComPort::onPortRead(): called"<<endl;
if(error==0)
{
currentContent+=bytes_transferred;
cout<<"Read some bytes: "<<bytes_transferred<<endl;
}
else if(error!=boost::asio::error::operation_aborted) // not cancelled
{
cerr<<"BoostComPort::onPortRead(): Unable to read from com port with error: "<<endl;
cerr<<"BoostComPort::onPortRead(): Error message: "<<error.message()<<endl;
cerr<<"BoostComPort::onPortRead(): Error code: "<<error<<endl;
lastError=ec;
}
executed=true;
}