Skip to content

Commit 4cae03d

Browse files
committed
qt: write operation moved to thread due to low performance of event loop
1 parent 0aaadb9 commit 4cae03d

File tree

3 files changed

+35
-405
lines changed

3 files changed

+35
-405
lines changed

qt/programmer.cpp

Lines changed: 23 additions & 294 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Programmer::~Programmer()
2626
disconnect();
2727
}
2828

29-
int Programmer::connect()
29+
int Programmer::serialPortConnect()
3030
{
3131
serialPort.setPortName(CDC_DEV_NAME);
3232
serialPort.setBaudRate(SERIAL_PORT_SPEED);
@@ -38,15 +38,27 @@ int Programmer::connect()
3838
return -1;
3939
}
4040

41+
return 0;
42+
}
43+
44+
void Programmer::serialPortDisconnect()
45+
{
46+
serialPort.close();
47+
}
48+
49+
int Programmer::connect()
50+
{
51+
if (serialPortConnect())
52+
return -1;
53+
4154
isConn = true;
4255

4356
return 0;
4457
}
4558

4659
void Programmer::disconnect()
4760
{
48-
serialPort.close();
49-
61+
serialPortDisconnect();
5062
isConn = false;
5163
}
5264

@@ -307,306 +319,23 @@ void Programmer::readChip(std::function<void(int)> callback, uint8_t *buf,
307319
this, std::placeholders::_1), &writeData);
308320
}
309321

310-
void Programmer::readRespWriteEndChipCb(int status)
322+
void Programmer::writeCb(int ret)
311323
{
312-
RespHeader *header;
313-
int ret = -1;
314-
315-
if (status == SerialPortReader::READ_ERROR)
316-
goto Exit;
317-
318-
if (readRespHeader(&readData, 0, header))
319-
goto Exit;
320-
321-
switch (header->code)
322-
{
323-
case RESP_STATUS:
324-
if (header->info != STATUS_OK)
325-
{
326-
qCritical() << "Programmer error: failed to handle write end "
327-
"chip command";
328-
}
329-
else
330-
ret = 0;
331-
break;
332-
default:
333-
handleWrongResp(header->code);
334-
break;
335-
}
336-
337-
Exit:
324+
QObject::disconnect(&writer, SIGNAL(result(int)), this, SLOT(writeCb(int)));
325+
serialPortConnect();
338326
writeChipCb(ret);
339327
}
340328

