Added a firmware uploader that can be used to upload firmware to supported cortex M3 boards (gvret, gevcu, evtvbms, etc) - Not tested to properly work yet but it does operate. Use at your own risk!

This commit is contained in:
Collin Kidder
2015-08-28 11:31:15 -04:00
parent ef1689dfe5
commit f36ba338f1
9 changed files with 436 additions and 5 deletions
+6 -3
View File
@@ -34,7 +34,8 @@ SOURCES += main.cpp\
dbcsignaleditor.cpp \
framefileio.cpp \
filecomparatorwindow.cpp \
mainsettingsdialog.cpp
mainsettingsdialog.cpp \
firmwareuploaderwindow.cpp
HEADERS += mainwindow.h \
can_structs.h \
@@ -57,7 +58,8 @@ HEADERS += mainwindow.h \
framefileio.h \
config.h \
filecomparatorwindow.h \
mainsettingsdialog.h
mainsettingsdialog.h \
firmwareuploaderwindow.h
FORMS += mainwindow.ui \
graphingwindow.ui \
@@ -70,7 +72,8 @@ FORMS += mainwindow.ui \
dbcmaineditor.ui \
dbcsignaleditor.ui \
filecomparatorwindow.ui \
mainsettingsdialog.ui
mainsettingsdialog.ui \
firmwareuploaderwindow.ui
DISTFILES +=
+232
View File
@@ -0,0 +1,232 @@
#include "firmwareuploaderwindow.h"
#include "ui_firmwareuploaderwindow.h"
#include "mainwindow.h"
#include <QFile>
FirmwareUploaderWindow::FirmwareUploaderWindow(const QVector<CANFrame> *frames, QWidget *parent) :
QDialog(parent),
ui(new Ui::FirmwareUploaderWindow)
{
ui->setupUi(this);
transferInProgress = false;
startedProcess = false;
firmwareSize = 0;
currentSendingPosition = 0;
baseAddress = 0;
bus = 0;
modelFrames = frames;
ui->lblFilename->setText("");
ui->spinBus->setValue(0);
ui->spinBus->setMaximum(1);
ui->txtBaseAddr->setText("0x100");
updateProgress();
timer = new QTimer();
timer->setInterval(100); //100ms without a reply will cause us to attempt a resend
connect(MainWindow::getReference(), SIGNAL(framesUpdated(int)), this, SLOT(updatedFrames(int)));
connect(ui->btnLoadFile, SIGNAL(clicked(bool)), this, SLOT(handleLoadFile()));
connect(ui->btnStartStop, SIGNAL(clicked(bool)), this, SLOT(handleStartStopTransfer()));
connect(timer, SIGNAL(timeout()), this, SLOT(timerElapsed()));
}
FirmwareUploaderWindow::~FirmwareUploaderWindow()
{
timer->stop();
delete timer;
delete ui;
}
void FirmwareUploaderWindow::updateProgress()
{
ui->lblProgress->setText(QString::number(currentSendingPosition * 4) + " of " + QString::number(firmwareSize) + " transferred");
}
void FirmwareUploaderWindow::updatedFrames(int numFrames)
{
CANFrame thisFrame;
if (numFrames == -1) //all frames deleted.
{
}
else if (numFrames == -2) //all new set of frames.
{
}
else //just got some new frames. See if they are relevant.
{
/*
//run through the supposedly new frames in order
for (int i = modelFrames->count() - numFrames; i < modelFrames->count(); i++)
{
thisFrame = modelFrames->at(i);
}
*/
}
}
void FirmwareUploaderWindow::gotTargettedFrame(int frameLoc)
{
const CANFrame &frame = modelFrames->at(frameLoc);
if (frame.ID == (baseAddress + 0x10)) {
qDebug() << "Start firmware reply";
if ((frame.data[0] == 0xDE) && (frame.data[1] == 0xAF))
{
if ((frame.data[2] == 0xDE) && (frame.data[3] == 0xED))
{
if ((frame.data[4] == (token & 0xFF)) && (frame.data[5] == ((token >> 8) & 0xFF)))
{
if ((frame.data[6] == ((token >> 16) & 0xFF)) && (frame.data[7] == ((token >> 24) & 0xFF)))
{
qDebug() << "starting firmware process";
MainWindow::getReference()->setTargettedID(baseAddress + 0x20);
transferInProgress = true;
sendFirmwareChunk();
}
}
}
}
}
if (frame.ID == (baseAddress + 0x20)) {
qDebug() << "Firmware reception success reply";
int seq = frame.data[0] + (256 * frame.data[1]);
if (seq == currentSendingPosition)
{
currentSendingPosition++;
if (currentSendingPosition * 4 > firmwareSize || currentSendingPosition > 65535)
{
transferInProgress = false;
timer->stop();
handleStartStopTransfer();
ui->progressBar->setValue(100);
sendFirmwareEnding();
}
else
{
ui->progressBar->setValue((400 * currentSendingPosition) / firmwareSize);
updateProgress();
sendFirmwareChunk();
}
}
}
}
void FirmwareUploaderWindow::timerElapsed()
{
sendFirmwareChunk(); //resend
}
void FirmwareUploaderWindow::sendFirmwareChunk()
{
CANFrame *output = new CANFrame;
int firmwareLocation = currentSendingPosition * 4;
int xorByte = 0;
output->extended = false;
output->len = 7;
output->ID = baseAddress + 0x16;
output->data[0] = currentSendingPosition & 0xFF;
output->data[1] = (currentSendingPosition >> 8) & 0xFF;
output->data[2] = firmwareData[firmwareLocation++];
output->data[3] = firmwareData[firmwareLocation++];
output->data[4] = firmwareData[firmwareLocation++];
output->data[5] = firmwareData[firmwareLocation++];
for (int i = 0; i < 6; i++) xorByte = xorByte ^ output->data[i];
output->data[6] = xorByte;
sendCANFrame(output, bus);
timer->start();
}
void FirmwareUploaderWindow::sendFirmwareEnding()
{
CANFrame *output = new CANFrame;
output->extended = false;
output->len = 4;
output->ID = baseAddress + 0x30;
output->data[0] = 0xC0;
output->data[1] = 0xDE;
output->data[2] = 0xFA;
output->data[3] = 0xDE;
sendCANFrame(output, bus);
}
void FirmwareUploaderWindow::handleStartStopTransfer()
{
startedProcess = !startedProcess;
if (startedProcess) //start the process
{
ui->progressBar->setValue(0);
ui->btnStartStop->setText("Stop Upload");
token = Utility::ParseStringToNum(ui->txtToken->text());
bus = ui->spinBus->value();
baseAddress = Utility::ParseStringToNum(ui->txtBaseAddr->text());
qDebug() << "Base address: " + QString::number(baseAddress);
MainWindow::getReference()->setTargettedID(baseAddress + 0x10);
CANFrame *output = new CANFrame;
output->extended = false;
output->len = 8;
output->ID = baseAddress;
output->data[0] = 0xDE;
output->data[1] = 0xAD;
output->data[2] = 0xBE;
output->data[3] = 0xEF;
output->data[4] = token & 0xFF;
output->data[5] = (token >> 8) & 0xFF;
output->data[6] = (token >> 16) & 0xFF;
output->data[7] = (token >> 24) & 0xFF;
sendCANFrame(output, bus);
}
else //stop anything in process
{
ui->btnStartStop->setText("Start Upload");
MainWindow::getReference()->setTargettedID(-1);
}
}
void FirmwareUploaderWindow::handleLoadFile()
{
QString filename;
QFileDialog dialog;
bool result = false;
QStringList filters;
filters.append(QString(tr("Raw firmware binary (*.bin)")));
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setNameFilters(filters);
dialog.setViewMode(QFileDialog::Detail);
if (dialog.exec() == QDialog::Accepted)
{
filename = dialog.selectedFiles()[0];
loadBinaryFile(filename);
}
}
void FirmwareUploaderWindow::loadBinaryFile(QString filename)
{
if (transferInProgress) handleStartStopTransfer();
QFile *inFile = new QFile(filename);
if (!inFile->open(QIODevice::ReadOnly))
{
delete inFile;
return;
}
firmwareData = inFile->readAll();
currentSendingPosition = 0;
firmwareSize = firmwareData.length();
updateProgress();
inFile->close();
delete inFile;
}
+53
View File
@@ -0,0 +1,53 @@
#ifndef FIRMWAREUPLOADERWINDOW_H
#define FIRMWAREUPLOADERWINDOW_H
#include <QDialog>
#include <QTimer>
#include "can_structs.h"
#include "utility.h"
#include "serialworker.h"
namespace Ui {
class FirmwareUploaderWindow;
}
class FirmwareUploaderWindow : public QDialog
{
Q_OBJECT
public:
explicit FirmwareUploaderWindow(const QVector<CANFrame> *frames, QWidget *parent = 0);
~FirmwareUploaderWindow();
signals:
void sendCANFrame(const CANFrame *, int);
public slots:
void gotTargettedFrame(int frameLoc);
private slots:
void handleLoadFile();
void handleStartStopTransfer();
void updatedFrames(int);
void timerElapsed();
private:
void updateProgress();
void loadBinaryFile(QString);
void sendFirmwareChunk();
void sendFirmwareEnding();
Ui::FirmwareUploaderWindow *ui;
bool transferInProgress;
bool startedProcess;
int firmwareSize;
int currentSendingPosition;
int baseAddress;
int bus;
uint32_t token;
QByteArray firmwareData;
const QVector<CANFrame> *modelFrames;
QTimer *timer;
};
#endif // FIRMWAREUPLOADERWINDOW_H
+106
View File
@@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FirmwareUploaderWindow</class>
<widget class="QDialog" name="FirmwareUploaderWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>327</width>
<height>357</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Loaded File:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblFilename">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnLoadFile">
<property name="text">
<string>Load File</string>
</property>
</widget>
</item>
<item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="label">
<property name="text">
<string>Device Token:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="txtToken"/>
</item>
<item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="label_4">
<property name="text">
<string>CAN Bus:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBus"/>
</item>
<item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Base Address:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="txtBaseAddr"/>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QProgressBar" name="progressBar">
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="lblProgress">
<property name="text">
<string>X of Y bytes</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnStartStop">
<property name="text">
<string>Start Upload</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+18
View File
@@ -104,6 +104,7 @@ MainWindow::MainWindow(QWidget *parent) :
dbcMainEditor = NULL;
comparatorWindow = NULL;
settingsDialog = NULL;
firmwareUploaderWindow = NULL;
dbcHandler = new DBCHandler;
bDirty = false;
inhibitFilterUpdate = false;
@@ -143,6 +144,7 @@ MainWindow::MainWindow(QWidget *parent) :
connect(ui->listFilters, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(filterListItemChanged(QListWidgetItem*)));
connect(ui->btnFilterAll, SIGNAL(clicked(bool)), this, SLOT(filterSetAll()));
connect(ui->btnFilterNone, SIGNAL(clicked(bool)), this, SLOT(filterClearAll()));
connect(ui->actionFirmware_Uploader, SIGNAL(triggered(bool)), this, SLOT(showFirmwareUploaderWindow()));
lbStatusConnected.setText(tr("Not connected"));
updateFileStatus();
@@ -906,6 +908,11 @@ void MainWindow::gotDeviceInfo(int build, int swCAN)
}
}
void MainWindow::setTargettedID(int id)
{
worker->targetFrameID(id);
}
void MainWindow::showSettingsDialog()
{
if (!settingsDialog)
@@ -972,6 +979,17 @@ void MainWindow::showPlaybackWindow()
playbackWindow->show();
}
void MainWindow::showFirmwareUploaderWindow()
{
if (!firmwareUploaderWindow)
{
firmwareUploaderWindow = new FirmwareUploaderWindow(model->getListReference());
connect(firmwareUploaderWindow, SIGNAL(sendCANFrame(const CANFrame*,int)), worker, SLOT(sendFrame(const CANFrame*,int)));
connect(worker, SIGNAL(gotTargettedFrame(int)), firmwareUploaderWindow, SLOT(gotTargettedFrame(int)));
}
firmwareUploaderWindow->show();
}
void MainWindow::showComparisonWindow()
{
if (!comparatorWindow)
+4
View File
@@ -17,6 +17,7 @@
#include "dbchandler.h"
#include "dbcmaineditor.h"
#include "mainsettingsdialog.h"
#include "firmwareuploaderwindow.h"
namespace Ui {
class MainWindow;
@@ -30,6 +31,7 @@ public:
explicit MainWindow(QWidget *parent = 0);
static QString loadedFileName;
static MainWindow *getReference();
void setTargettedID(int);
~MainWindow();
private slots:
@@ -52,6 +54,7 @@ private slots:
void showFuzzyScopeWindow();
void showComparisonWindow();
void showSettingsDialog();
void showFirmwareUploaderWindow();
void exitApp();
void handleSaveDecoded();
void changeBaudRates();
@@ -115,6 +118,7 @@ private:
DBCMainEditor *dbcMainEditor;
FileComparatorWindow *comparatorWindow;
MainSettingsDialog *settingsDialog;
FirmwareUploaderWindow *firmwareUploaderWindow;
//various private storage
QLabel lbStatusConnected;
+7 -1
View File
@@ -293,7 +293,7 @@
<x>0</x>
<y>0</y>
<width>800</width>
<height>26</height>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menu_RE_Tools">
@@ -314,6 +314,7 @@
</property>
<addaction name="action_Playback"/>
<addaction name="action_Custom"/>
<addaction name="actionFirmware_Uploader"/>
</widget>
<widget class="QMenu" name="menuFile">
<property name="title">
@@ -440,6 +441,11 @@
<string>Save Filter Definition</string>
</property>
</action>
<action name="actionFirmware_Uploader">
<property name="text">
<string>Firmware Uploader</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
+7 -1
View File
@@ -19,6 +19,7 @@ SerialWorker::SerialWorker(CANFrameModel *model, QObject *parent) : QObject(pare
capturing = true;
gotValidated = true;
isAutoRestart = false;
targetID = -1;
readSettings();
}
@@ -245,7 +246,7 @@ void SerialWorker::procRXChar(unsigned char c)
break;
case 9:
gotValidated = true;
qDebug() << "Got validated";
//qDebug() << "Got validated";
rx_state = IDLE;
break;
}
@@ -302,6 +303,7 @@ void SerialWorker::procRXChar(unsigned char c)
{
canModel->addFrame(*buildFrame, false);
gotFrames++;
if (buildFrame->ID == targetID) emit gotTargettedFrame(canModel->rowCount() - 1);
}
}
break;
@@ -477,3 +479,7 @@ void SerialWorker::startFrameCapture()
capturing = true;
}
void SerialWorker::targetFrameID(int target)
{
targetID = target;
}
+3
View File
@@ -32,6 +32,7 @@ public:
SerialWorker(CANFrameModel *model, QObject *parent = 0);
~SerialWorker();
void readSettings();
void targetFrameID(int);
signals: //we emit signals
void error(const QString &);
@@ -39,6 +40,7 @@ signals: //we emit signals
void connectionSuccess(int, int);
void connectionFailure();
void deviceInfo(int, int);
void gotTargettedFrame(int);
private slots: //we receive things in slots
void readSerialData();
@@ -70,6 +72,7 @@ private:
QTime *elapsedTime;
int framesPerSec;
int gotFrames;
int targetID;
STATE rx_state;
int rx_step;
CANFrame *buildFrame;