Tips to make QSerialPort task more optimal
-
Hey,
I am using QSearialPort to receive data from my embedded system at 1516800 baud rate, buffer size is 1936 bytes. Buffer is sent every 30 ms, (Sending whole buffer takes about 12 ms). Everything works with this set up, but my end result should be reading 10 channels, so I need to read 10 COMPORTS. I created a new thread for every serial port reading, so now I have 10 threads just for reading data and emitting signal to a parse slot, every thread signals same parser, because I need to log received data in a single .txt file. Inside each thread, read function waits for correct buffer length to be received: if less is received, it stores data in static buffer, if too much was received, it drops it and emits error GUI indication. On the embedded side, I have FTDI chips going to 10 ports of USB 3.0 hub with external power supply and this hub is connected to USB SS port. Everything seems to work correctly, I get no CRC errors, I receive data that I send, but sometimes, some tests tend to get a lot more those too big buffer errors, then others. I do these receive and log tests for 30 s and some work without errors, some get up to 70 errors on various channels. Maybe you can give me some tips to optimize my algorythm, so I would always receive correct amount? As I understood, QSerialPort doesn't just receive whole data, it receives it in chunks because of OS, my job is to buffer this data until correct amount is received, but as I said, sometimes it works flawless, but sometimes it just receives random lengths which causes errors. Everything is constant, because all devices are synced (with +/- 1% offset in their systick), so same buffe size, same baud rate, same send time.
Here is read code:void serialThread::serial_readData() { qsizetype data_size = 0; rs_485_tx_packet_t received_data = {0}; //get data data.append(serial->readAll()); if (data.size() < sizeof(rs_485_tx_packet_t)) { // qDebug() << "too short packed received: " << data.size(); return; } else if (data.size() > sizeof(rs_485_tx_packet_t)) { //save data size and pass it to debug data_size = data.size(); data.clear(); //call ui function emit signal_fault(data_size); return; } QByteArray packet = data.first(sizeof(rs_485_tx_packet_t)); emit signal_dataToParse(packet, serial_channel_number); data.clear(); }
-
Hi,
Rather than basing your logic on the data size, you should have a protocol that allows you to know when you have a full frame of data so you only drop stuff when you have an "end of frame" without a matching "start of frame".
Out of curiosity, why are you using a static buffer ? Or maybe, what do you mean by static buffer ?
-
I wonder if OP has done the math to determine the aggregate bandwidth needed to do "serial uart concentrator" over ten high speed UARTs and has made sure their equipment is beefy enough. I mean I don't care if they are multiplexing over a USB channel. UARTS are still an interrupt-per-char device. If anything, a USB wrapper adds more overhead. and flow control? what's that?