Skip to content

Commit 269cbd1

Browse files
committed
Sync reader and writer with UI thread
1 parent 88550dc commit 269cbd1

File tree

10 files changed

+133
-41
lines changed

10 files changed

+133
-41
lines changed

qt/main_window.cpp

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ void MainWindow::initBufTable()
5353
void MainWindow::resetBufTable()
5454
{
5555
bufferTableModel.setFile(ui->filePathLineEdit->text());
56-
buffer.clear();
56+
buffer.buf.clear();
5757
}
5858

5959
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
@@ -264,7 +264,10 @@ void MainWindow::slotProgReadCompleted(int readBytes)
264264
return;
265265
}
266266

267-
workFile.write((const char *)buffer.constData(), buffer.size());
267+
buffer.mutex.lock();
268+
workFile.write((const char *)buffer.buf.data(), buffer.buf.size());
269+
buffer.buf.clear();
270+
buffer.mutex.unlock();
268271

269272
if (readBytes != workFile.size())
270273
{
@@ -289,8 +292,10 @@ void MainWindow::slotProgReadProgress(unsigned int progress)
289292
progressPercent = progress * 100ULL / readSize;
290293
setProgress(progressPercent);
291294

292-
workFile.write((const char *)buffer.constData(), buffer.size());
293-
buffer.clear();
295+
buffer.mutex.lock();
296+
workFile.write((const char *)buffer.buf.data(), buffer.buf.size());
297+
buffer.buf.clear();
298+
buffer.mutex.unlock();
294299
}
295300

296301
void MainWindow::slotProgRead()
@@ -331,7 +336,7 @@ void MainWindow::slotProgRead()
331336

332337
workFile.resize(0);
333338
resetBufTable();
334-
buffer.clear();
339+
buffer.buf.clear();
335340

336341
qInfo() << "Reading data ...";
337342
setProgress(0);
@@ -371,13 +376,26 @@ void MainWindow::slotProgWriteProgress(unsigned int progress)
371376
progressPercent = progress * 100ULL / progSize;
372377
setProgress(progressPercent);
373378

374-
uint32_t dataSize = workFile.read((char *)buffer.data(), pageSize);
379+
std::unique_lock<std::mutex> lck(buffer.mutex);
375380

376-
if (dataSize < pageSize)
381+
qint64 readSize = workFile.read((char *)buffer.buf.data(), pageSize);
382+
if (readSize < 0)
377383
{
378-
uint32_t tail = pageSize - dataSize;
379-
memset(buffer.end() - tail, 0xFF, tail);
384+
qCritical() << "Failed to read file";
385+
return;
386+
}
387+
else if (readSize == 0)
388+
{
389+
return;
380390
}
391+
else if (readSize < pageSize)
392+
{
393+
std::fill(buffer.buf.begin() + readSize, buffer.buf.end(), 0xFF);
394+
}
395+
396+
// Notify writer that new data is ready
397+
buffer.ready = true;
398+
buffer.cv.notify_one();
381399
}
382400

383401
void MainWindow::slotProgWrite()
@@ -432,8 +450,25 @@ void MainWindow::slotProgWrite()
432450
ui->filePathLineEdit->setDisabled(true);
433451
ui->selectFilePushButton->setDisabled(true);
434452

435-
buffer.reserve(pageSize);
436-
buffer.resize(workFile.read((char *)buffer.data(), pageSize));
453+
buffer.buf.reserve(pageSize);
454+
buffer.buf.resize(pageSize);
455+
qint64 readSize = workFile.read((char *)buffer.buf.data(), (qint64)pageSize);
456+
if (readSize < 0)
457+
{
458+
qCritical() << "Failed to read file";
459+
return;
460+
}
461+
else if (readSize == 0)
462+
{
463+
qInfo() << "File is empty";
464+
return;
465+
}
466+
else if (readSize < pageSize)
467+
{
468+
std::fill(buffer.buf.begin() + readSize, buffer.buf.end(), 0xFF);
469+
}
470+
471+
buffer.ready = true;
437472
prog->writeChip(&buffer, START_ADDRESS, progSize, pageSize);
438473
}
439474

