1

I read all the solutions and test them. someone said used O_NDELAY and remove fnctl or the other said to use O_NONBLOCK and so on, but my problem does not solve.
I have nanopi neo and I want to use UART0. This is my code:
Main.cpp:

#include <QCoreApplication>
//#include "serialport.h"
#include "portserial.h"
#include <iostream>
#include <istream>
using namespace std;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QString port;PortSerial *p;

    cout<<"Enter tty:";
    QTextStream s(stdin);
    port = s.readLine();
    p=new PortSerial(port,1);
    if(p->openport(port)==1)
    {
        cout << "connected\n";
    }
    else
    {
        qDebug()<<"Not serial port : "<<port;
        delete p;
    }

    return a.exec();
}

and portSerial.h and .cpp:

#ifndef PORTSERIAL_H
#define PORTSERIAL_H

#include <stdio.h>   /* Standard input/output definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include "errno.h"   /* Error number definitions */
#include "termio.h" /* POSIX terminal control definitions */
#include <stdlib.h>
#include "QDebug"
#define MAXDATASIZE 2048
#include <QByteArray>
#include <QThread>
#include <pthread.h>

class PortSerial:public QObject
{
    Q_OBJECT
public:
    QThread t;
//    pthread_t  pthrd;
    int fd;
    int status;
    char * buffer;
    char * buffertemp;
    char buf2[MAXDATASIZE];
    QString output;
    QByteArray ba;
    QByteArray batemp;
    fd_set readfs;
    timeval tv;
    int n;
    int devid;
    bool wait;
    PortSerial(QString port, int dev);
    ~PortSerial();
public slots:
    int openport(QString port);
    int init();
    void closeport();
    void readData();
    void ifExist();
//    int readifexist(char &tmp);
    void writeData(QByteArray ba);
    signals:
    void readyread(QByteArray ba,int devids);
};

#endif // PORTSERIAL_H

and .cpp is:

#include "portserial.h"

PortSerial::PortSerial(QString port,int dev)
{
//    qDebug()<<"Start the thread";
    buffer = new char[1024];
    devid=dev;
    openport(port);
    moveToThread(&t);
    connect(&t, SIGNAL(started()), this, SLOT(ifExist()));
    t.start();
}

PortSerial::~PortSerial()
{
    closeport();
}



//____________________________
int PortSerial::openport(QString port)
{
  fd=open(port.toStdString().c_str(),O_RDWR|O_NOCTTY|O_NDELAY/*O_NONBLOCK*/);//ARM

   if (fd==-1)
   {
       return -1;//return open port error
   }
   else
   {
//       fcntl(fd,F_SETFL,O_NDELAY);
       init();
       return 1;
   }
}
//-------------------------------------
void PortSerial::closeport()
{
    qDebug()<<"Close with : " << close(fd);
}
//-------------------------------------
int PortSerial::init()
{
    struct termios tty;
    struct termios tty_old;
    memset (&tty, 0, sizeof tty);

    /* Error Handling */
    if ( tcgetattr ( fd, &tty ) != 0 ) {
       //qDebug() << "Error " << errno << " from tcgetattr: " << strerror(errno) << std::endl;
        return -2;

    }

    /* Save old tty parameters */
    tty_old = tty;

    /* Set Baud Rate */
    if(devid==1){//rfid
        cfsetospeed (&tty, (speed_t)B9600);
        cfsetispeed (&tty, (speed_t)B9600);
        qDebug()<<"fd is : "<< fd<<" with this baud rate: 9600";
    }
    else{//fp
        cfsetospeed (&tty, (speed_t)B115200);
        cfsetispeed (&tty, (speed_t)B115200);
        qDebug()<<"fd is : "<< fd<<" with this baud rate: 115200";
    }

    /* Setting other Port Stuff */
    tty.c_cflag     &=  ~PARENB;            // Make 8n1
    tty.c_cflag     &=  ~CSTOPB;
    tty.c_cflag     &=  ~CSIZE;
    tty.c_cflag     |=  CS8;

    tty.c_cflag     &=  ~CRTSCTS;           // no flow control
    tty.c_cc[VMIN]   =  1;                  // read doesn't block
    tty.c_cc[VTIME]  =  5;                  // 0.5 seconds read timeout
    tty.c_cflag     |=  CREAD | CLOCAL;     // turn on READ & ignore ctrl lines

    /* Make raw */
    cfmakeraw(&tty);

    /* Flush Port, then applies attributes */
    tcflush( fd, TCIFLUSH );
    if ( tcsetattr ( fd, TCSANOW, &tty ) != 0) {
       //qDebug() << "Error " << errno << " from tcsetattr" << std::endl;
        return -3;
    }
    return 1;

}

