Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QSerialPort on Linux with high baudrate
Forum Updated to NodeBB v4.3 + New Features

QSerialPort on Linux with high baudrate

Scheduled Pinned Locked Moved Unsolved General and Desktop
14 Posts 5 Posters 2.0k 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.
  • T Texture

    @aha_1980 Thank you for answer, I understand that whole data can be received partially. So in my code I am waiting till inner buffer has necessary size:

    if (_serialPort->bytesAvailable() == _bytesToRead) {
       answer = _serialPort->readAll();
       ...
    }
    

    Signal readyRead() is called several times, collecting new 64 bytes at once. I expect to receive 7392 bytes, but only 7352 bytes comes.

    aha_1980A Offline
    aha_1980A Offline
    aha_1980
    Lifetime Qt Champion
    wrote on last edited by
    #4

    @kuzulis, do you have an idea here?

    May there be some internal buffer overrunning (as we are soon at the 8kB border)?

    Thanks

    Qt has to stay free or it will die.

    1 Reply Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #5

      @aha_1980 said in QSerialPort on Linux with high baudrate:

      May there be some internal buffer overrunning

      To be sure I would read out the data into an own buffer

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      T 1 Reply Last reply
      1
      • T Texture

        @aha_1980 Thank you for answer, I understand that whole data can be received partially. So in my code I am waiting till inner buffer has necessary size:

        if (_serialPort->bytesAvailable() == _bytesToRead) {
           answer = _serialPort->readAll();
           ...
        }
        

        Signal readyRead() is called several times, collecting new 64 bytes at once. I expect to receive 7392 bytes, but only 7352 bytes comes.

        aha_1980A Offline
        aha_1980A Offline
        aha_1980
        Lifetime Qt Champion
        wrote on last edited by
        #6

        Hi @Texture,

        I thought about this problem again. Can you create a dump of the received data on both systems and compare it?

        So at least we know if the missing chars are at the start, middle or end.

        Regards

        Qt has to stay free or it will die.

        T 1 Reply Last reply
        0
        • Christian EhrlicherC Christian Ehrlicher

          @aha_1980 said in QSerialPort on Linux with high baudrate:

          May there be some internal buffer overrunning

          To be sure I would read out the data into an own buffer

          T Offline
          T Offline
          Texture
          wrote on last edited by
          #7

          @Christian-Ehrlicher I have tried this approach and have the same issue. Every time when readyRead() is catched, I save information to my external buffer and continue. Nothing changes.

          1 Reply Last reply
          0
          • aha_1980A aha_1980

            Hi @Texture,

            I thought about this problem again. Can you create a dump of the received data on both systems and compare it?

            So at least we know if the missing chars are at the start, middle or end.

            Regards

            T Offline
            T Offline
            Texture
            wrote on last edited by
            #8

            @aha_1980 I have tried to look through data as you proposed and what I could say: the whole package comes (I have special CRC in the end and test increasing uint16_t numbers as data so I could identify the real end), but bytes partially lost somewhere in the middle. I have tested several times and first bytes disappearance occurs at byte #64.

            aha_1980A JonBJ 2 Replies Last reply
            0
            • T Texture

              @aha_1980 I have tried to look through data as you proposed and what I could say: the whole package comes (I have special CRC in the end and test increasing uint16_t numbers as data so I could identify the real end), but bytes partially lost somewhere in the middle. I have tested several times and first bytes disappearance occurs at byte #64.

              aha_1980A Offline
              aha_1980A Offline
              aha_1980
              Lifetime Qt Champion
              wrote on last edited by
              #9

              Hi @Texture,

              very strange behavior!

              Well, next thing would be to find out the source of the problem. It may be anywhere from

              1. Hardware
              2. Linux Kernel (driver)
              3. Qt Serial Port
              4. Your program

              What comes to my mind is, that most PC's traditionally use "odd" baud rates: 1200, 9600, 57600, 115200 and so on. Even modern USB-serial adapters often use these baudrates or multiples of that.

              So may it be your device cannot be set to exactly 500000 baud? How is the USB implemented on the device side? With an external chip like FTDI FT232R or similar? Or as software stack within the controller?

              To exclude possible bugs within QtSerialPort, you'd have to write a receive example in pure POSIX code yourself. I have not done that for ages, so no example at hand. But you can find many of them in the internet.

              Regards

              Qt has to stay free or it will die.

              T 1 Reply Last reply
              2
              • T Texture

                @aha_1980 I have tried to look through data as you proposed and what I could say: the whole package comes (I have special CRC in the end and test increasing uint16_t numbers as data so I could identify the real end), but bytes partially lost somewhere in the middle. I have tested several times and first bytes disappearance occurs at byte #64.

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #10

                @Texture

                • You don't slot onto the QSerialPort::errorOccurred signal, you should check in case the missing bytes are being reported as such!

                • It's only a few(-ish) lines to test with C/OS level [_]open() & [_]read() lines to count up how many bytes you receive with the least possible code overhead. If that does not keep up with the baud rate, Qt won't!

                • You could also run your program under Linux strace. From that you could discover what bytes the port is actually sending/receiving, in case that differs from what your reader code sees.

                • I don't know about external devices, but is it possible that it's the serial device which cannot keep up with the baud rate? Or the Linux driver, or could it need hardware flow control?

                T 1 Reply Last reply
                0
                • aha_1980A aha_1980

                  Hi @Texture,

                  very strange behavior!

                  Well, next thing would be to find out the source of the problem. It may be anywhere from

                  1. Hardware
                  2. Linux Kernel (driver)
                  3. Qt Serial Port
                  4. Your program

                  What comes to my mind is, that most PC's traditionally use "odd" baud rates: 1200, 9600, 57600, 115200 and so on. Even modern USB-serial adapters often use these baudrates or multiples of that.

                  So may it be your device cannot be set to exactly 500000 baud? How is the USB implemented on the device side? With an external chip like FTDI FT232R or similar? Or as software stack within the controller?

                  To exclude possible bugs within QtSerialPort, you'd have to write a receive example in pure POSIX code yourself. I have not done that for ages, so no example at hand. But you can find many of them in the internet.

                  Regards

                  T Offline
                  T Offline
                  Texture
                  wrote on last edited by
                  #11

                  @aha_1980 Thank you for your suggestions!
                  The same device perfectly works with the same code running on windows machine. I had some experiments today and force my device send fixed array. In this case my Linux program could catch every byte. Looks like external device has not so good timings, but why Windows case works without any issue?

                  External device is STM32 connected with PC via uart with FTDI converter (as well as I've tested with CH340).

                  I will try to check with pure POSIX code.

                  1 Reply Last reply
                  0
                  • JonBJ JonB

                    @Texture

                    • You don't slot onto the QSerialPort::errorOccurred signal, you should check in case the missing bytes are being reported as such!

                    • It's only a few(-ish) lines to test with C/OS level [_]open() & [_]read() lines to count up how many bytes you receive with the least possible code overhead. If that does not keep up with the baud rate, Qt won't!

                    • You could also run your program under Linux strace. From that you could discover what bytes the port is actually sending/receiving, in case that differs from what your reader code sees.

                    • I don't know about external devices, but is it possible that it's the serial device which cannot keep up with the baud rate? Or the Linux driver, or could it need hardware flow control?

                    T Offline
                    T Offline
                    Texture
                    wrote on last edited by
                    #12

                    @JonB Thank you for the answer.

                    I have connected with errorOccurred() slot, but it has no messages/signals while receiving the bytes.

                    External device is STM32 connected with PC via uart with FTDI converter (as well as I've tested with CH340) and it perfectly works with this baudrate with the same code on Windows machine. I will give a try to check bytes with strace.

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

                      So,

                      1. do you use FTDI && CH340 as a serial converters in both OS's ?
                      2. had you checked it in a simple console application?

                      I'm ask, because earlier we too faced with a troubles with the serial port communications on Linux. But in our case we used iMX53 boad with in-bound serial port (not USB). A problem was in a driver of that port in Linux: there are was allocated a small FIFO size, which are overrunned on a high speed (we got an overrun errors). But, switching. e.g. to the USB serial converters solved a problems (in our case)...

                      So, it is strange.

                      I have tested several times and first bytes disappearance occurs at byte #64.

                      It looks like an overrun errors. You can try to look on an overrun errors, like this: https://askubuntu.com/questions/459392/read-serial-error-counters-from-shell (but, I'm not sure).

                      Maybe, you can try to put your worker class to the other thread and give a high priority to a thread.
                      Maybe, you can try to update a linux kernel... or try other Linux distro...

                      T 1 Reply Last reply
                      0
                      • K kuzulis

                        So,

                        1. do you use FTDI && CH340 as a serial converters in both OS's ?
                        2. had you checked it in a simple console application?

                        I'm ask, because earlier we too faced with a troubles with the serial port communications on Linux. But in our case we used iMX53 boad with in-bound serial port (not USB). A problem was in a driver of that port in Linux: there are was allocated a small FIFO size, which are overrunned on a high speed (we got an overrun errors). But, switching. e.g. to the USB serial converters solved a problems (in our case)...

                        So, it is strange.

                        I have tested several times and first bytes disappearance occurs at byte #64.

                        It looks like an overrun errors. You can try to look on an overrun errors, like this: https://askubuntu.com/questions/459392/read-serial-error-counters-from-shell (but, I'm not sure).

                        Maybe, you can try to put your worker class to the other thread and give a high priority to a thread.
                        Maybe, you can try to update a linux kernel... or try other Linux distro...

                        T Offline
                        T Offline
                        Texture
                        wrote on last edited by Texture
                        #14

                        @kuzulis

                        Thank you for your reply. I have spent a time to get some experiment results before answering. Some answers and notices are below:

                        • As external device for testing I have STM32F4 Discovery and its UART connected with PC via CH340 serial converter.
                        • First simple case (500k baudrate) is perfectly working on Linux with CuteCom terminal emulator (unfortunately, it doesn't support 1kk baudrate).
                        • I have created pure simple console application with two approaches (singleton and dynamic QSerialPort handler classes), everything is working well with 500k and 1kk baudrate.
                        • I have tried to put my serial port handler class to other thread in my program, but nothing changed.
                        • Very weird and not obvious effect for me: if I programmatically generate answer array in STM32 (e.g. fill in for-loop with for indexes), my program is working without any problem. If I use ADC in STM32 to fill my array (as it supposed for my embedded device) I get issues described above.
                        • UPD: I have tested the following case: my array is generated by STM32 with using not only indexes, but function (sin(), cos() or rand()). In this case even CuteCom can not receive the whole package. As far I understand it is also based on Qt5 and QSerialPort.

                        I am so confused with so many factors that affect on serial port reading and don't know, what should I try to fix at first...

                        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