qt/main_window.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class MainWindow : public QMainWindow
2929

3030
private:
3131
Ui::MainWindow *ui;
32-
QVector<uint8_t> buffer;
32+
SyncBuffer buffer;
3333
BufferTableModel bufferTableModel;
3434
ChipId chipId;
3535
ParallelChipDb parallelChipDb;

qt/programmer.cpp

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ void Programmer::connectCb(int ret)
5656
QObject::disconnect(&reader, SIGNAL(result(int)), this,
5757
SLOT(connectCb(int)));
5858

59-
memcpy(&fwVersion, buf.constData(), sizeof(fwVersion));
59+
memcpy(&fwVersion, buffer.buf.data(), sizeof(fwVersion));
6060

6161
if (ret < 0)
6262
{
@@ -86,9 +86,9 @@ int Programmer::connect()
8686

8787
writeData.clear();
8888
writeData.append(reinterpret_cast<const char *>(&cmd), sizeof(cmd));
89-
buf.clear();
89+
buffer.buf.clear();
9090
reader.init(usbDevName, SERIAL_PORT_SPEED,
91-
&buf, sizeof(fwVersion),
91+
&buffer, sizeof(fwVersion),
9292
reinterpret_cast<const uint8_t *>(writeData.constData()),
9393
static_cast<uint32_t>(writeData.size()), false, false);
9494
reader.start();
@@ -152,7 +152,7 @@ void Programmer::readChipIdCb(int ret)
152152
QObject::disconnect(&reader, SIGNAL(result(int)), this,
153153
SLOT(readChipIdCb(int)));
154154

155-
memcpy(chipId_p, buf.constData(), sizeof(ChipId));
155+
memcpy(chipId_p, buffer.buf.data(), sizeof(ChipId));
156156

157157
emit readChipIdCompleted(ret);
158158
}
@@ -171,9 +171,9 @@ void Programmer::readChipId(ChipId *chipId)
171171

172172
chipId_p = chipId;
173173

174-
buf.clear();
174+
buffer.buf.clear();
175175
reader.init(usbDevName, SERIAL_PORT_SPEED,
176-
&buf, sizeof(ChipId),
176+
&buffer, sizeof(ChipId),
177177
reinterpret_cast<const uint8_t *>(writeData.constData()),
178178
static_cast<uint32_t>(writeData.size()), false, false);
179179
reader.start();
@@ -232,7 +232,7 @@ void Programmer::readProgressCb(unsigned int progress)
232232
emit readChipProgress(progress);
233233
}
234234