///new code
/// *******************************************************
///
///
/// *******************************************************
void PortSerial::readData()
{
        buffer[0]=0;
        usleep(20000);
        int res = read(fd,buffer,2048);
        if(res <=0)
            qDebug() << strerror(errno) ;
        if(res >0)
        {
            buffer[res]=0;
//            batemp = QByteArray((char*)buffer, res);
            batemp.append(QByteArray((char*)buffer, res));
//            emit readyread(ba,devid);
//            qDebug()<<"_____READ________\n"<<ba.toHex()<<"\n";
        }
}


void PortSerial::ifExist()
{
    int c=0;
    while(1){
        //set timeout for wait
        tv.tv_sec = 0;
        tv.tv_usec = 1000;
        FD_ZERO(&readfs);
        FD_SET(fd, &readfs);
        n=select(fd+1, &readfs, NULL, NULL, &tv /* no timeout */);
        if(n==1)
        {
            qDebug("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@reading");
           readData();
        }
        else
        {
            if(batemp.length()>0){
           qDebug()<<"batemp len is:"<<batemp.length();
               emit readyread(batemp,devid);
               qDebug()<<"\n________________________READ byte_____________________________\n"<<batemp.toHex()
                      <<"\nnon hex is: "<<batemp<<"\n";
               batemp.clear();
        }
        }
    }
}
///new code
/// *******************************************************
///
///
/// *******************************************************
//------------------------------------
void PortSerial::writeData(QByteArray ba)
{
    int res=write(fd,ba,ba.length());
    qDebug()<<"port write : "/*<<ba.toHex()*/<<"*******   res is : "<<res;

}

When I give this serial port: /dev/ttyS0 to this, First read Null (0a03 in hex) and then just read this:

root@NanoPi-NEO:~# ./FPConsole -qws
Enter tty:/dev/ttyS0
fd is :  7  with this baud rate: 9600
fd is :  8  with this baud rate: 9600
connected
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@reading
batemp len is: 2

________________________READ byte_____________________________
 "0a03"
non hex is:  "
"

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@reading
Resource temporarily unavailable

How Can I solve this?To read the exact RFID card data and read it more than once without resource temporarily unavailable .

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
H.Ghassami
  • 1,012
  • 2
  • 21
  • 42
  • Close the port and reopen? I don't think you can reread data without doing that. – john Jul 26 '18 at 09:04
  • @john, So why did it read NULL for the first time? – H.Ghassami Jul 26 '18 at 09:06
  • 1
    Why do not you use QSerialPort? – eyllanesc Jul 26 '18 at 09:52
  • 1
    You're getting *"resource temporarily unavailable"* because you insist on using nonblocking mode. So use blocking mode. Whatever *"solutions"* you read you seem to have got backwards. – sawdust Jul 26 '18 at 18:05
  • @eyllanesc: because QSerialPort Since Qt 5.1 and I should use Qt4.8.6. – H.Ghassami Jul 28 '18 at 04:56
  • @sawdust: I want to read RFID card whenever the users put their cards. I think I should use a nonblocking mood. But I don't get what you said at last? – H.Ghassami Jul 28 '18 at 04:59
  • @H.Ghassami It seems QtSerialPort supports Qt4. https://wiki.qt.io/Qt_Serial_Port#Building_and_Installing – HeyYO Jul 28 '18 at 06:28
  • *"I think I should use a nonblocking mood [sic]."* -- You're making a choice without understanding what each mode does. Non-blocking non-canonical mode is a degenerate configuration. Study https://stackoverflow.com/questions/25996171/linux-blocking-vs-non-blocking-serial-read/26006680#26006680 – sawdust Jul 28 '18 at 21:05

0 Answers0