From 9ad63d83d8e0930faed2b40bd27c65eaed09ea58 Mon Sep 17 00:00:00 2001 From: Michael Carpenter Date: Mon, 12 May 2014 23:11:41 -0400 Subject: [PATCH] FreeEmsPlugin: Better handling of disconnect detection and reconnect syncing EMSTune will now pop up a display when it detects that it has connected to a device with differing non-readonly memory locations. It will also allow the user to either send local changes to the ECU,or accept ECU defaults as the current memory situation. The plugin will also notify the user when it has detected that the ECU has gone silent for more than 1500 milliseconds. This will be user configurable in the future once plugin-specific settings are supported. Added functionality to actually check if incoming data is different from what is stored in application memory and sendinga notification to the the user. This is a temp commit to trigger a test build and will be replaced with an actual commit containing a proper diff window of some sort of the data iTEmp --- core/core.pro | 9 +- core/src/mainwindow.cpp | 53 ++++++++++++ core/src/mainwindow.h | 10 +++ core/src/ramdiffwindow.cpp | 23 +++++ core/src/ramdiffwindow.h | 25 ++++++ core/src/ramdiffwindow.ui | 87 +++++++++++++++++++ lib/core/emscomms.h | 6 +- plugins/freeems/emsdata.cpp | 132 ++++++++++++++++++++++++++++- plugins/freeems/emsdata.h | 17 ++++ plugins/freeems/freeemscomms.cpp | 70 +++++++++++++-- plugins/freeems/freeemscomms.h | 11 ++- plugins/freeems/memorylocation.cpp | 28 ++++++ plugins/freeems/memorylocation.h | 4 + 13 files changed, 458 insertions(+), 17 deletions(-) create mode 100644 core/src/ramdiffwindow.cpp create mode 100644 core/src/ramdiffwindow.h create mode 100644 core/src/ramdiffwindow.ui diff --git a/core/core.pro b/core/core.pro index 3744519..b7bac94 100644 --- a/core/core.pro +++ b/core/core.pro @@ -122,7 +122,8 @@ SOURCES += src/main.cpp\ src/gaugeutil.cpp \ src/roundgaugeitem.cpp \ src/scalarparam.cpp \ - src/comboparam.cpp + src/comboparam.cpp \ + src/ramdiffwindow.cpp HEADERS += src/mainwindow.h \ @@ -172,7 +173,8 @@ HEADERS += src/mainwindow.h \ src/roundgaugeitem.h \ src/gaugeutil.h \ src/scalarparam.h \ - src/comboparam.h + src/comboparam.h \ + src/ramdiffwindow.h FORMS += src/mainwindow.ui \ src/comsettings.ui \ @@ -194,7 +196,8 @@ FORMS += src/mainwindow.ui \ src/firmwaremetadata.ui \ src/scalarparam.ui \ src/comboparam.ui \ - src/parameterwidget.ui + src/parameterwidget.ui \ + src/ramdiffwindow.ui SUBDIRS += plugins OTHER_FILES += \ README.md \ diff --git a/core/src/mainwindow.cpp b/core/src/mainwindow.cpp index d4bfca2..88a791f 100644 --- a/core/src/mainwindow.cpp +++ b/core/src/mainwindow.cpp @@ -49,8 +49,11 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) QLOG_INFO() << "Full hash:" << define2string(GIT_HASH); progressView=0; emsComms=0; + ramDiffWindow=0; m_interrogationInProgress = false; m_debugLogs = false; + emsSilenceTimer = new QTimer(this); + connect(emsSilenceTimer,SIGNAL(timeout()),this,SLOT(emsCommsSilenceTimerTick())); // emsData = new EmsData(); // connect(emsData,SIGNAL(updateRequired(unsigned short)),this,SLOT(updateDataWindows(unsigned short))); @@ -607,12 +610,33 @@ void MainWindow::emsCommsSilence() { //This is called when the ems has been silent for 5 seconds, when it was previously talking. QLOG_WARN() << "EMS HAS GONE SILENT"; + ui.statusLabel->setStyleSheet("background-color: rgb(255, 0, 0);"); + ui.statusLabel->setText("EMS SILENT"); + emsSilenceTimer->start(250); + QMessageBox::information(this,"Warning","ECU has gone silent. If this is unintentional, it may be a sign that something is wrong..."); + +} +void MainWindow::emsCommsSilenceTimerTick() +{ + if (m_emsSilenceLabelIsRed) + { + m_emsSilenceLabelIsRed = false; + ui.statusLabel->setStyleSheet("color: rgb(255, 255, 0);\nbackground-color: rgb(255, 85, 0);"); + } + else + { + m_emsSilenceLabelIsRed = true; + ui.statusLabel->setStyleSheet("color: rgb(255, 255, 0);\nbackground-color: rgb(255, 0, 0);"); + } } void MainWindow::emsCommsSilenceBroken() { //This is called when ems had previously been talking, gone silent, then started talking again. + ui.statusLabel->setText("Status Normal"); + emsSilenceTimer->stop(); QLOG_WARN() << "EMS HAS GONE NOISEY"; + ui.statusLabel->setStyleSheet(""); } void MainWindow::emsCommsDisconnected() @@ -623,6 +647,7 @@ void MainWindow::emsCommsDisconnected() ui.actionConnect->setEnabled(true); ui.actionDisconnect->setEnabled(false); m_offlineMode = true; + ui.statusLabel->setText("DISCONNECTED"); } void MainWindow::setPlugin(QString plugin) @@ -704,6 +729,8 @@ void MainWindow::setPlugin(QString plugin) connect(emsComms,SIGNAL(memoryDirty()),statusView,SLOT(setEmsMemoryDirty())); connect(emsComms,SIGNAL(memoryClean()),statusView,SLOT(setEmsMemoryClean())); connect(emsComms,SIGNAL(datalogDescriptor(QString)),this,SLOT(datalogDescriptor(QString))); + connect(emsComms,SIGNAL(ramLocationDirty(unsigned short)),this,SLOT(ramLocationDirty(unsigned short))); + connect(emsComms,SIGNAL(flashLocationDirty(unsigned short)),this,SLOT(flashLocationDirty(unsigned short))); emsComms->setBaud(m_comBaud); emsComms->setPort(m_comPort); emsComms->setLogsEnabled(m_saveLogs); @@ -1342,6 +1369,7 @@ void MainWindow::loadWizards(QString dir) void MainWindow::emsCommsConnected() { + ui.statusLabel->setText("Connected"); m_interrogationFailureCount = 0; ui.actionSave_Offline_Data->setEnabled(true); ui.actionLoad_Offline_Data->setEnabled(true); @@ -2121,3 +2149,28 @@ void MainWindow::datalogDescriptor(QString data) { Q_UNUSED(data) } +void MainWindow::ramLocationDirty(unsigned short locationid) +{ + if (!ramDiffWindow) + { + ramDiffWindow = new RamDiffWindow(); + connect(ramDiffWindow,SIGNAL(acceptLocalChanges()),this,SLOT(dirtyRamAcceptLocalChanges())); + connect(ramDiffWindow,SIGNAL(rejectLocalChanges()),this,SLOT(dirtyRamRejectLocalChanges())); + ramDiffWindow->show(); + } + ramDiffWindow->setDirtyLocation(locationid); + //QMessageBox::information(0,"Error","Ram location dirty 0x" + QString::number(locationid,16)); +} +void MainWindow::dirtyRamAcceptLocalChanges() +{ + emsComms->acceptLocalChanges(); +} +void MainWindow::dirtyRamRejectLocalChanges() +{ + emsComms->rejectLocalChanges(); +} + +void MainWindow::flashLocationDirty(unsigned short locationid) +{ + QMessageBox::information(0,"Error","Flash location dirty 0x" + QString::number(locationid,16)); +} diff --git a/core/src/mainwindow.h b/core/src/mainwindow.h index 42d8c0a..5375ab4 100644 --- a/core/src/mainwindow.h +++ b/core/src/mainwindow.h @@ -53,7 +53,9 @@ #include "serialportstatus.h" #include #include "parameterview.h" +#include "ramdiffwindow.h" #include "wizardview.h" + class RawDataBlock { public: @@ -129,6 +131,8 @@ class MainWindow : public QMainWindow QMdiSubWindow *packetStatusMdiWindow; QMdiSubWindow *aboutMdiWindow; QMdiSubWindow *emsStatusMdiWindow; + RamDiffWindow *ramDiffWindow; + QTimer *emsSilenceTimer; ParameterView *parameterView; QMdiSubWindow *parameterMdiWindow; @@ -137,6 +141,7 @@ class MainWindow : public QMainWindow void checkMessageCounters(int sequencenumber); DataPacketDecoder *dataPacketDecoder; void populateDataFields(); + bool m_emsSilenceLabelIsRed; Ui::MainWindow ui; QString m_pluginFileName; @@ -250,6 +255,11 @@ private slots: void emsMemoryDirty(); void emsMemoryClean(); void datalogDescriptor(QString data); + void ramLocationDirty(unsigned short locationid); + void flashLocationDirty(unsigned short locationid); + void dirtyRamAcceptLocalChanges(); + void dirtyRamRejectLocalChanges(); + void emsCommsSilenceTimerTick(); }; diff --git a/core/src/ramdiffwindow.cpp b/core/src/ramdiffwindow.cpp new file mode 100644 index 0000000..846f8a0 --- /dev/null +++ b/core/src/ramdiffwindow.cpp @@ -0,0 +1,23 @@ +#include "ramdiffwindow.h" +#include "ui_ramdiffwindow.h" + +RamDiffWindow::RamDiffWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::RamDiffWindow) +{ + ui->setupUi(this); + ui->tableWidget->setColumnCount(1); + ui->tableWidget->setColumnWidth(0,200); + connect(ui->pushLocalButton,SIGNAL(clicked()),this,SIGNAL(acceptLocalChanges())); + connect(ui->pullRemoteButton,SIGNAL(clicked()),this,SIGNAL(rejectLocalChanges())); +} + +RamDiffWindow::~RamDiffWindow() +{ + delete ui; +} +void RamDiffWindow::setDirtyLocation(unsigned short locationid) +{ + ui->tableWidget->setRowCount(ui->tableWidget->rowCount()+1); + ui->tableWidget->setItem(ui->tableWidget->rowCount()-1,0,new QTableWidgetItem(QString::number(locationid))); +} diff --git a/core/src/ramdiffwindow.h b/core/src/ramdiffwindow.h new file mode 100644 index 0000000..5fb0c9b --- /dev/null +++ b/core/src/ramdiffwindow.h @@ -0,0 +1,25 @@ +#ifndef RAMDIFFWINDOW_H +#define RAMDIFFWINDOW_H + +#include + +namespace Ui { +class RamDiffWindow; +} + +class RamDiffWindow : public QWidget +{ + Q_OBJECT + +public: + explicit RamDiffWindow(QWidget *parent = 0); + ~RamDiffWindow(); + void setDirtyLocation(unsigned short locationid); +private: + Ui::RamDiffWindow *ui; +signals: + void acceptLocalChanges(); + void rejectLocalChanges(); +}; + +#endif // RAMDIFFWINDOW_H diff --git a/core/src/ramdiffwindow.ui b/core/src/ramdiffwindow.ui new file mode 100644 index 0000000..e169ff5 --- /dev/null +++ b/core/src/ramdiffwindow.ui @@ -0,0 +1,87 @@ + + + RamDiffWindow + + + + 0 + 0 + 679 + 458 + + + + Form + + + + + + <h2>Warning</h2> + + + + + + + The ECU has different RAM in memory than the tuner. This could be a result of the ECU resetting, or otherwise losing sync with the tuner. The locations which are different, are listed below + + + true + + + + + + + + + + + + + + To accept the local tuner changes, click below to send these changes to the ECU. + + + true + + + + + + + Accept Local + + + + + + + + + + + To accept the ECU changes, click below to wipe out any local changes. + + + true + + + + + + + Accept Remote + + + + + + + + + + + + diff --git a/lib/core/emscomms.h b/lib/core/emscomms.h index a0156fe..bc8cd25 100644 --- a/lib/core/emscomms.h +++ b/lib/core/emscomms.h @@ -120,14 +120,16 @@ class EmsComms : public QThread virtual QByteArray generatePacket(QByteArray header,QByteArray payload)=0; virtual int updateBlockInRam(unsigned short location,unsigned short offset, unsigned short size,QByteArray data)=0; virtual int updateBlockInFlash(unsigned short location,unsigned short offset, unsigned short size,QByteArray data)=0; - virtual int retrieveBlockFromRam(unsigned short location, unsigned short offset, unsigned short size)=0; - virtual int retrieveBlockFromFlash(unsigned short location, unsigned short offset, unsigned short size)=0; + virtual int retrieveBlockFromRam(unsigned short location, unsigned short offset, unsigned short size,bool mark=true)=0; + virtual int retrieveBlockFromFlash(unsigned short location, unsigned short offset, unsigned short size,bool mark=true)=0; virtual int burnBlockFromRamToFlash(unsigned short location,unsigned short offset, unsigned short size)=0; virtual void setInterByteSendDelay(int milliseconds)=0; virtual void setlogsDebugEnabled(bool enabled)=0; virtual int enableDatalogStream()=0; virtual int disableDatalogStream()=0; virtual void writeAllRamToRam()=0; + virtual void acceptLocalChanges()=0; + virtual void rejectLocalChanges()=0; }; Q_DECLARE_INTERFACE(EmsComms,"EmsComms/1.0") #endif // EMSCOMMS_H diff --git a/plugins/freeems/emsdata.cpp b/plugins/freeems/emsdata.cpp index 5a993ba..ac645b6 100644 --- a/plugins/freeems/emsdata.cpp +++ b/plugins/freeems/emsdata.cpp @@ -722,8 +722,35 @@ void EmsData::ramBlockUpdate(unsigned short locationid, QByteArray header, QByte } if (payload != getLocalRamBlock(locationid)) { + QLOG_ERROR() << "Ram block on device does not match ram block on tuner! This means local data is out of date!"; //We need to prompt the user, local ram is out of date. - setLocalRamBlock(locationid,payload); + if (isLocalRamDirty(locationid)) + { + QLOG_ERROR() << "Ram block is marked dirty"; + setLocalRamBlock(locationid,payload); + markLocalRamLocationClean(locationid); + } + else + { + MemoryLocation *ram= getLocalRamBlockInfo(locationid); + if (ram) + { + if (!ram->isReadOnly) + { + //Don't mark read only as dirty, we don't care. + m_dirtyLocalRamMemoryList.append(QPair(locationid,payload)); + emit localRamLocationDirty(locationid); + } + } + else + { + //No memory location, don't do anything + } + } + } + else + { + QLOG_ERROR() << "Ram block on device matches ram block on tuner"; } } } @@ -808,7 +835,20 @@ void EmsData::flashBlockUpdate(unsigned short locationid, QByteArray header, QBy } if (getLocalFlashBlock(locationid) != payload) { - setLocalFlashBlock(locationid,payload); + if(isLocalFlashDirty(locationid)) + { + setLocalFlashBlock(locationid,payload); + markLocalFlashLocationClean(locationid); + } + else + { + //We have incoming memory, when wedidn't know it was dirty. + //Emit a signal to let the user know there is a descrepancy that needs + //to be accepted, or rejected (in which case, rewritten to the ECU) + m_dirtyLocalFlashMemoryList.append(QPair(locationid,payload)); + emit localFlashLocationDirty(locationid); + } + } } } @@ -984,3 +1024,91 @@ MemoryLocation* EmsData::getLocalRamBlockInfo(unsigned short locationid) } return 0; } +MemoryLocation* EmsData::getLocalFlashBlockInfo(unsigned short locationid) +{ + for (int i=0;ilocationid == locationid) + { + return m_flashMemoryList[i]; + } + } + return 0; +} +void EmsData::markLocalFlashLocationDirty(unsigned short location,unsigned short offset,unsigned short size) +{ + MemoryLocation *flash = getLocalFlashBlockInfo(location); + if (flash) + { + if (size == 0) + { + size = flash->size; + } + for (int i=flash->flashAddress+offset;i<(flash->flashAddress+offset) + size;i++) + { + flash->setByteDirty(i); + } + } +} +void EmsData::markLocalFlashLocationClean(unsigned short locationid) +{ + MemoryLocation *flash = getLocalFlashBlockInfo(locationid); + if (flash) + { + for (int i=flash->flashAddress;iflashAddress+flash->size;i++) + { + flash->setByteClean(i); + } + } +} + +void EmsData::markLocalRamLocationDirty(unsigned short location,unsigned short offset,unsigned short size) +{ + MemoryLocation *ram= getLocalRamBlockInfo(location); + if (ram) + { + if (ram->isReadOnly) + { + //Don't mark read only as dirty, we don't care. + return; + } + if (size == 0) + { + size = ram->size; + } + for (int i=ram->ramAddress+offset;i<(ram->ramAddress+offset) + size;i++) + { + ram->setByteDirty(i); + } + } +} +void EmsData::markLocalRamLocationClean(unsigned short locationid) +{ + MemoryLocation *ram= getLocalRamBlockInfo(locationid); + if (ram) + { + for (int i=ram->ramAddress;iramAddress+ram->size;i++) + { + ram->setByteClean(i); + } + } +} +bool EmsData::isLocalRamDirty(unsigned short locationid) +{ + MemoryLocation *ram= getLocalRamBlockInfo(locationid); + if (ram) + { + return ram->isDirty(); + } + return false; +} + +bool EmsData::isLocalFlashDirty(unsigned short locationid) +{ + MemoryLocation *flash = getLocalFlashBlockInfo(locationid); + if (flash) + { + return flash->isDirty(); + } + return false; +} diff --git a/plugins/freeems/emsdata.h b/plugins/freeems/emsdata.h index 1443735..1a90134 100644 --- a/plugins/freeems/emsdata.h +++ b/plugins/freeems/emsdata.h @@ -107,6 +107,19 @@ class EmsData : public QObject QList getTopLevelUniqueLocationIdList(); QList getUniqueLocationIdList(); MemoryLocation* getLocalRamBlockInfo(unsigned short locationid); + MemoryLocation* getLocalFlashBlockInfo(unsigned short locationid); + + void markLocalFlashLocationDirty(unsigned short location,unsigned short offset,unsigned short size); + void markLocalFlashLocationClean(unsigned short locationid); + void markLocalRamLocationDirty(unsigned short location,unsigned short offset,unsigned short size); + void markLocalRamLocationClean(unsigned short locationid); + bool isLocalRamDirty(unsigned short locationid); + bool isLocalFlashDirty(unsigned short locationid); + QList > getDirtyFlashLocations() { return m_dirtyLocalFlashMemoryList; } + QList > getDirtyRamLocations() { return m_dirtyLocalRamMemoryList; } + void clearDirtyRamLocations() { m_dirtyLocalRamMemoryList.clear(); } + void clearDirtyFlashLocations() { m_dirtyLocalFlashMemoryList.clear(); } + private: bool m_checkEmsDataInUse; @@ -126,6 +139,8 @@ class EmsData : public QObject QList m_configMetaData; QList m_readOnlyMetaData; QMap m_errorMap; + QList > m_dirtyLocalFlashMemoryList; + QList > m_dirtyLocalRamMemoryList; bool verifyMemoryBlock(unsigned short locationid,QByteArray header,QByteArray payload); double calcAxis(int val,QList > metadata); int backConvertAxis(double val,QList > metadata); @@ -135,6 +150,8 @@ class EmsData : public QObject void ramBlockUpdateRequest(unsigned short locationid,unsigned short offset,unsigned short size,QByteArray data); void flashBlockUpdateRequest(unsigned short locationid,unsigned short offset,unsigned short size,QByteArray data); void configRecieved(ConfigBlock,QVariant); + void localFlashLocationDirty(unsigned short locationid); + void localRamLocationDirty(unsigned short locationid); public slots: void ramBlockUpdate(unsigned short locationid, QByteArray header, QByteArray payload); void flashBlockUpdate(unsigned short locationid, QByteArray header, QByteArray payload); diff --git a/plugins/freeems/freeemscomms.cpp b/plugins/freeems/freeemscomms.cpp index 34ef95d..4166c2a 100644 --- a/plugins/freeems/freeemscomms.cpp +++ b/plugins/freeems/freeemscomms.cpp @@ -57,6 +57,7 @@ FreeEmsComms::FreeEmsComms(QObject *parent) : EmsComms(parent) connect(m_packetDecoder,SIGNAL(flashBlockUpdatePacket(QByteArray,QByteArray)),this,SLOT(flashBlockUpdateRec(QByteArray,QByteArray))); connect(m_packetDecoder,SIGNAL(dataLogPayloadReceived(QByteArray,QByteArray)),this,SIGNAL(dataLogPayloadReceived(QByteArray,QByteArray))); connect(m_packetDecoder,SIGNAL(dataLogPayloadReceived(QByteArray,QByteArray)),dataPacketDecoder,SLOT(decodePayloadPacket(QByteArray,QByteArray))); + connect(m_packetDecoder,SIGNAL(dataLogPayloadReceived(QByteArray,QByteArray)),this,SLOT(dataLogPayloadReceivedRec(QByteArray,QByteArray))); connect(m_packetDecoder,SIGNAL(compilerVersion(QString)),this,SLOT(compilerVersion(QString))); connect(m_packetDecoder,SIGNAL(decoderName(QString)),this,SLOT(decoderName(QString))); connect(m_packetDecoder,SIGNAL(firmwareBuild(QString)),this,SLOT(firmwareBuild(QString))); @@ -122,6 +123,8 @@ FreeEmsComms::FreeEmsComms(QObject *parent) : EmsComms(parent) connect(&emsData,SIGNAL(flashBlockUpdateRequest(unsigned short,unsigned short,unsigned short,QByteArray)),this,SLOT(updateBlockInFlash(unsigned short,unsigned short,unsigned short,QByteArray))); connect(&emsData,SIGNAL(updateRequired(unsigned short)),this,SLOT(locationIdUpdate(unsigned short))); connect(&emsData,SIGNAL(configRecieved(ConfigBlock,QVariant)),this,SIGNAL(configRecieved(ConfigBlock,QVariant))); + connect(&emsData,SIGNAL(localRamLocationDirty(unsigned short)),this,SLOT(ramLocationMarkedDirty(unsigned short))); + connect(&emsData,SIGNAL(localFlashLocationDirty(unsigned short)),this,SLOT(flashLocationMarkedDirty(unsigned short))); QFile dialogFile("menuconfig.json"); @@ -546,6 +549,8 @@ int FreeEmsComms::updateBlockInRam(unsigned short location,unsigned short offset m_sequenceNumber++; m_reqList.append(req); + emsData.markLocalRamLocationDirty(location,offset,size); + if (emsData.getLocalRamBlockInfo(location)->isFlash) { unsigned short ramaddress = emsData.getLocalRamBlockInfo(location)->ramAddress; @@ -575,6 +580,8 @@ int FreeEmsComms::updateBlockInFlash(unsigned short location,unsigned short offs req.hasLength = true; m_sequenceNumber++; m_reqList.append(req); + emsData.markLocalFlashLocationDirty(location,offset,size); + return m_sequenceNumber-1; } @@ -650,7 +657,7 @@ int FreeEmsComms::getBuiltByName() m_reqList.append(req); return m_sequenceNumber-1; } -int FreeEmsComms::retrieveBlockFromFlash(unsigned short location, unsigned short offset, unsigned short size) +int FreeEmsComms::retrieveBlockFromFlash(unsigned short location, unsigned short offset, unsigned short size,bool mark) { QMutexLocker locker(&m_reqListMutex); RequestClass req; @@ -667,8 +674,16 @@ int FreeEmsComms::retrieveBlockFromFlash(unsigned short location, unsigned short //emsData.getLocalRamBlockInfo(location)->size; //emsData.getLocalRamBlockInfo(location)->ramAddress; - if (emsData.getLocalRamBlockInfo(location)) + //We mark it dirty, so it will be silently replaced. + if (mark) + { + emsData.markLocalFlashLocationDirty(location,offset,size); + } + + /*if (emsData.getLocalRamBlockInfo(location)) { + emsData.markLocalRamLocationClean(location,offset,size); + for (int i=emsData.getLocalRamBlockInfo(location)->ramAddress + offset;iramAddress+offset+size;i++) { if (m_dirtyRamAddresses.contains(i)) @@ -680,10 +695,10 @@ int FreeEmsComms::retrieveBlockFromFlash(unsigned short location, unsigned short { emit memoryClean(); } - } + }*/ return m_sequenceNumber-1; } -int FreeEmsComms::retrieveBlockFromRam(unsigned short location, unsigned short offset, unsigned short size) +int FreeEmsComms::retrieveBlockFromRam(unsigned short location, unsigned short offset, unsigned short size,bool mark) { QMutexLocker locker(&m_reqListMutex); RequestClass req; @@ -696,6 +711,10 @@ int FreeEmsComms::retrieveBlockFromRam(unsigned short location, unsigned short o req.hasReply = true; m_sequenceNumber++; m_reqList.append(req); + if (mark) + { + emsData.markLocalRamLocationDirty(location,offset,size); + } return m_sequenceNumber-1; } int FreeEmsComms::getInterfaceVersion() @@ -1358,13 +1377,13 @@ void FreeEmsComms::sendNextInterrogationPacket() } for (int i=0;i 5000) + if (current > 1500) { - //It's been 5 seconds since our last datalog. We've likely either reset, or stopped responding. + //It's been 1.5 seconds since our last datalog. We've likely either reset, or stopped responding. m_isSilent = true; m_lastDatalogUpdateEnabled = false; emit emsSilenceStarted(); @@ -1919,5 +1939,39 @@ void FreeEmsComms::locationIdInfoRec(MemoryLocationInfo info) m_rawDataMap[locationid] = data; } } +void FreeEmsComms::ramLocationMarkedDirty(unsigned short locationid) +{ + emit ramLocationDirty(locationid); +} + +void FreeEmsComms::flashLocationMarkedDirty(unsigned short locationid) +{ + emit flashLocationDirty(locationid); + +} +void FreeEmsComms::acceptLocalChanges() +{ + for (int i=0;i getConfigList(); void writeAllRamToRam(); + void acceptLocalChanges(); + void rejectLocalChanges(); protected: void run(); private: @@ -210,15 +212,20 @@ class FreeEmsComms : public EmsComms void memoryDirty(); void memoryClean(); void benchTestReply(unsigned short countRemaining,unsigned char currentEvent); + void flashLocationDirty(unsigned short locationid); + void ramLocationDirty(unsigned short locationid); public slots: int updateBlockInRam(unsigned short location,unsigned short offset, unsigned short size,QByteArray data); int updateBlockInFlash(unsigned short location,unsigned short offset, unsigned short size,QByteArray data); - int retrieveBlockFromRam(unsigned short location, unsigned short offset, unsigned short size); - int retrieveBlockFromFlash(unsigned short location, unsigned short offset, unsigned short size); + int retrieveBlockFromRam(unsigned short location, unsigned short offset, unsigned short size,bool mark=true); + int retrieveBlockFromFlash(unsigned short location, unsigned short offset, unsigned short size,bool mark=true); int burnBlockFromRamToFlash(unsigned short location,unsigned short offset, unsigned short size); private slots: + void dataLogPayloadReceivedRec(QByteArray header,QByteArray payload); void ramBlockUpdateRec(QByteArray header,QByteArray payload); void rxThreadPortGone(); + void ramLocationMarkedDirty(unsigned short locationid); + void flashLocationMarkedDirty(unsigned short locationid); void flashBlockUpdateRec(QByteArray header,QByteArray payload); void packetNakedRec(unsigned short payloadid,QByteArray header,QByteArray payload,unsigned short errornum); void packetAckedRec(unsigned short payloadid,QByteArray header,QByteArray payload); diff --git a/plugins/freeems/memorylocation.cpp b/plugins/freeems/memorylocation.cpp index 94e56e4..d8f8c3b 100644 --- a/plugins/freeems/memorylocation.cpp +++ b/plugins/freeems/memorylocation.cpp @@ -53,6 +53,34 @@ void MemoryLocation::childChanged(MemoryLocation *child,QByteArray data) } m_data.replace(childinparent,data.length(),data); } +void MemoryLocation::setByteDirty(unsigned short offset) +{ + if (!m_dirty.contains(offset)) + { + m_dirty.append(offset); + } +} + +void MemoryLocation::setByteClean(unsigned short offset) +{ + if (m_dirty.contains(offset)) + { + m_dirty.removeOne(offset); + } +} + +bool MemoryLocation::MemoryLocation::isDirty() +{ + if (m_dirty.size() == 0) + { + return false; + } + else + { + return true; + } +} + QByteArray MemoryLocation::data(MemoryLocation *child) { unsigned short childinparent=0; diff --git a/plugins/freeems/memorylocation.h b/plugins/freeems/memorylocation.h index 31cd2e8..c253031 100644 --- a/plugins/freeems/memorylocation.h +++ b/plugins/freeems/memorylocation.h @@ -48,8 +48,12 @@ class MemoryLocation void childChanged(MemoryLocation *child,QByteArray data); QByteArray data(MemoryLocation *child); QByteArray data(); + void setByteDirty(unsigned short offset); + void setByteClean(unsigned short offset); + bool isDirty(); private: QByteArray m_data; + QList m_dirty; QList m_childList; MemoryLocation *m_parent; signals: