Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. QSerialPort: delayed signal on new received bytes
QtWS25 Last Chance

QSerialPort: delayed signal on new received bytes

Scheduled Pinned Locked Moved Mobile and Embedded
15 Posts 2 Posters 7.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    kuzulis
    Qt Champions 2020
    wrote on last edited by
    #4

    bq. How would I increase priority in this case?

    Move the QSerialPort to separate QThread and set "thread priority": http://qt-project.org/doc/qt-4.8/qthread.html#setPriority.

    bq. As far as I can tell, this already is the best setting.

    Quite possibly that these 0/0 remained from QSerialPort. You can re-start your board and try do run the stty (before use of QSerialPort), to see an default VMIN/VTIME. So, you can change VMIN/VTIME as you want.

    bq. Sorry, I’m not sure what you mean exactly.

    I mean: do not use of heavy QtSerialPort && Qt on an applications which required precise time for communications (I/O) issues. E.g. use the pure C/C++ code && others lite GUI toolkits.. :)

    1 Reply Last reply
    0
    • McLionM Offline
      McLionM Offline
      McLion
      wrote on last edited by
      #5

      [quote author="kuzulis" date="1405088316"]
      Move the QSerialPort to separate QThread and set "thread priority": http://qt-project.org/doc/qt-4.8/qthread.html#setPriority.

      [/quote]

      Sounds like quite some piece of work since I have no experience with QThread .. never used before.

      Thanks

      1 Reply Last reply
      0
      • McLionM Offline
        McLionM Offline
        McLion
        wrote on last edited by
        #6

        What I don't get is the difference between QextSerialPort and QSerialPort. since they both rely on the native Linux IO functions (AFAIK, wrapped by QIO device) how comes they have such a huge difference in emitting the readyRead signal?

        I am not really sure putting the serial port in a seperate thread is the best solution. It is also recommended "Best Practice" to not put it in a separate thread for asynchronous communication. When I see that QextSerialPort does not have this delay and emits the readyRead like immediately, I strongly feel that something with the QSerialPort code is wrong.

        1 Reply Last reply
        0
        • K Offline
          K Offline
          kuzulis
          Qt Champions 2020
          wrote on last edited by
          #7

          bq. I strongly feel that something with the QSerialPort code is wrong.

          You can itself try to find a problem place. The main places (difference) at which I would to check, is:

          1. Try to add this code (from the QextSerialPort "sources":https://code.google.com/p/qextserialport/source/browse/src/qextserialport_unix.cpp ,line 86):

          @
          const long vdisable = ::fpathconf(fd, _PC_VDISABLE);
          currentTermios.c_cc[VINTR] = vdisable;
          currentTermios.c_cc[VQUIT] = vdisable;
          currentTermios.c_cc[VSTART] = vdisable;
          currentTermios.c_cc[VSTOP] = vdisable;
          currentTermios.c_cc[VSUSP] = vdisable;
          @

          at initialization of device.

          1. Try to change the QSocketNotifier's event handling from the direct events to the signal/slot. The QSerialPort override the QSocketNotifier::event() method, but the QextSerialPort use the QSocketNotifier::activated(int) signal.

          2. Maybe something excessively in QSerialPortPrivate::readNotification() method. Maybe is reasonable to simplify it up to:

          @
          // Always buffered, read data from the port into the read buffer
          qint64 newBytes = readBuffer.size();
          qint64 bytesToRead = policy == QSerialPort::IgnorePolicy ? ReadChunkSize : 1;

          if (readBufferMaxSize && bytesToRead > (readBufferMaxSize - readBuffer.size())) {
              bytesToRead = readBufferMaxSize - readBuffer.size();
              if (bytesToRead == 0) {
                  // Buffer is full. User must read data from the buffer
                  // before we can read more from the port.
                  return false;
              }
          }
          
          char *ptr = readBuffer.reserve(bytesToRead);
          const qint64 readBytes = readFromPort(ptr, bytesToRead);
          
          if (readBytes <= 0) {
              QSerialPort::SerialPortError error = decodeSystemError();
              if (error != QSerialPort::ResourceError)
                  error = QSerialPort::ReadError;
              else
                  setReadNotificationEnabled(false);
              q->setError(error);
              readBuffer.chop(bytesToRead);
              return false;
          }
          
          readBuffer.chop(bytesToRead - qMax(readBytes, qint64(0)));
          
          newBytes = readBuffer.size() - newBytes;
          
          // If read buffer is full, disable the read port notifier.
          if (readBufferMaxSize && readBuffer.size() == readBufferMaxSize)
              setReadNotificationEnabled(false);
          
          // only emit readyRead() when not recursing, and only if there is data available
          const bool hasData = newBytes > 0;
          
          if (!emittedReadyRead && hasData) {
              emittedReadyRead = true;
              emit q->readyRead();
              emittedReadyRead = false;
          }
          
          if (!hasData)
              setReadNotificationEnabled(true);
          

          @

          1 Reply Last reply
          0
          • McLionM Offline
            McLionM Offline
            McLion
            wrote on last edited by
            #8

            I'll read through that.
            One additional question: I assume it doesn't make a difference if I use
            @QByteArray read(qint64 maxSize)@

            instead of
            @virtual qint64 readData(char * data, qint64 maxSize)@

            to read out data, though readData seems to read from a ringbuffer and read reads from IODevice?

            1 Reply Last reply
            0
            • K Offline
              K Offline
              kuzulis
              Qt Champions 2020
              wrote on last edited by
              #9

              The readData(() it is protected method of QIODevice. You can't use it in your user code. The common chain is following: read() -> readData() -> read from ring buffer.

              The implementation of QSerialPort::readData() always read data from the internal ring buffer, but implementation of QextSerialPort try to read from the internal buffer + read directly from device.

              So, it make difference between read() and readData(). :)

              1 Reply Last reply
              0
              • McLionM Offline
                McLionM Offline
                McLion
                wrote on last edited by
                #10

                Arrgghh ... trying to modify code of QSerialPort as you suggested.
                Last week I could build successfully on Windows and Linux, now I crash even building on windows with a
                @DEVINST was not declared in this scope @

                1 Reply Last reply
                0
                • K Offline
                  K Offline
                  kuzulis
                  Qt Champions 2020
                  wrote on last edited by
                  #11

                  Try to replace the DEVINST by DWORD. Most likely your compiler do not contains the "cfgmgr32.h" file (or file has other place).

                  1 Reply Last reply
                  0
                  • McLionM Offline
                    McLionM Offline
                    McLion
                    wrote on last edited by
                    #12

                    Solved the DEVINST issue and added the termios settings. No change in the behaviour. There are only 3 diffs left from stty --a --F /dev/ttyS1 between QextSerialPort and QSerialPort. The following 3 option are deactivated (-) with QextSerialPort and activated with QSerialPort:
                    @ignpar
                    echoe
                    echok
                    @

                    and I don't think that this will make the difference. Now going to look into your further suggestions.

                    1 Reply Last reply
                    0
                    • McLionM Offline
                      McLionM Offline
                      McLion
                      wrote on last edited by
                      #13

                      Found that I have bytes dropping with QSerial as well. Seems to be some issue with underlying native linux or alike.
                      Coming back ...

                      1 Reply Last reply
                      0
                      • K Offline
                        K Offline
                        kuzulis
                        Qt Champions 2020
                        wrote on last edited by
                        #14

                        bq. Found that I have bytes dropping with QSerial as well.

                        There can't be.

                        Btw: this is an other issue not related with this thread.

                        1 Reply Last reply
                        0
                        • McLionM Offline
                          McLionM Offline
                          McLion
                          wrote on last edited by
                          #15

                          You're right, it's not exactly related to the topic of this thread.
                          I just wanted to update this thread with the fact that I am not further investigating the delayed readyRead as long as I have bytes dropping.
                          I actually implemented QSerial on my 4.6.3 because I thought that the bytes dropping was an issue of QextSerialPort. As it turns out, the issue is somewhere else (HW / underlying Linux).

                          1 Reply Last reply
                          0

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved