Skip to content

Commit ed19d34

Browse files
committed
Use async API for serial port write
1 parent 7f803c9 commit ed19d34

File tree

2 files changed

+83
-75
lines changed

2 files changed

+83
-75
lines changed

qt/writer.cpp

Lines changed: 67 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@
1010
#include <QTextCursor>
1111

1212
#define READ_ACK_TIMEOUT 5000
13-
#define BUF_SIZE 64
14-
15-
Q_DECLARE_METATYPE(QtMsgType)
1613

1714
void Writer::init(const QString &portName, qint32 baudRate, uint8_t *buf,
1815
uint32_t addr, uint32_t len, uint32_t pageSize, bool skipBB, bool incSpare,
@@ -31,9 +28,10 @@ void Writer::init(const QString &portName, qint32 baudRate, uint8_t *buf,
3128
this->endCmd = endCmd;
3229
bytesWritten = 0;
3330
bytesAcked = 0;
31+
offset = 0;
3432
}
3533

36-
int Writer::write(uint8_t *data, uint32_t dataLen)
34+
int Writer::write(char *data, uint32_t dataLen)
3735
{
3836
qint64 ret;
3937

@@ -50,25 +48,18 @@ int Writer::write(uint8_t *data, uint32_t dataLen)
5048
return 0;
5149
}
5250

53-
int Writer::read(uint8_t *data, uint32_t dataLen)
51+
int Writer::read(char *data, uint32_t dataLen)
5452
{
55-
qint64 ret;
56-
57-
//TODO: handle timeout
58-
// if (!serialPort->waitForReadyRead(READ_ACK_TIMEOUT))
59-
// {
60-
// logErr("Write ACK was not received");
61-
// return -1;
62-
// }
53+
std::function<void(int)> cb = std::bind(&Writer::readCb, this,
54+
std::placeholders::_1);
6355

64-
ret = serialPort->read(reinterpret_cast<char *>(data), dataLen);
65-
if (ret < 0)
56+
if (serialPort->asyncReadWithTimeout(data, dataLen, cb, READ_ACK_TIMEOUT)
57+
< 0)
6658
{
67-
logErr("Failed to read ACK");
6859
return -1;
6960
}
7061

71-
return static_cast<int>(ret);
62+
return 0;
7263
}
7364

7465
int Writer::handleWriteAck(RespHeader *header, uint32_t len)
@@ -125,7 +116,7 @@ int Writer::handleError(RespHeader *header, uint32_t len)
125116
return -1;
126117
}
127118

128-
int Writer::handleStatus(uint8_t *pbuf, uint32_t len)
119+
int Writer::handleStatus(char *pbuf, uint32_t len)
129120
{
130121
RespHeader *header = reinterpret_cast<RespHeader *>(pbuf);
131122
uint8_t status = header->info;
@@ -148,7 +139,7 @@ int Writer::handleStatus(uint8_t *pbuf, uint32_t len)
148139
return -1;
149140
}
150141

151-
int Writer::handlePacket(uint8_t *pbuf, uint32_t len)
142+
int Writer::handlePacket(char *pbuf, uint32_t len)
152143
{
153144
RespHeader *header = reinterpret_cast<RespHeader *>(pbuf);
154145

@@ -165,7 +156,7 @@ int Writer::handlePacket(uint8_t *pbuf, uint32_t len)
165156
return handleStatus(pbuf, len);
166157
}
167158

168-
int Writer::handlePackets(uint8_t *pbuf, uint32_t len)
159+
int Writer::handlePackets(char *pbuf, uint32_t len)
169160
{
170161
int ret;
171162
uint32_t offset = 0;
@@ -188,26 +179,50 @@ int Writer::handlePackets(uint8_t *pbuf, uint32_t len)
188179
return static_cast<int>(len - offset);
189180
}
190181

191-
int Writer::readData()
182+
void Writer::readCb(int size)
192183
{
193-
uint8_t pbuf[BUF_SIZE];
194-
int len, offset = 0;
184+
if (size < 0)
185+
goto Error;
195186

196-
do
187+
size += offset;
188+
189+
if ((offset = handlePackets(pbuf, static_cast<uint32_t>(size))) < 0)
190+
goto Error;
191+
192+
if (offset)
193+
{
194+
if (read(pbuf + offset, bufSize - offset) < 0)
195+
goto Error;
196+
return;
197+
}
198+
199+
if (cmd == startCmd)
197200
{
198-
if ((len = read(pbuf + offset,
199-
static_cast<uint32_t>(BUF_SIZE - offset))) < 0)
201+
if (writeData())
202+
goto Error;
203+
}
204+
else if (cmd == dataCmd)
205+
{
206+
if (len)
200207
{
201-
return -1;
208+
if (writeData())
209+
goto Error;
202210
}
203-
len += offset;
204-
205-
if ((offset = handlePackets(pbuf, static_cast<uint32_t>(len))) < 0)
206-
return -1;
211+
else if (writeEnd())
212+
goto Error;
213+
}
214+
else if (cmd == endCmd)
215+
{
216+
emit result(0);
217+
goto Exit;
207218
}
208-
while (offset);
209219

210-
return 0;
220+
return;
221+
222+
Error:
223+
emit result(-1);
224+
Exit:
225+
serialPortDestroy();
211226
}
212227

213228
int Writer::writeStart()
@@ -219,28 +234,29 @@ int Writer::writeStart()
219234
writeStartCmd.len = len;
220235
writeStartCmd.flags.skipBB = skipBB;
221236
writeStartCmd.flags.incSpare = incSpare;
237+
cmd = startCmd;
222238

223-
if (write(reinterpret_cast<uint8_t *>(&writeStartCmd),
239+
if (write(reinterpret_cast<char *>(&writeStartCmd),
224240
sizeof(WriteStartCmd)))
225241
{
226242
return -1;
227243
}
228244

229-
if (readData())
245+
if (read(pbuf, bufSize))
230246
return -1;
231247

232248
return 0;
233249
}
234250

235251
int Writer::writeData()
236252
{
237-
uint8_t pbuf[BUF_SIZE];
238253
WriteDataCmd *writeDataCmd = reinterpret_cast<WriteDataCmd *>(pbuf);
239254
uint32_t dataLen, dataLenMax, headerLen, pageLim;
240255

241256
writeDataCmd->cmd.code = dataCmd;
242257
headerLen = sizeof(WriteDataCmd);
243-
dataLenMax = BUF_SIZE - headerLen;
258+
dataLenMax = bufSize - headerLen;
259+
cmd = dataCmd;
244260

245261
while (len)
246262
{
@@ -258,13 +274,13 @@ int Writer::writeData()
258274
bytesWritten += dataLen;
259275
len -= dataLen;
260276

261-
if (len && bytesWritten != pageLim)
262-
continue;
263-
264-
if (readData())
265-
return -1;
277+
if (!len || bytesWritten == pageLim)
278+
break;
266279
}
267280

281+
if (read(pbuf, bufSize))
282+
return -1;
283+
268284
return 0;
269285
}
270286

@@ -273,11 +289,12 @@ int Writer::writeEnd()
273289
WriteEndCmd writeEndCmd;
274290

275291
writeEndCmd.cmd.code = endCmd;
292+
cmd = endCmd;
276293

277-
if (write(reinterpret_cast<uint8_t *>(&writeEndCmd), sizeof(WriteEndCmd)))
294+
if (write(reinterpret_cast<char *>(&writeEndCmd), sizeof(WriteEndCmd)))
278295
return -1;
279296

280-
if (readData())
297+
if (read(pbuf, bufSize))
281298
return -1;
282299

283300
return 0;
@@ -287,16 +304,8 @@ int Writer::serialPortCreate()
287304
{
288305
serialPort = new SerialPort();
289306

290-
291-
//TODO: Handle error
292-
// if (!serialPort->open(QIODevice::ReadWrite))
293-
// {
294-
// logErr(QString("Failed to open serial port: %1")
295-
// .arg(serialPort->errorString()));
296-
// return -1;
297-
// }
298-
299-
serialPort->start(portName.toLatin1(), baudRate);
307+
if (!serialPort->start(portName.toLatin1(), baudRate))
308+
return -1;
300309

301310
return 0;
302311
}
@@ -307,27 +316,19 @@ void Writer::serialPortDestroy()
307316
free(serialPort);
308317
}
309318

310-
void Writer::run()
319+
void Writer::start()
311320
{
312-
int ret = -1;
313-
314-
/* Required for logger */
315-
qRegisterMetaType<QtMsgType>();
316-
317321
if (serialPortCreate())
318322
goto Exit;
319323

320324
if (writeStart())
321325
goto Exit;
322-
if (writeData())
323-
goto Exit;
324-
if (writeEnd())
325-
goto Exit;
326326

327-
ret = 0;
327+
return;
328+
328329
Exit:
329330
serialPortDestroy();
330-
emit result(ret);
331+
emit result(-1);
331332
}
332333

333334
void Writer::logErr(const QString& msg)

qt/writer.h

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@
88

99
#include "cmd.h"
1010
#include "serial_port.h"
11-
#include <QThread>
11+
#include <QObject>
1212

13-
class Writer : public QThread
13+
class Writer : public QObject
1414
{
1515
Q_OBJECT
16+
17+
static const uint32_t bufSize = 64;
18+
1619
SerialPort *serialPort;
1720
QString portName;
1821
qint32 baudRate;
@@ -27,22 +30,24 @@ class Writer : public QThread
2730
uint8_t startCmd;
2831
uint8_t dataCmd;
2932
uint8_t endCmd;
33+
char pbuf[bufSize];
34+
int offset;
35+
uint8_t cmd;
3036

31-
int write(uint8_t *data, uint32_t dataLen);
32-
int read(uint8_t *data, uint32_t dataLen);
37+
int write(char *data, uint32_t dataLen);
38+
int read(char *data, uint32_t dataLen);
39+
void readCb(int size);
3340
int handleWriteAck(RespHeader *header, uint32_t len);
3441
int handleBadBlock(RespHeader *header, uint32_t len, bool isSkipped);
3542
int handleError(RespHeader *header, uint32_t len);
36-
int handleStatus(uint8_t *pbuf, uint32_t len);
37-
int handlePacket(uint8_t *pbuf, uint32_t len);
38-
int handlePackets(uint8_t *pbuf, uint32_t len);
39-
int readData();
43+
int handleStatus(char *pbuf, uint32_t len);
44+
int handlePacket(char *pbuf, uint32_t len);
45+
int handlePackets(char *pbuf, uint32_t len);
4046
int writeStart();
4147
int writeData();
4248
int writeEnd();
4349
int serialPortCreate();
4450
void serialPortDestroy();
45-
void run() override;
4651
void logErr(const QString& msg);
4752
void logInfo(const QString& msg);
4853

@@ -51,6 +56,8 @@ class Writer : public QThread
5156
uint32_t addr, uint32_t len, uint32_t pageSize,
5257
bool skipBB, bool incSpare, uint8_t startCmd, uint8_t dataCmd,
5358
uint8_t endCmd);
59+
void start();
60+
5461
signals:
5562
void result(int ret);
5663
void progress(unsigned int progress);

0 commit comments

Comments
 (0)