diff --git a/tests/manual/trk/adapter.cpp b/tests/manual/trk/adapter.cpp index 2e0e3788bd7d868b9ab78474a0b6af650cb62895..0f28ad8f0128743909f132e93e9c41e46be7b805 100644 --- a/tests/manual/trk/adapter.cpp +++ b/tests/manual/trk/adapter.cpp @@ -127,9 +127,10 @@ static inline void dumpRegister(int n, uint value, QByteArray &a) } struct AdapterOptions { - AdapterOptions() : verbose(1),registerEndianness(LittleEndian),useSocket(false) {} + AdapterOptions() : verbose(1),serialFrame(true),registerEndianness(LittleEndian),useSocket(false) {} int verbose; + bool serialFrame; Endianness registerEndianness; bool useSocket; QString gdbServer; @@ -148,6 +149,7 @@ public: void setGdbServerName(const QString &name); void setTrkServerName(const QString &name) { m_trkServerName = name; } void setVerbose(int verbose) { m_verbose = verbose; } + void setSerialFrame(bool b) { m_serialFrame = b; } void setRegisterEndianness(Endianness r) { m_registerEndianness = r; } void setUseSocket(bool s) { m_useSocket = s; } bool startServer(); @@ -261,6 +263,7 @@ private: int m_verbose; Endianness m_registerEndianness; bool m_useSocket; + bool m_serialFrame; bool m_startInferiorTriggered; }; @@ -277,6 +280,7 @@ Adapter::Adapter() : m_verbose(1), m_registerEndianness(LittleEndian), m_useSocket(false), + m_serialFrame(true), m_startInferiorTriggered(false) { startTimer(100); @@ -1012,7 +1016,7 @@ void Adapter::tryTrkWrite() void Adapter::trkWrite(const TrkMessage &msg) { - QByteArray ba = frameMessage(msg.code, msg.token, msg.data); + QByteArray ba = frameMessage(msg.code, msg.token, msg.data, m_serialFrame); m_writtenTrkMessages.insert(msg.token, msg); m_trkWriteBusy = true; @@ -1071,7 +1075,7 @@ void Adapter::tryTrkRead() } while (!m_trkReadQueue.isEmpty()) - handleResult(extractResult(&m_trkReadQueue)); + handleResult(extractResult(&m_trkReadQueue, m_serialFrame)); m_trkWriteBusy = false; } @@ -1612,6 +1616,8 @@ static bool readAdapterArgs(const QStringList &args, AdapterOptions *o) o->registerEndianness = BigEndian; } else if (*it == QLatin1String("-s")) { o->useSocket = true; + } else if (*it == QLatin1String("-f")) { + o->serialFrame = false; } } else { switch (argNumber++) { @@ -1639,6 +1645,7 @@ int main(int argc, char *argv[]) if (!readAdapterArgs(app.arguments(), &options)) { qDebug("Usage: %s [-v|-q] [-s][-l] <trk com/trkservername> <gdbserverport>\n" "Options: -v verbose\n" + " -f Turn serial message frame off\n" " -q quiet\n" " -s Use socket (simulation)\n" " -b Set register endianness to big\n", argv[0]); @@ -1651,6 +1658,7 @@ int main(int argc, char *argv[]) adapter.setVerbose(options.verbose); adapter.setRegisterEndianness(options.registerEndianness); adapter.setUseSocket(options.useSocket); + adapter.setSerialFrame(options.serialFrame); if (adapter.startServer()) return app.exec(); return 4; diff --git a/tests/manual/trk/launcher.cpp b/tests/manual/trk/launcher.cpp index a7268e40e5c7dd5e479acec25f817cc289a865e9..389548fd05378e567fe17ccabf38f6c007395fe0 100644 --- a/tests/manual/trk/launcher.cpp +++ b/tests/manual/trk/launcher.cpp @@ -42,6 +42,9 @@ #else # include <stdio.h> # include <sys/ioctl.h> +# include <termios.h> +# include <errno.h> +# include <string.h> #endif #ifdef Q_OS_WIN @@ -125,6 +128,7 @@ struct LauncherPrivate { QString m_copySrcFileName; QString m_copyDstFileName; QString m_installFileName; + bool m_serialFrame; int m_verbose; }; @@ -135,6 +139,7 @@ LauncherPrivate::LauncherPrivate() : m_trkWriteToken(0), m_trkWriteBusy(false), m_timerId(-1), + m_serialFrame(true), m_verbose(0) { } @@ -173,6 +178,11 @@ void Launcher::setInstallFileName(const QString &name) d->m_installFileName = name; } +void Launcher::setSerialFrame(bool b) +{ + d->m_serialFrame = b; +} + bool Launcher::startServer(QString *errorMessage) { if (d->m_verbose) { @@ -239,6 +249,27 @@ bool Launcher::openTrkPort(const QString &port, QString *errorMessage) *errorMessage = QString::fromLatin1("Cannot open %1: %2").arg(port, d->m_file.errorString()); return false; } + + struct termios termInfo; + if (tcgetattr(d->m_file.handle(), &termInfo) < 0) { + *errorMessage = QString::fromLatin1("Unable to retrieve terminal settings: %1 %2").arg(errno).arg(QString::fromAscii(strerror(errno))); + return false; + } + // Turn off terminal echo as not get messages back, among other things + termInfo.c_cflag|=CREAD|CLOCAL; + termInfo.c_lflag&=(~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|ISIG)); + termInfo.c_iflag&=(~(INPCK|IGNPAR|PARMRK|ISTRIP|ICRNL|IXANY)); + termInfo.c_oflag&=(~OPOST); + termInfo.c_cc[VMIN]=0; + termInfo.c_cc[VINTR] = _POSIX_VDISABLE; + termInfo.c_cc[VQUIT] = _POSIX_VDISABLE; + termInfo.c_cc[VSTART] = _POSIX_VDISABLE; + termInfo.c_cc[VSTOP] = _POSIX_VDISABLE; + termInfo.c_cc[VSUSP] = _POSIX_VDISABLE; + if (tcsetattr(d->m_file.handle(), TCSAFLUSH, &termInfo) < 0) { + *errorMessage = QString::fromLatin1("Unable to apply terminal settings: %1 %2").arg(errno).arg(QString::fromAscii(strerror(errno))); + return false; + } return true; #endif } @@ -324,7 +355,7 @@ void Launcher::tryTrkWrite() void Launcher::trkWrite(const TrkMessage &msg) { - QByteArray ba = frameMessage(msg.code, msg.token, msg.data); + QByteArray ba = frameMessage(msg.code, msg.token, msg.data, d->m_serialFrame); d->m_writtenTrkMessages.insert(msg.token, msg); d->m_trkWriteBusy = true; @@ -364,10 +395,11 @@ void Launcher::tryTrkRead() while (TryReadFile(d->m_hdevice, buffer, BUFFERSIZE, &charsRead, NULL)) { d->m_trkReadQueue.append(buffer, charsRead); - if (isValidTrkResult(d->m_trkReadQueue)) + if (isValidTrkResult(d->m_trkReadQueue, d->m_serialFrame)) break; } - if (!isValidTrkResult(d->m_trkReadQueue)) { + const ushort len = isValidTrkResult(d->m_trkReadQueue, d->m_serialFrame); + if (!len) { logMessage("Partial message: " + stringFromArray(d->m_trkReadQueue)); return; } @@ -377,7 +409,8 @@ void Launcher::tryTrkRead() return; const QByteArray data = d->m_file.read(size); d->m_trkReadQueue.append(data); - if (!isValidTrkResult(d->m_trkReadQueue)) { + const ushort len = isValidTrkResult(d->m_trkReadQueue, d->m_serialFrame); + if (!len) { if (d->m_trkReadQueue.size() > 10) { logMessage(QString::fromLatin1("Unable to extract message from '%1' '%2'"). arg(QLatin1String(d->m_trkReadQueue.toHex())).arg(QString::fromAscii(d->m_trkReadQueue))); @@ -385,8 +418,8 @@ void Launcher::tryTrkRead() return; } #endif // Q_OS_WIN - logMessage("READ: " + stringFromArray(d->m_trkReadQueue)); - handleResult(extractResult(&d->m_trkReadQueue)); + logMessage(QString::fromLatin1("READ: %1 bytes %2").arg(len).arg(stringFromArray(d->m_trkReadQueue))); + handleResult(extractResult(&d->m_trkReadQueue, d->m_serialFrame)); d->m_trkWriteBusy = false; } diff --git a/tests/manual/trk/launcher.h b/tests/manual/trk/launcher.h index ad56bfe83127f6bdb7f22527396cc0d8ce9092c2..27af42425e1958c9498aa7456d31d299638f1de8 100644 --- a/tests/manual/trk/launcher.h +++ b/tests/manual/trk/launcher.h @@ -51,7 +51,8 @@ public: void setCopyFileName(const QString &srcName, const QString &dstName); void setInstallFileName(const QString &name); bool startServer(QString *errorMessage); - void setVerbose(int v); + void setVerbose(int v); + void setSerialFrame(bool b); signals: void copyingStarted(); diff --git a/tests/manual/trk/main_launcher.cpp b/tests/manual/trk/main_launcher.cpp index 537617ea3c1f566b3fa864875039621307937dd0..e4900feb01bb38f76f2e0da1f984df1fcc932f5a 100644 --- a/tests/manual/trk/main_launcher.cpp +++ b/tests/manual/trk/main_launcher.cpp @@ -6,7 +6,8 @@ static const char *usageC = "\nUsage: %1 <trk_port_name> [-v] [-i remote_sis_file | -I local_sis_file remote_sis_file] <remote_executable_name>\n" -"\nOptions:\n -v verbose\n\n" +"\nOptions:\n -v verbose\n" + " -f turn serial message frame off\n\n" "\nPing:\n" "%1 COM5\n" "\nRemote launch:\n" @@ -40,6 +41,9 @@ static bool parseArguments(const QStringList &arguments, trk::Launcher &launcher case 'v': verbosity++; break; + case 'f': + launcher.setSerialFrame(false); + break;verbosity++; case 'i': install = true; break; diff --git a/tests/manual/trk/trkserver.cpp b/tests/manual/trk/trkserver.cpp index 5ffbc5f706e2657712b40fd9532cd2a7ce5d0acf..e764562c3c9d3e41c4ba8044e9cce176f6909402 100644 --- a/tests/manual/trk/trkserver.cpp +++ b/tests/manual/trk/trkserver.cpp @@ -52,9 +52,10 @@ void signalHandler(int) using namespace trk; struct TrkOptions { - TrkOptions() : verbose(1) {} + TrkOptions() : verbose(1), serialFrame(true) {} int verbose; + bool serialFrame; QString serverName; QString dumpName; QStringList additionalDumps; @@ -191,6 +192,7 @@ public: void setServerName(const QString &name) { m_serverName = name; } void setMemoryDumpName(const QString &source) { m_memoryDumpName = source; } void setVerbose(int v) { m_verbose = v; } + void setSerialFrame(bool b) { m_serialFrame = b; } bool readDump(const QString &fn); bool startServer(); @@ -218,12 +220,15 @@ private: Inferior m_inferior; byte m_notificationToken; int m_verbose; + bool m_serialFrame; }; -TrkServer::TrkServer() : m_verbose(1) +TrkServer::TrkServer() : + m_adapterConnection(0), + m_notificationToken(0), + m_verbose(1), + m_serialFrame(true) { - m_adapterConnection = 0; - m_notificationToken = 0; } TrkServer::~TrkServer() @@ -294,12 +299,12 @@ void TrkServer::readFromAdapter() logMessage("buffer: " + stringFromArray(m_adapterReadBuffer)); while (!m_adapterReadBuffer.isEmpty()) - handleAdapterMessage(extractResult(&m_adapterReadBuffer)); + handleAdapterMessage(extractResult(&m_adapterReadBuffer, m_serialFrame)); } void TrkServer::writeToAdapter(byte command, byte token, const QByteArray &data) { - QByteArray msg = frameMessage(command, token, data); + QByteArray msg = frameMessage(command, token, data, m_serialFrame); logMessage("trk: <- " + stringFromArray(msg)); m_adapterConnection->write(msg); } @@ -450,7 +455,10 @@ static bool readTrkArgs(const QStringList &args, TrkOptions *o) o->verbose++; } else if (*it == QLatin1String("-q")) { o->verbose = 0; + } else if (*it == QLatin1String("-f")) { + o->serialFrame= false; } + } else { switch (argNumber++) { case 0: @@ -479,6 +487,7 @@ int main(int argc, char *argv[]) if (!readTrkArgs(app.arguments(), &options)) { qWarning("Usage: %s [-v|-q] <trkservername> <replaysource> [additional dumps]\n" "Options: -v verbose\n" + " -f Turn serial message frame off\n" " -q quiet\n" " Additional dump names must follow the naming convention '0x4AD.bin", argv[0]); return 1; @@ -487,6 +496,7 @@ int main(int argc, char *argv[]) TrkServer server; server.setServerName(options.serverName); server.setMemoryDumpName(options.dumpName); + server.setSerialFrame(options.serialFrame); foreach(const QString &ad, options.additionalDumps) if (!server.readDump(ad)) return -1; diff --git a/tests/manual/trk/trkutils.cpp b/tests/manual/trk/trkutils.cpp index daec6e30a678468e24eebcca43d0a9e2d7af8d9f..1709cf31b3c5ed2dcf2c9e4900114f849c34658d 100644 --- a/tests/manual/trk/trkutils.cpp +++ b/tests/manual/trk/trkutils.cpp @@ -43,6 +43,13 @@ QByteArray hexNumber(uint n, int digits) return QByteArray(digits - ba.size(), '0') + ba; } +TrkResult::TrkResult() : + code(0), + token(0), + isDebugOutput(false) +{ +} + QString TrkResult::toString() const { QString res = stringFromByte(code) + "[" + stringFromByte(token); @@ -50,7 +57,7 @@ QString TrkResult::toString() const return res + "] " + stringFromArray(data); } -QByteArray frameMessage(byte command, byte token, const QByteArray &data) +QByteArray frameMessage(byte command, byte token, const QByteArray &data, bool serialFrame) { byte s = command + token; for (int i = 0; i != data.size(); ++i) @@ -66,13 +73,15 @@ QByteArray frameMessage(byte command, byte token, const QByteArray &data) response.append(char(checksum)); QByteArray encodedData = encode7d(response); - ushort encodedSize = encodedData.size() + 2; // 2 x 0x7e QByteArray ba; - ba.append(char(0x01)); - ba.append(char(0x90)); - ba.append(char(encodedSize / 256)); - ba.append(char(encodedSize % 256)); + if (serialFrame) { + ba.append(char(0x01)); + ba.append(char(0x90)); + const ushort encodedSize = encodedData.size() + 2; // 2 x 0x7e + ba.append(char(encodedSize / 256)); + ba.append(char(encodedSize % 256)); + } ba.append(char(0x7e)); ba.append(encodedData); ba.append(char(0x7e)); @@ -82,38 +91,48 @@ QByteArray frameMessage(byte command, byte token, const QByteArray &data) /* returns 0 if array doesn't represent a result, otherwise returns the length of the result data */ -ushort isValidTrkResult(const QByteArray &buffer) +ushort isValidTrkResult(const QByteArray &buffer, bool serialFrame) { - if (buffer.length() < 4) - return 0; - if (buffer.at(0) != 0x01 || byte(buffer.at(1)) != 0x90) - return 0; - ushort len = extractShort(buffer.data() + 2); - - if (buffer.size() < len + 4) { - return 0; + if (serialFrame) { + // Serial protocol with length info + if (buffer.length() < 4) + return 0; + if (buffer.at(0) != 0x01 || byte(buffer.at(1)) != 0x90) + return 0; + const ushort len = extractShort(buffer.data() + 2); + return (buffer.size() >= len + 4) ? len : ushort(0); + } + // Frameless protocol without length info + const char delimiter = char(0x7e); + const int firstDelimiterPos = buffer.indexOf(delimiter); + // Regular message delimited by 0x7e..0x7e + if (firstDelimiterPos == 0) { + const int endPos = buffer.indexOf(delimiter, firstDelimiterPos + 1); + return endPos != -1 ? endPos + 1 - firstDelimiterPos : 0; } - return len; + // Some ASCII log message up to first delimiter or all + return firstDelimiterPos != -1 ? firstDelimiterPos : buffer.size(); } -TrkResult extractResult(QByteArray *buffer) +TrkResult extractResult(QByteArray *buffer, bool serialFrame) { TrkResult result; - ushort len = isValidTrkResult(*buffer); + const ushort len = isValidTrkResult(*buffer, serialFrame); if (!len) return result; // handle receiving application output, which is not a regular command - if (buffer->at(4) != 0x7e) { + const int delimiterPos = serialFrame ? 4 : 0; + if (buffer->at(delimiterPos) != 0x7e) { result.isDebugOutput = true; - result.data = buffer->mid(4, len); + result.data = buffer->mid(delimiterPos, len); result.data.replace("\r\n", "\n"); - *buffer = buffer->mid(4 + len); + *buffer->remove(0, delimiterPos + len); return result; } // FIXME: what happens if the length contains 0xfe? // Assume for now that it passes unencoded! - QByteArray data = decode7d(buffer->mid(5, len - 2)); - *buffer->remove(0, 4 + len); + const QByteArray data = decode7d(buffer->mid(delimiterPos + 1, len - 2)); + *buffer->remove(0, delimiterPos + len); byte sum = 0; for (int i = 0; i < data.size(); ++i) // 3 = 2 * 0xfe + sum diff --git a/tests/manual/trk/trkutils.h b/tests/manual/trk/trkutils.h index cba53689556efd5acc67859dffd6286bd04091b4..ce5baa79d4c773dbdcff555aa7f84c6af4d922a0 100644 --- a/tests/manual/trk/trkutils.h +++ b/tests/manual/trk/trkutils.h @@ -171,7 +171,7 @@ struct Breakpoint struct TrkResult { - TrkResult() { code = token = 0; isDebugOutput = false; } + TrkResult(); QString toString() const; // 0 for no error. int errorCode() const; @@ -183,10 +183,11 @@ struct TrkResult bool isDebugOutput; }; -// returns a QByteArray containing 0x01 0x90 <len> 0x7e encoded7d(ba) 0x7e -QByteArray frameMessage(byte command, byte token, const QByteArray &data); -ushort isValidTrkResult(const QByteArray &buffer); -TrkResult extractResult(QByteArray *buffer); +// returns a QByteArray containing optionally +// the serial frame [0x01 0x90 <len>] and 0x7e encoded7d(ba) 0x7e +QByteArray frameMessage(byte command, byte token, const QByteArray &data, bool serialFrame); +ushort isValidTrkResult(const QByteArray &buffer, bool serialFrame); +TrkResult extractResult(QByteArray *buffer, bool serialFrame); QByteArray errorMessage(byte code); QByteArray hexNumber(uint n, int digits = 0); uint swapEndian(uint in);