Hello!
I "created" a library for working with serial port to Qt4 in asynchronous mode, while using as a base - QextSerialPort and the full of his altered.
My class is inherited from QIODevice.
Problems arise when working in Qt 4.3.4 under ArchLinux x86_64, which is that if the function bytesAvaiable() call inside a function readDAta() - a function bytesAvaiable() returns an incorrect number of bytes = 16384! o_O
Implementation bytesAvaiable () for POSIX:
qint64 TPosixSerialDevice::bytesAvailable()
{
if (isOpen()) {
int bytesQueued=0;
if (ioctl(fd, FIONREAD, &bytesQueued)==-1) {
TTY_PORTABILITY_DEBUG("TPosixSerialDevice::bytesAvailable->ioctl(FIONREAD)! Error!");
return -1;
}
return bytesQueued + QIODEvice:: bytesAvaiable() ;
}//if isOpen()
TTY_PORTABILITY_DEBUG("TPosixSerialDevice::bytesAvailable->Device is not open! Error!");
return -1;
}
qint64 TPosixSerialDevice::bytesAvailable()
{
if (isOpen()) {
int bytesQueued=0;
if (ioctl(fd, FIONREAD, &bytesQueued)==-1) {
TTY_PORTABILITY_DEBUG("TPosixSerialDevice::bytesAvailable->ioctl(FIONREAD)! Error!");
return -1;
}
return bytesQueued + QIODEvice:: bytesAvaiable() ;
}//if isOpen()
TTY_PORTABILITY_DEBUG("TPosixSerialDevice::bytesAvailable->Device is not open! Error!");
return -1;
}
To copy to clipboard, switch view to plain text mode
So:
1. If you do it like this:
int main(int argc, char *argv[])
{
TSerialDevice *MyDevice; // where TSerialDevice - the heir of QIODEvice!
MyDevice = new TSerialDevice();
return 0;
}
if (MyDevice->waitForReadyRead(3000)) { //wait data 3 sec
cout << "Data is ready" << endl;
int bav = MyDevice->bytesAvailable(); // <========== HERE returning the proper number of bytes in the reception buffer!
}
cout << "End for";
MyDevice->close();
cout << "End Close";
return app.exec();
}
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
TSerialDevice *MyDevice; // where TSerialDevice - the heir of QIODEvice!
MyDevice = new TSerialDevice();
if (!MyDevice->open(QIODevice::ReadWrite)) {
return 0;
}
if (MyDevice->waitForReadyRead(3000)) { //wait data 3 sec
cout << "Data is ready" << endl;
int bav = MyDevice->bytesAvailable(); // <========== HERE returning the proper number of bytes in the reception buffer!
}
cout << "End for";
MyDevice->close();
cout << "End Close";
return app.exec();
}
To copy to clipboard, switch view to plain text mode
then the function MyDevice-> bytesAvailable () - returns all right!
2. If you do it like this:
int main(int argc, char *argv[])
{
TSerialDevice *MyDevice; //where TSerialDevice - the heir of QIODEvice!
MyDevice = new TSerialDevice();
return 0;
}
if (MyDevice->waitForReadyRead(3000)) { //wait data 3 sec
cout << "Data is ready" << endl;
QBytesArray ba = MyDevice->read(); // HERE DOES NOT RIGHT!
}
cout << "End for";
MyDevice->close();
cout << "End Close";
return app.exec();
}
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
TSerialDevice *MyDevice; //where TSerialDevice - the heir of QIODEvice!
MyDevice = new TSerialDevice();
if (!MyDevice->open(QIODevice::ReadWrite)) {
return 0;
}
if (MyDevice->waitForReadyRead(3000)) { //wait data 3 sec
cout << "Data is ready" << endl;
QBytesArray ba = MyDevice->read(); // HERE DOES NOT RIGHT!
}
cout << "End for";
MyDevice->close();
cout << "End Close";
return app.exec();
}
To copy to clipboard, switch view to plain text mode
ie if you call read (), which is readData (), which is called bytesAvailable () - it bytesAvailable () returns an incorrect value = 16384!
Implementation readData() for POSIX
qint64 TPosixSerialDevice::readData(char * data, qint64 maxSize)
{
int bytesRead=0;//the number of bytes actually read in one pass
int retVal=0;//the number of bytes actually read all the passages
int bav=0;// the number of bytes ready to read, which are currently in the reception buffer, the serial device
do {
if (maxSize>retVal) {
bav=bytesAvailable(); // <=========== THIS RETURN INCORRECT VALUE = 16384 !!! о_О
if (bav>0) {
if ((maxSize-retVal)<=bav) {
bav=maxSize-retVal;
}
bytesRead = ::read(fd, (void*)(data+retVal), bav);
if (bytesRead==-1) {
TTY_PORTABILITY_DEBUG("TPosixSerialDevice::readData->bytesRead==-1! Error!");
return -1;
}//if read == -1
else {
if (bytesRead==bav) {
retVal+=bytesRead;//with OK
}//if bytesRead==bav
else {
TTY_PORTABILITY_DEBUG("TPosixSerialDevice::readData->(bytesRead!=bav) with OK! Error!");
return -1;
}//else bytesRead!=bav
}//else read
}//if bav>0
else {
TTY_PORTABILITY_DEBUG("TPosixSerialDevice::readData-> (bav<=0)! Error!");
return -1;
}//else bav<=0
}//if maxSize>retVal
else {
return retVal;
}
} while (waitForReadyRead(parameters->charIntervalTimeout));//forward to coming to the reception buffer device next character
return retVal;
}
qint64 TPosixSerialDevice::readData(char * data, qint64 maxSize)
{
int bytesRead=0;//the number of bytes actually read in one pass
int retVal=0;//the number of bytes actually read all the passages
int bav=0;// the number of bytes ready to read, which are currently in the reception buffer, the serial device
do {
if (maxSize>retVal) {
bav=bytesAvailable(); // <=========== THIS RETURN INCORRECT VALUE = 16384 !!! о_О
if (bav>0) {
if ((maxSize-retVal)<=bav) {
bav=maxSize-retVal;
}
bytesRead = ::read(fd, (void*)(data+retVal), bav);
if (bytesRead==-1) {
TTY_PORTABILITY_DEBUG("TPosixSerialDevice::readData->bytesRead==-1! Error!");
return -1;
}//if read == -1
else {
if (bytesRead==bav) {
retVal+=bytesRead;//with OK
}//if bytesRead==bav
else {
TTY_PORTABILITY_DEBUG("TPosixSerialDevice::readData->(bytesRead!=bav) with OK! Error!");
return -1;
}//else bytesRead!=bav
}//else read
}//if bav>0
else {
TTY_PORTABILITY_DEBUG("TPosixSerialDevice::readData-> (bav<=0)! Error!");
return -1;
}//else bav<=0
}//if maxSize>retVal
else {
return retVal;
}
} while (waitForReadyRead(parameters->charIntervalTimeout));//forward to coming to the reception buffer device next character
return retVal;
}
To copy to clipboard, switch view to plain text mode
At the same time when testing in Qt4.1 under Windows - that no error!
Help to understand what's wrong! : (
PS:
source code library and examples can be downloaded at the forum: http://www.prog.org.ru/topic_9537_0.html
there must be pre-registered. Downloads: QSerialDevce.tar.bz2 attached as an attachment.
Bookmarks