235-
void Programmer::readChip(QVector<uint8_t> *buf, uint32_t addr, uint32_t len,
235+
void Programmer::readChip(SyncBuffer *buf, uint32_t addr, uint32_t len,
236236
bool isReadLess)
237237
{
238238
ReadCmd readCmd;
@@ -270,7 +270,7 @@ void Programmer::writeProgressCb(unsigned int progress)
270270
emit writeChipProgress(progress);
271271
}
272272

273-
void Programmer::writeChip(QVector<uint8_t> *buf, uint32_t addr, uint32_t len,
273+
void Programmer::writeChip(SyncBuffer *buf, uint32_t addr, uint32_t len,
274274
uint32_t pageSize)
275275
{
276276
QObject::connect(&writer, SIGNAL(result(int)), this, SLOT(writeCb(int)));
@@ -402,15 +402,15 @@ int Programmer::firmwareImageRead()
402402
FIRMWARE_IMAGE_1;
403403
updateImageSize = firmwareImage[updateImage].size;
404404
updateImageOffset = firmwareImage[updateImage].offset;
405-
buf.resize(updateImageSize);
405+
firmwareBuffer.resize(updateImageSize);
406406

407407
if (!file.seek(updateImageOffset))
408408
{
409409
qCritical() << "Failed to seek firmware image " << firmwareFileName;
410410
goto Error;
411411
}
412412

413-
if ((ret = file.read((char *)buf.data(), updateImageSize)) < 0)
413+
if ((ret = file.read((char *)firmwareBuffer.data(), updateImageSize)) < 0)
414414
{
415415
qCritical() << "Failed to read firmware image " << firmwareFileName <<
416416
", error:" << file.errorString();
@@ -427,7 +427,7 @@ int Programmer::firmwareImageRead()
427427
return 0;
428428

429429
Error:
430-
buf.clear();
430+
firmwareBuffer.clear();
431431
emit firmwareUpdateCompleted(-1);
432432
return -1;
433433
}
@@ -436,6 +436,12 @@ void Programmer::firmwareUpdateProgressCb(unsigned int progress)
436436
{
437437
emit firmwareUpdateProgress(progress * 100ULL /
438438
firmwareImage[updateImage].size);
439+
440+
std::copy(firmwareBuffer.begin() + progress, firmwareBuffer.begin() +
441+
progress + flashPageSize, buffer.buf.begin());
442+
// Notify writer that new data is ready
443+
buffer.ready = true;
444+
buffer.cv.notify_one();
439445
}
440446

441447
void Programmer::firmwareUpdateCb(int ret)
@@ -446,7 +452,8 @@ void Programmer::firmwareUpdateCb(int ret)
446452
QObject::disconnect(&writer, SIGNAL(result(int)), this,
447453
SLOT(firmwareUpdateCb(int)));
448454

449-
buf.clear();
455+
buffer.buf.clear();
456+
firmwareBuffer.clear();
450457

451458
emit firmwareUpdateCompleted(ret);
452459
}
@@ -464,8 +471,13 @@ void Programmer::firmwareUpdateStart()
464471
QObject::connect(&writer, SIGNAL(progress(unsigned int)), this,
465472
SLOT(firmwareUpdateProgressCb(unsigned int)));
466473

474+
buffer.buf.reserve(flashPageSize);
475+
buffer.buf.resize(flashPageSize);
476+
std::copy(firmwareBuffer.begin(), firmwareBuffer.begin() + flashPageSize,
477+
buffer.buf.begin());
478+
buffer.ready = true;
467479
writer.init(usbDevName, SERIAL_PORT_SPEED,
468-
&buf,
480+
&buffer,
469481
firmwareImage[updateImage].address, firmwareImage[updateImage].size,
470482
flashPageSize, 0, 0, 0, CMD_FW_UPDATE_S, CMD_FW_UPDATE_D,
471483
CMD_FW_UPDATE_E);
@@ -478,7 +490,7 @@ void Programmer::getActiveImageCb(int ret)
478490
QObject::disconnect(&reader, SIGNAL(result(int)), this,
479491
SLOT(getActiveImageCb(int)));
480492

481-
activeImage = buf[0];
493+
activeImage = buffer.buf.at(0);
482494

483495
if (ret < 0)
484496
{
@@ -516,8 +528,8 @@ void Programmer::firmwareUpdate(const QString &fileName)
516528
writeData.clear();
517529
writeData.append(reinterpret_cast<const char *>(&cmd), sizeof(cmd));
518530

519-
buf.clear();
520-
reader.init(usbDevName, SERIAL_PORT_SPEED, &buf,
531+
buffer.buf.clear();
532+
reader.init(usbDevName, SERIAL_PORT_SPEED, &buffer,
521533
sizeof(activeImage),
522534
reinterpret_cast<const uint8_t *>(writeData.constData()),
523535
static_cast<uint32_t>(writeData.size()), false, false);

qt/programmer.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ class Programmer : public QObject
5656
uint8_t activeImage;
5757
uint8_t updateImage;
5858
QString firmwareFileName;
59-
QVector<uint8_t> buf;
59+
QByteArray firmwareBuffer;
60+
SyncBuffer buffer;
6061
ChipId *chipId_p;
6162

6263
int serialPortConnect();
@@ -82,8 +83,8 @@ class Programmer : public QObject
8283
void setHwEccEnabled(bool isHwEccEnabled);
8384
void readChipId(ChipId *chipId);
8485
void eraseChip(uint32_t addr, uint32_t len);
85-
void readChip(QVector<uint8_t> *buf, uint32_t addr, uint32_t len, bool isReadLess);
86-
void writeChip(QVector<uint8_t> *buf, uint32_t addr, uint32_t len,
86+
void readChip(SyncBuffer *buf, uint32_t addr, uint32_t len, bool isReadLess);
87+
void writeChip(SyncBuffer *buf, uint32_t addr, uint32_t len,
8788
uint32_t pageSize);
8889
void readChipBadBlocks();
8990
void confChip(ChipInfo *chipInfo);

qt/qt.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ HEADERS += main_window.h \
6363
spi_chip_db_dialog.h \
6464
spi_chip_db_table_model.h \
6565
spi_chip_info.h \
66+
sync_buffer.h \
6667
writer.h \
6768
reader.h \
6869
settings_programmer_dialog.h \

qt/reader.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Reader::~Reader()
2121
stop();
2222
}
2323

24-
void Reader::init(const QString &portName, qint32 baudRate, QVector<uint8_t> *rbuf,
24+
void Reader::init(const QString &portName, qint32 baudRate, SyncBuffer *rbuf,
2525
uint32_t rlen, const uint8_t *wbuf, uint32_t wlen, bool isSkipBB,
2626
bool isReadLess)
2727
{
@@ -162,9 +162,10 @@ int Reader::handleData(char *pbuf, uint32_t len)
162162
return -1;
163163
}
164164

165-
QVector<uint8_t>tmp(dataSize);
166-
memcpy(tmp.data(), data, dataSize);
167-
rbuf->append(tmp);
165+
rbuf->mutex.lock();
166+
rbuf->buf.insert(rbuf->buf.end(), data, data + dataSize);
167+
rbuf->mutex.unlock();
168+
168169
readOffset += dataSize;
169170
bytesRead += dataSize;
170171

qt/reader.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#define READER_H
88

99
#include <QObject>
10+
#include "sync_buffer.h"
1011
#include "serial_port.h"
1112

1213
class Reader : public QObject
@@ -18,7 +19,7 @@ class Reader : public QObject
1819
SerialPort *serialPort = nullptr;
1920
QString portName;
2021
qint32 baudRate;
21-
QVector<uint8_t> *rbuf;
22+
SyncBuffer *rbuf;
2223
uint32_t rlen;
2324
const uint8_t *wbuf;
2425
uint32_t wlen;
@@ -49,7 +50,7 @@ class Reader : public QObject
4950
explicit Reader();
5051
~Reader();
5152

52-
void init(const QString &portName, qint32 baudRate, QVector<uint8_t> *rbuf,
53+
void init(const QString &portName, qint32 baudRate, SyncBuffer *rbuf,
5354
uint32_t rlen, const uint8_t *wbuf, uint32_t wlen, bool isSkipBB,
5455
bool isReadLess);
5556
void start();

qt/sync_buffer.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/* Copyright (C) 2020 NANDO authors
2+
* This program is free software; you can redistribute it and/or modify
3+
* it under the terms of the GNU General Public License version 3.
4+
*/
5+
6+
#ifndef SYNC_BUFFER_H
7+
#define SYNC_BUFFER_H
8+
9+
#include <mutex>
10+
#include <vector>
11+
#include <condition_variable>
12+
13+
typedef struct
14+
{
15+
std::vector<uint8_t> buf;
16+
std::mutex mutex;
17+
std::condition_variable cv;
18+
bool ready;
19+
} SyncBuffer;
20+
21+
#endif // SYNC_BUFFER_H

0 commit comments

Comments
 (0)