Added "continuous logging" functionality.

This is useful if you're having stability troubles and/or are worried
about crashes. With traditional logging you can lose your capture if
the program, CAN adapter, or computer crash before you've saved. With
continuous logging the file is flushed to disk every couple of seconds
so you won't lose more than a few seconds of log even during a crash.
This commit is contained in:
Collin Kidder
2017-10-07 22:15:21 -04:00
parent 316ecedc13
commit 9be4838618
6 changed files with 170 additions and 10 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
#ifndef CONFIG
#define CONFIG
#define VERSION 176
#define VERSION 177
//try to keep this in sync.
//SavvyCAN will complain if you connect a GVRET board with a revision
+88 -1
View File
@@ -7,9 +7,10 @@
#include "utility.h"
QFile FrameFileIO::continuousFile;
FrameFileIO::FrameFileIO()
{
}
bool FrameFileIO::saveFrameFile(QString &fileName, const QVector<CANFrame>* frameCache)
@@ -611,6 +612,92 @@ bool FrameFileIO::saveNativeCSVFile(QString filename, const QVector<CANFrame>* f
return true;
}
bool FrameFileIO::openContinuousNative()
{
QString filename;
QFileDialog dialog(qApp->activeWindow());
QStringList filters;
filters.append(QString(tr("GVRET Logs (*.csv *.CSV)")));
dialog.setFileMode(QFileDialog::AnyFile);
dialog.setNameFilters(filters);
dialog.setViewMode(QFileDialog::Detail);
dialog.setAcceptMode(QFileDialog::AcceptSave);
if (dialog.exec() == QDialog::Accepted)
{
filename = dialog.selectedFiles()[0];
continuousFile.setFileName(filename);
if (!continuousFile.open(QIODevice::WriteOnly | QIODevice::Text))
{
return false;
}
continuousFile.write("Time Stamp,ID,Extended,Dir,Bus,LEN,D1,D2,D3,D4,D5,D6,D7,D8");
continuousFile.write("\n");
return true;
}
return false;
}
bool FrameFileIO::closeContinuousNative()
{
if (continuousFile.isOpen())
{
continuousFile.close();
return true;
}
return false;
}
bool FrameFileIO::writeContinuousNative(const QVector<CANFrame>* frames, int beginningFrame)
{
if (!continuousFile.isOpen()) return false;
qDebug() << "Bgn: " << beginningFrame << " Count: " << frames->count();
for (int c = beginningFrame; c < frames->count(); c++)
{
continuousFile.write(QString::number(frames->at(c).timestamp).toUtf8());
continuousFile.putChar(44);
continuousFile.write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8());
continuousFile.putChar(44);
if (frames->at(c).extended) continuousFile.write("true,");
else continuousFile.write("false,");
if (frames->at(c).isReceived) continuousFile.write("Rx,");
else continuousFile.write("Tx,");
continuousFile.write(QString::number(frames->at(c).bus).toUtf8());
continuousFile.putChar(44);
continuousFile.write(QString::number(frames->at(c).len).toUtf8());
continuousFile.putChar(44);
for (unsigned int temp = 0; temp < 8; temp++)
{
if (temp < frames->at(c).len)
continuousFile.write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
else
continuousFile.write("00");
continuousFile.putChar(44);
}
continuousFile.write("\n");
}
return true;
}
bool FrameFileIO::flushContinuousNative()
{
if (continuousFile.isOpen())
{
return continuousFile.flush();
}
return false;
}
bool FrameFileIO::loadGenericCSVFile(QString filename, QVector<CANFrame>* frames)
{
QFile *inFile = new QFile(filename);
+8 -1
View File
@@ -42,7 +42,7 @@ public:
static bool loadCanDumpFile(QString, QVector<CANFrame>*);
static bool loadPCANFile(QString, QVector<CANFrame>*);
static bool loadKvaserFile(QString, QVector<CANFrame>*, bool);
static bool saveCRTDFile(QString, const QVector<CANFrame>*);
static bool saveCRTDFile(QString, const QVector<CANFrame>*);
static bool saveNativeCSVFile(QString, const QVector<CANFrame>*);
static bool saveGenericCSVFile(QString, const QVector<CANFrame>*);
static bool saveLogFile(QString, const QVector<CANFrame>*);
@@ -51,6 +51,13 @@ public:
static bool saveIXXATFile(QString, const QVector<CANFrame>*);
static bool saveCANDOFile(QString, const QVector<CANFrame>*);
static bool saveVehicleSpyFile(QString, const QVector<CANFrame>*);
static bool openContinuousNative();
static bool closeContinuousNative();
static bool writeContinuousNative(const QVector<CANFrame>*, int);
static bool flushContinuousNative();
private:
static QFile continuousFile;
};
#endif // FRAMEFILEIO_H
+44 -7
View File
@@ -8,15 +8,8 @@
#include "utility.h"
/*
Compile for all platforms and create release and make Win32 binary.
Some notes on things I'd like to put into the program but haven't put on github (yet)
Single / Multi state - The goal is to find bits that change based on toggles or discrete state items (shifters, etc)
fuzzy scope - Try to find potential places where a given value might be stored - offer guesses and the program tries to find candidates for you
or, try to find things that appear to be multi-byte integers
Allow scripts to read/write signals from DBC files
allow scripts to load DBC files in support of the script - maybe the graphing system too.
*/
@@ -88,6 +81,8 @@ MainWindow::MainWindow(QWidget *parent) :
inhibitFilterUpdate = false;
rxFrames = 0;
framesPerSec = 0;
continuousLogging = false;
continuousLogFlushCounter = 0;
connect(ui->actionSetup, SIGNAL(triggered(bool)), SLOT(showConnectionSettingsWindow()));
connect(ui->actionOpen_Log_File, &QAction::triggered, this, &MainWindow::handleLoadFile);
@@ -128,6 +123,7 @@ MainWindow::MainWindow(QWidget *parent) :
connect(ui->actionMotorControlConfig, &QAction::triggered, this, &MainWindow::showMCConfigWindow);
connect(ui->actionCapture_Bisector, &QAction::triggered, this, &MainWindow::showBisectWindow);
connect(ui->actionSignal_Viewer, &QAction::triggered, this, &MainWindow::showSignalViewer);
connect(ui->actionSave_Continuous_Logfile, &QAction::triggered, this, &MainWindow::handleContinousLogging);
connect(CANConManager::getInstance(), &CANConManager::framesReceived, model, &CANFrameModel::addFrames);
@@ -413,6 +409,30 @@ void MainWindow::tickGUIUpdate()
if (model->needsFilterRefresh()) updateFilterList();
if (continuousLogging)
{
const QVector<CANFrame> *modelFrames = model->getListReference();
FrameFileIO::writeContinuousNative(modelFrames, modelFrames->count() - rxFrames);
continuousLogFlushCounter++;
if ((continuousLogFlushCounter % 3) == 0)
{
if (ui->lblContMsg->text().length() > 2)
{
ui->lblContMsg->setText("");
}
else
{
ui->lblContMsg->setText("CONTINUOUS LOGGING");
}
}
if (continuousLogFlushCounter > 8)
{
continuousLogFlushCounter = 0;
FrameFileIO::flushContinuousNative();
}
}
rxFrames = 0;
//}
}
@@ -493,6 +513,23 @@ void MainWindow::handleSaveFile()
}
}
void MainWindow::handleContinousLogging()
{
continuousLogging = !continuousLogging;
if (continuousLogging)
{
ui->actionSave_Continuous_Logfile->setText(tr("Cease Continuous Logging"));
FrameFileIO::openContinuousNative();
}
else
{
ui->actionSave_Continuous_Logfile->setText(tr("Start Continuous Logging"));
ui->lblContMsg->setText("");
FrameFileIO::closeContinuousNative();
}
}
void MainWindow::handleSaveFilteredFile()
{
QString filename;
+4
View File
@@ -58,6 +58,7 @@ private slots:
void handleSaveFilteredFile();
void handleSaveFilters();
void handleLoadFilters();
void handleContinousLogging();
void showGraphingWindow();
void showFrameDataAnalysis();
void clearFrames();
@@ -132,6 +133,9 @@ private:
bool bDirty; //have frames been added or subtracted since the last save/load?
bool useFiltered; //should sub-windows use the unfiltered or filtered frames list?
bool continuousLogging;
int continuousLogFlushCounter;
//References to other windows we can display
GraphingWindow *graphingWindow;
FrameInfoWindow *frameInfoWindow;
+25
View File
@@ -49,6 +49,24 @@
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="lblContMsg">
<property name="font">
<font>
<pointsize>11</pointsize>
<weight>75</weight>
<italic>true</italic>
<bold>true</bold>
</font>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="label">
<property name="sizePolicy">
@@ -240,6 +258,8 @@
<addaction name="actionOpen_Log_File"/>
<addaction name="actionSave_Filtered_Log_File"/>
<addaction name="actionSave_Log_File"/>
<addaction name="actionSave_Continuous_Logfile"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="actionLoad_Filter_Definition"/>
<addaction name="actionSave_Filter_Definition"/>
@@ -428,6 +448,11 @@
<string>Signal Viewer</string>
</property>
</action>
<action name="actionSave_Continuous_Logfile">
<property name="text">
<string>Start Continuous Logging</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>