341-
int Programmer::handleWriteError(QByteArray *data)
342-
{
343-
RespHeader *header;
344-
345-
while (data->size())
346-
{
347-
if (readRespHeader(data, 0, header))
348-
return -1;
349-
switch (header->code)
350-
{
351-
case RESP_STATUS:
352-
if (header->info == STATUS_BAD_BLOCK)
353-
{
354-
if (!handleBadBlock(data, 0))
355-
{
356-
data->remove(0, sizeof(RespBadBlock));
357-
continue;
358-
}
359-
else
360-
return -1;
361-
}
362-
else
363-
{
364-
qCritical() << "Programmer error: failed to write chip";
365-
return -1;
366-
}
367-
break;
368-
default:
369-
handleWrongResp(header->code);
370-
return -1;
371-
}
372-
}
373-
374-
return 0;
375-
}
376-
377-
void Programmer::sendWriteCmdCb(int status)
378-
{
379-
isWriteInProgress = false;
380-
381-
if (isReadError)
382-
return;
383-
384-
if (status != SerialPortWriter::WRITE_OK)
385-
{
386-
serialPortReader->readCancel();
387-
writeChipCb(-1);
388-
return;
389-
}
390-
391-
if (writeSentBytes < writeAckBytes + writeAckBytesLim)
392-
sendWriteCmd();
393-
}
394-
395-
void Programmer::sendWriteCmd()
396-
{
397-
uint8_t cdcBuf[CDC_BUF_SIZE];
398-
uint32_t sendDataLen, txBufDataLen, ackLim;
399-
WriteEndCmd *writeEndCmd;
400-
WriteDataCmd *writeDataCmd;
401-
402-
if (isWriteInProgress)
403-
return;
404-
405-
txBufDataLen = sizeof(cdcBuf) - sizeof(WriteDataCmd);
406-
if (writeRemainingBytes)
407-
{
408-
isWriteInProgress = true;
409-
410-
sendDataLen = writeRemainingBytes < txBufDataLen ?
411-
writeRemainingBytes : txBufDataLen;
412-
ackLim = writeAckBytes + writeAckBytesLim;
413-
if (writeSentBytes + sendDataLen > ackLim)
414-
sendDataLen = ackLim - writeSentBytes;
415-
416-
writeDataCmd = (WriteDataCmd *)cdcBuf;
417-
writeDataCmd->cmd.code = CMD_NAND_WRITE_D;
418-
writeDataCmd->len = sendDataLen;
419-
memcpy(writeDataCmd->data, writeChipBuf + writeSentBytes, sendDataLen);
420-
writeSentBytes += sendDataLen;
421-
writeRemainingBytes -= sendDataLen;
422-
423-
writeData.clear();
424-
writeData.append((const char *)cdcBuf, sizeof(WriteDataCmd) + sendDataLen);
425-
serialPortWriter->write(std::bind(&Programmer::sendWriteCmdCb, this,
426-
std::placeholders::_1), &writeData);
427-
}
428-
else
429-
{
430-
writeEndCmd = (WriteEndCmd *)cdcBuf;
431-
writeEndCmd->cmd.code = CMD_NAND_WRITE_E;
432-
433-
readData.clear();
434-
serialPortReader->read(std::bind(&Programmer::readRespWriteEndChipCb,
435-
this, std::placeholders::_1), &readData, WRITE_TIMEOUT_MS,
436-
sizeof(RespHeader));
437-
438-
writeData.clear();
439-
writeData.append((const char *)cdcBuf, sizeof(WriteEndCmd));
440-
serialPortWriter->write(std::bind(&Programmer::sendCmdCb,
441-
this, std::placeholders::_1), &writeData);
442-
}
443-
}
444-
445-
int Programmer::handleWriteAck(QByteArray *data)
446-
{
447-
RespWriteAck *header;
448-
449-
if (data->size() < (int)sizeof(RespWriteAck))
450-
{
451-
qCritical() << "Programmer error: write acknowledge is not full";
452-
return -1;
453-
}
454-
455-
header = (RespWriteAck *)data->data();
456-
if (!header->ackBytes || header->ackBytes > writeLen)
457-
{
458-
qCritical() << "Programmer error: acknowledged " << header->ackBytes
459-
<< " bytes";
460-
return -1;
461-
}
462-
463-
writeAckBytes = header->ackBytes;
464-
465-
data->clear();
466-
serialPortReader->read(std::bind(&Programmer::readRespWriteChipCb,
467-
this, std::placeholders::_1), data, WRITE_TIMEOUT_MS,
468-
sizeof(RespHeader));
469-
470-
if (writeSentBytes < writeAckBytes + writeAckBytesLim)
471-
sendWriteCmd();
472-
473-
return 0;
474-
}
475-
476-
void Programmer::readRespWriteChipCb(int status)
477-
{
478-
RespHeader *header;
479-
480-
if (status != SerialPortReader::READ_OK)
481-
goto Error;
482-
483-
while (readData.size())
484-
{
485-
if (readRespHeader(&readData, 0, header))
486-
goto Error;
487-
488-
switch (header->code)
489-
{
490-
case RESP_STATUS:
491-
switch(header->info)
492-
{
493-
case STATUS_WRITE_ACK:
494-
if (!handleWriteAck(&readData))
495-
readData.remove(0, sizeof(RespWriteAck));
496-
else
497-
goto Error;
498-
break;
499-
case STATUS_BAD_BLOCK:
500-
if (!handleBadBlock(&readData, 0))
501-
readData.remove(0, sizeof(RespBadBlock));
502-
else
503-
goto Error;
504-
break;
505-
case STATUS_ERROR:
506-
qCritical() << "Programmer error: failed to write chip";
507-
goto Error;
508-
default:
509-
handleStatus(header);
510-
goto Error;
511-
}
512-
}
513-
}
514-
515-
return;
516-
517-
Error:
518-
readData.clear();
519-
isReadError = 1;
520-
writeChipCb(-1);
521-
522-
}
523-
524-
void Programmer::readRespWriteStartChipCb(int status)
525-
{
526-
RespHeader *header;
527-
528-
if (status != SerialPortReader::READ_OK)
529-
goto Error;
530-
531-
if (readRespHeader(&readData, 0, header))
532-
goto Error;
533-
534-
switch (header->code)
535-
{
536-
case RESP_STATUS:
537-
switch (header->info)
538-
{
539-
case STATUS_OK:
540-
break;
541-
default:
542-
qCritical() << "Programmer error: failed to handle write start "
543-
"command";
544-
goto Error;
545-
}
546-
break;
547-
default:
548-
handleWrongResp(header->code);
549-
goto Error;
550-
}
551-
552-
isReadError = 0;
553-
readData.clear();
554-
serialPortReader->read(std::bind(&Programmer::readRespWriteChipCb,
555-
this, std::placeholders::_1), &readData, WRITE_TIMEOUT_MS,
556-
sizeof(RespHeader));
557-
558-
isWriteInProgress = false;
559-
560-
if (!serialPortWriter->isPending())
561-
sendWriteCmd();
562-
else
563-
schedWrite = true;
564-
return;
565-
566-
Error:
567-
writeChipCb(-1);
568-
}
569-
570-
void Programmer::sendWriteStartCmdCb(int status)
571-
{
572-
if (status != SerialPortWriter::WRITE_OK)
573-
{
574-
serialPortReader->readCancel();
575-
writeChipCb(-1);
576-
return;
577-
}
578-
579-
if (schedWrite)
580-
sendWriteCmd();
581-
}
582-
583329
void Programmer::writeChip(std::function<void(int)> callback, uint8_t *buf,
584330
uint32_t addr, uint32_t len, uint32_t pageSize)
585331
{
586-
WriteStartCmd writeStartCmd;
587-
588-
schedWrite = false;
589-
590-
readData.clear();
591-
serialPortReader->read(std::bind(&Programmer::readRespWriteStartChipCb,
592-
this, std::placeholders::_1), &readData, WRITE_TIMEOUT_MS,
593-
sizeof(RespHeader));
594-
595-
writeStartCmd.cmd.code = CMD_NAND_WRITE_S;
596-
writeStartCmd.addr = addr;
597-
598-
writeSentBytes = 0;
599-
writeChipBuf = buf;
600-
writeRemainingBytes = len;
601-
writeLen = len;
602332
writeChipCb = callback;
603-
writeAckBytes = 0;
604-
writeAckBytesLim = pageSize;
605-
writeData.clear();
606-
writeData.append((const char *)&writeStartCmd, sizeof(writeStartCmd));
333+
QObject::connect(&writer, SIGNAL(result(int)), this, SLOT(writeCb(int)));
607334

608-
serialPortWriter->write(std::bind(&Programmer::sendWriteStartCmdCb,
609-
this, std::placeholders::_1), &writeData);
335+
/* Serial port object cannot be used in other thread */
336+
serialPortDisconnect();
337+
writer.init(CDC_DEV_NAME, SERIAL_PORT_SPEED, buf, addr, len, pageSize);
338+
writer.start();
610339
}
611340

612341
void Programmer::readRespSelectChipCb(int status)

0 commit comments

Comments
 (0)