From d38b94120df5df35f1b6c335cd2750c5846b121d Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Thu, 11 May 2017 21:42:12 -0400 Subject: [PATCH] Fixes to allow for rapid frame updating in screens that need it, more implementation of UDS scanner (and fixes to make it work with current code base) --- canframemodel.cpp | 25 ++++--- config.h | 2 +- connections/canconmanager.cpp | 6 +- mainwindow.h | 4 +- re/udsscanwindow.cpp | 104 +++++++++++++------------- re/udsscanwindow.h | 4 +- ui/udsscanwindow.ui | 134 ++++++++++++++++++++++++++-------- 7 files changed, 179 insertions(+), 100 deletions(-) diff --git a/canframemodel.cpp b/canframemodel.cpp index 5d24df6..07e2869 100644 --- a/canframemodel.cpp +++ b/canframemodel.cpp @@ -49,12 +49,12 @@ CANFrameModel::CANFrameModel(QObject *parent) if (QSysInfo::WordSize > 32) { qDebug() << "64 bit OS detected. Requesting a large preallocation"; - preallocSize = 20000000; + preallocSize = 10000000; } else //if compiling for 32 bit you can't ask for gigabytes of preallocation so tone it down. { qDebug() << "32 bit OS detected. Requesting a much restricted prealloc"; - preallocSize = 4000000; + preallocSize = 2000000; } frames.reserve(preallocSize); @@ -106,7 +106,7 @@ void CANFrameModel::setInterpetMode(bool mode) void CANFrameModel::normalizeTiming() { mutex.lock(); - if (frames.count() == 0) return; + if (frames.count() == 0) return; timeOffset = frames[0].timestamp; for (int i = 0; i < frames.count(); i++) { @@ -240,7 +240,7 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const if (!timeSeconds) return QString::number(thisFrame.timestamp); else return QString::number((double)thisFrame.timestamp / 1000000.0, 'f', 6); break; - case 1: //id + case 1: //id return Utility::formatNumber(thisFrame.ID); break; case 2: //ext @@ -281,7 +281,7 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const tempString.append(sigString); tempString.append("\n"); } - } + } } } return tempString; @@ -351,7 +351,7 @@ void CANFrameModel::addFrame(const CANFrame& frame, bool autoRefresh = false) } if (!overwriteDups) - { + { frames.append(tempFrame); if (filters[tempFrame.ID]) { @@ -366,14 +366,14 @@ void CANFrameModel::addFrame(const CANFrame& frame, bool autoRefresh = false) for (int i = 0; i < frames.count(); i++) { if (frames[i].ID == tempFrame.ID) - { + { frames.replace(i, tempFrame); found = true; break; } } if (!found) - { + { frames.append(tempFrame); if (filters[tempFrame.ID]) { @@ -409,9 +409,9 @@ void CANFrameModel::addFrames(const CANConnection*, const QVector& pFr } void CANFrameModel::sendRefresh() -{ +{ qDebug() << "Sending mass refresh"; - QVector tempContainer; + QVector tempContainer; int count = frames.count(); for (int i = 0; i < count; i++) { @@ -423,8 +423,9 @@ void CANFrameModel::sendRefresh() mutex.lock(); beginResetModel(); filteredFrames.clear(); - filteredFrames.append(tempContainer); filteredFrames.reserve(preallocSize); + filteredFrames.append(tempContainer); + lastUpdateNumFrames = filteredFrames.count(); endResetModel(); mutex.unlock(); @@ -479,7 +480,7 @@ void CANFrameModel::clearFrames() * allows for a mass import of frames into the model */ void CANFrameModel::insertFrames(const QVector &newFrames) -{ +{ //not resetting the model here because the serial worker automatically does a bulk refresh every 1/4 second //and that refresh will cause the view to update. If you do both it usually ends up thinking you have //double the number of frames. diff --git a/config.h b/config.h index 333b4f1..d89fe49 100644 --- a/config.h +++ b/config.h @@ -1,7 +1,7 @@ #ifndef CONFIG #define CONFIG -#define VERSION 166 +#define VERSION 167 //try to keep this in sync. //SavvyCAN will complain if you connect a GVRET board with a revision diff --git a/connections/canconmanager.cpp b/connections/canconmanager.cpp index 0403d72..0fe5453 100644 --- a/connections/canconmanager.cpp +++ b/connections/canconmanager.cpp @@ -17,7 +17,7 @@ CANConManager* CANConManager::getInstance() CANConManager::CANConManager(QObject *parent): QObject(parent) { connect(&mTimer, SIGNAL(timeout()), this, SLOT(refreshCanList())); - mTimer.setInterval(125); /*tick 8 times a second */ + mTimer.setInterval(62); /*tick 16 times a second */ mTimer.setSingleShot(false); mTimer.start(); @@ -39,7 +39,7 @@ CANConManager::~CANConManager() void CANConManager::add(CANConnection* pConn_p) -{ +{ mConns.append(pConn_p); } @@ -196,7 +196,7 @@ bool CANConManager::sendFrames(const QList& pFrames) bool CANConManager::addTargettedFrame(int pBusId, uint32_t ID, uint32_t mask, QObject *receiver) { int tempBusVal; - int busBase = 0; + int busBase = 0; foreach (CANConnection* conn, mConns) { diff --git a/mainwindow.h b/mainwindow.h index 8b90e4b..e9ada2e 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -101,7 +101,7 @@ signals: void suspendCapturing(bool); //-1 = frames cleared, -2 = a new file has been loaded (so all frames are different), otherwise # of new frames - void framesUpdated(int numFrames); //something has updated the frame list + void framesUpdated(int numFrames); //something has updated the frame list (send at gui update frequency) void frameUpdateRapid(int numFrames); void settingsUpdated(); void sendCenterTimeID(int32_t ID, double timestamp); @@ -112,7 +112,7 @@ private: //canbus related data CANFrameModel *model; - DBCHandler *dbcHandler; + DBCHandler *dbcHandler; QByteArray inputBuffer; QTimer updateTimer; QTime *elapsedTime; diff --git a/re/udsscanwindow.cpp b/re/udsscanwindow.cpp index 9f36c36..7d8b3cf 100644 --- a/re/udsscanwindow.cpp +++ b/re/udsscanwindow.cpp @@ -17,7 +17,7 @@ UDSScanWindow::UDSScanWindow(const QVector *frames, QWidget *parent) : waitTimer->setInterval(100); connect(MainWindow::getReference(), SIGNAL(framesUpdated(int)), this, SLOT(updatedFrames(int))); - connect(MainWindow::getReference(), SIGNAL(frameUpdateRapid(int)), this, SLOT(rapidFrames(int))); + connect(CANConManager::getInstance(), &CANConManager::framesReceived, this, &UDSScanWindow::rapidFrames); connect(ui->btnScan, &QPushButton::clicked, this, &UDSScanWindow::scanUDS); connect(waitTimer, &QTimer::timeout, this, &UDSScanWindow::timeOut); @@ -33,6 +33,23 @@ UDSScanWindow::~UDSScanWindow() delete waitTimer; } +void UDSScanWindow::sendOnBuses(CANFrame &frame, int buses) +{ + if (buses < ui->cbBuses->count()- 1) + { + frame.bus = buses; + sendingFrames.append(frame); + } + else + { + for (int c = 0; c < ui->cbBuses->count() - 1; c++) + { + frame.bus = c; + sendingFrames.append(frame); + } + } +} + void UDSScanWindow::scanUDS() { if (currentlyRunning) @@ -43,6 +60,8 @@ void UDSScanWindow::scanUDS() ui->btnScan->setText("Start Scan"); } + waitTimer->setInterval(ui->spinDelay->value()); + ui->listResults->clear(); sendingFrames.clear(); @@ -54,62 +73,51 @@ void UDSScanWindow::scanUDS() int buses = ui->cbBuses->currentIndex(); - //start out by sending tester present to every address to see if anyone replies for (id = startID; id <= endID; id++) { frame.ID = id; frame.len = 8; frame.extended = false; - frame.data[0] = 2; - frame.data[1] = 0x3E; //tester present - frame.data[2] = 0; - frame.data[3] = 0;frame.data[4] = 0;frame.data[5] = 0; - frame.data[6] = 0;frame.data[7] = 0; - if (buses < ui->cbBuses->count()- 1) + if (ui->ckTester->isChecked()) { - frame.bus = buses; - sendingFrames.append(frame); - } - else - { - for (int c = 0; c < ui->cbBuses->count() - 1; c++) - { - frame.bus = c; - sendingFrames.append(frame); - } - } - - } - - //then try asking for the various diagnostic session types - for (typ = 1; typ < 5; typ++) - { - for (id = startID; id <= endID; id++) - { - frame.ID = id; - frame.len = 8; - frame.extended = false; frame.data[0] = 2; - frame.data[1] = 0x10; - frame.data[2] = typ; + frame.data[1] = 0x3E; //tester present + frame.data[2] = 0; frame.data[3] = 0;frame.data[4] = 0;frame.data[5] = 0; frame.data[6] = 0;frame.data[7] = 0; - - if (buses < ui->cbBuses->count()- 1) + sendOnBuses(frame, buses); + } + if (ui->ckSession->isChecked()) + { + for (typ = 1; typ < 4; typ++) //try each type of session access { - frame.bus = buses; - sendingFrames.append(frame); - } - else - { - for (int c = 0; c < ui->cbBuses->count() - 1; c++) - { - frame.bus = c; - sendingFrames.append(frame); - } + frame.data[0] = 2; + frame.data[1] = 0x10; + frame.data[2] = typ; + frame.data[3] = 0;frame.data[4] = 0;frame.data[5] = 0; + frame.data[6] = 0;frame.data[7] = 0; + sendOnBuses(frame, buses); } } + if (ui->ckReset->isChecked()) //try to command a reset of the ECU. You're likely to know if it works. ;) + { + frame.data[0] = 2; + frame.data[1] = 0x11; //Reset + frame.data[2] = 1; //hard reset. 2 = key off/on 3 = soft reset + frame.data[3] = 0;frame.data[4] = 0;frame.data[5] = 0; + frame.data[6] = 0;frame.data[7] = 0; + sendOnBuses(frame, buses); + } + if (ui->ckSecurity->isChecked()) //try to enter security mode - very likely to get a response if an ECU exists. + { + frame.data[0] = 2; + frame.data[1] = 0x27; //request security mode + frame.data[2] = 1; //request seed from ECU + frame.data[3] = 0;frame.data[4] = 0;frame.data[5] = 0; + frame.data[6] = 0;frame.data[7] = 0; + sendOnBuses(frame, buses); + } } waitTimer->start(); @@ -135,26 +143,24 @@ void UDSScanWindow::updatedFrames(int numFrames) //Updates here are nearly once per millisecond if there is heavy traffic. That's more like it! //TODO: I really doubt this works anymore with the new connection system. This breaks the UDS scanner for now! ;( -void UDSScanWindow::rapidFrames(int numFrames) +void UDSScanWindow::rapidFrames(const CANConnection* conn, const QVector& pFrames) { - CANFrame thisFrame; QString result; uint32_t id; int offset = ui->spinReplyOffset->value(); CANFrame sentFrame; bool gotReply = false; - if (numFrames > modelFrames->count()) return; + if (pFrames.length() <= 0) return; int numSending = sendingFrames.length(); if (numSending == 0) return; if (currIdx >= numSending) return; sentFrame = sendingFrames[currIdx]; - for (int i = modelFrames->count() - numFrames; i < modelFrames->count(); i++) + foreach(const CANFrame& thisFrame, pFrames) { if (currIdx >= numSending) return; - thisFrame = modelFrames->at(i); id = thisFrame.ID; if ((id == (uint32_t)(sentFrame.ID + offset)) || ui->cbAllowAdaptiveOffset->isChecked()) diff --git a/re/udsscanwindow.h b/re/udsscanwindow.h index 4039345..7f232d4 100644 --- a/re/udsscanwindow.h +++ b/re/udsscanwindow.h @@ -2,6 +2,7 @@ #define UDSSCANWINDOW_H #include "can_structs.h" +#include "connections/canconnection.h" #include @@ -19,7 +20,7 @@ public: private slots: void updatedFrames(int numFrames); - void rapidFrames(int numFrames); + void rapidFrames(const CANConnection* conn, const QVector& pFrames); void scanUDS(); void timeOut(); @@ -32,6 +33,7 @@ private: bool currentlyRunning; void sendNextMsg(); + void sendOnBuses(CANFrame &frame, int buses); }; #endif // UDSSCANWINDOW_H diff --git a/ui/udsscanwindow.ui b/ui/udsscanwindow.ui index 0c157bf..ca477ab 100644 --- a/ui/udsscanwindow.ui +++ b/ui/udsscanwindow.ui @@ -7,7 +7,7 @@ 0 0 742 - 527 + 628 @@ -65,41 +65,111 @@ - - - Reply Offset: - - + + + + + Reply Offset: + + + + + + + -128 + + + 128 + + + 8 + + + + + + + Allow adaptive reply offset + + + + - - - -128 - - - 128 - - - 8 - - + + + + + Scan Types: + + + + + + + Tester Present + + + + + + + Session Control + + + + + + + ECU Reset + + + + + + + Security Access + + + + - - - Allow adaptive reply offset - - - - - - - Buses to scan - - - - - + + + + + Buses to scan + + + + + + + + + + Maximum reply delay + + + + + + + 50 + + + 10000 + + + 10 + + + 100 + + + +