1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-11-30 08:24:11 +01:00

GCS-side implementation: if a firmware is package with description 100 byte bin blob at the end, it will use it, and parse it back

if description is structured the same way.
This commit is contained in:
elafargue 2011-05-08 11:36:55 +02:00
parent b61bd5bf31
commit 4af0c562e3
5 changed files with 112 additions and 52 deletions

View File

@ -117,9 +117,16 @@ void deviceWidget::populate()
int size=((OP_DFU::device)m_dfu->devices[deviceID]).SizeOfDesc; int size=((OP_DFU::device)m_dfu->devices[deviceID]).SizeOfDesc;
m_dfu->enterDFU(deviceID); m_dfu->enterDFU(deviceID);
QString str = m_dfu->DownloadDescription(size); QByteArray desc = m_dfu->DownloadDescriptionAsBA(size);
myDevice->description->setMaxLength(size); if (! populateStructuredDescription(desc)) {
myDevice->description->setText(str.left(str.indexOf(QChar(255)))); // desc was not a structured description
QString str = m_dfu->DownloadDescription(size);
myDevice->description->setMaxLength(size);
myDevice->description->setText(str.left(str.indexOf(QChar(255))));
myDevice->buildDate->setText("Warning: development firmware");
myDevice->commitTag->setText("");
}
status("Ready...", STATUSICON_INFO); status("Ready...", STATUSICON_INFO);
@ -137,6 +144,51 @@ void deviceWidget::freeze()
myDevice->retrieveButton->setEnabled(false); myDevice->retrieveButton->setEnabled(false);
} }
/**
Populates the widget field with the description in case
it is structured properly
*/
bool deviceWidget::populateStructuredDescription(QByteArray desc)
{
if (desc.startsWith("OpFw")) {
// This looks like a binary with a description at the end
/*
# 4 bytes: header: "OpFw"
# 4 bytes: GIT commit tag (short version of SHA1)
# 4 bytes: Unix timestamp of compile time
# 2 bytes: target platform. Should follow same rule as BOARD_TYPE and BOARD_REVISION in board define files.
# 26 bytes: commit tag if it is there, otherwise "Unreleased". Zero-padded
# ---- 40 bytes limit ---
# 20 bytes: SHA1 sum of the firmware.
# 40 bytes: free for now.
*/
// I don't want to use structs, ok ?
quint32 gitCommitTag = desc.at(4)&0xFF;
for (int i=1;i<4;i++) {
gitCommitTag = gitCommitTag<<8;
gitCommitTag += desc.at(4+i) & 0xFF;
}
myDevice->commitTag->setText("GIT tag 0x" + QString::number(gitCommitTag,16));
quint32 buildDate = desc.at(8)&0xFF;
for (int i=1;i<4;i++) {
buildDate = buildDate<<8;
buildDate += desc.at(8+i) & 0xFF;
}
myDevice->buildDate->setText(QString("Build time: ") + QDateTime::fromTime_t(buildDate).toString());
QByteArray targetPlatform = desc.mid(12,2);
// TODO: check platform compatibility
QString dscText = QString(desc.mid(14,26));
myDevice->description->setText(dscText);
return true;
}
return false;
}
/** /**
Updates status message for messages coming from DFU Updates status message for messages coming from DFU
*/ */
@ -199,8 +251,6 @@ void deviceWidget::uploadFirmware()
return; return;
} }
// TODO : parse the firmware last 100 bytes and see whether it is
// packaged:
QFile file(filename); QFile file(filename);
if (!file.open(QIODevice::ReadOnly)) { if (!file.open(QIODevice::ReadOnly)) {
status("Can't open file", STATUSICON_FAIL); status("Can't open file", STATUSICON_FAIL);
@ -209,36 +259,11 @@ void deviceWidget::uploadFirmware()
QByteArray arr = file.readAll(); QByteArray arr = file.readAll();
QByteArray desc = arr.right(100); QByteArray desc = arr.right(100);
if (desc.startsWith("OpFw")) { if (populateStructuredDescription(desc)) {
// This looks like a binary with a description at the end descriptionArray = desc;
/*
# 4 bytes: header: "OpFw"
# 4 bytes: GIT commit tag (short version of SHA1)
# 4 bytes: Unix timestamp of compile time
# 2 bytes: target platform. Should follow same rule as BOARD_TYPE and BOARD_REVISION in board define files.
# 26 bytes: commit tag if it is there, otherwise "Unreleased". Zero-padded
# ---- 40 bytes limit ---
# 20 bytes: SHA1 sum of the firmware.
# 40 bytes: free for now.
*/
// I don't want to use structs, ok ?
QByteArray gitCommitTag = desc.mid(4,4);
quint32 buildDate = desc.at(8)&0xFF;
for (int i=1;i<4;i++) {
buildDate = buildDate<<8;
buildDate += desc.at(8+i) & 0xFF;
}
myDevice->buildDate->setText(QDateTime::fromTime_t(buildDate).toString());
QByteArray targetPlatform = desc.mid(12,2);
// TODO: check platform compatibility
QString dscText = QString(desc.mid(14,26));
myDevice->description->setText(dscText);
return;
} else { } else {
// TODO : tell the user that the firmware is not packaged. // TODO : tell the user that the firmware is not packaged.
descriptionArray.clear();
} }
@ -320,15 +345,27 @@ void deviceWidget::uploadFinished(OP_DFU::Status retstatus)
status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL); status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL);
return; return;
} else } else
if(!myDevice->description->text().isEmpty()) { if (!descriptionArray.isEmpty()) {
// We have a structured array to save
status(QString("Updating description"), STATUSICON_RUNNING); status(QString("Updating description"), STATUSICON_RUNNING);
repaint(); // Make sure the text above shows right away repaint(); // Make sure the text above shows right away
retstatus = m_dfu->UploadDescription(myDevice->description->text()); retstatus = m_dfu->UploadDescription(descriptionArray);
if( retstatus != OP_DFU::Last_operation_Success) { if( retstatus != OP_DFU::Last_operation_Success) {
status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL); status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL);
return; return;
} }
} else if (!myDevice->description->text().isEmpty()) {
// Fallback: we save the description field:
status(QString("Updating description"), STATUSICON_RUNNING);
repaint(); // Make sure the text above shows right away
retstatus = m_dfu->UploadDescription(myDevice->description->text());
if( retstatus != OP_DFU::Last_operation_Success) {
status(QString("Upload failed with code: ") + m_dfu->StatusToString(retstatus).toLatin1().data(), STATUSICON_FAIL);
return;
}
} }
status("Upload successful", STATUSICON_OK); status("Upload successful", STATUSICON_OK);
} }

View File

@ -59,7 +59,9 @@ private:
QByteArray downloadedFirmware; QByteArray downloadedFirmware;
QString filename; QString filename;
QGraphicsSvgItem *devicePic; QGraphicsSvgItem *devicePic;
QByteArray descriptionArray;
void status(QString str, StatusIcon ic); void status(QString str, StatusIcon ic);
bool populateStructuredDescription(QByteArray arr);
signals: signals:

View File

@ -137,17 +137,17 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="6" column="0"> <item row="3" column="0" colspan="2">
<widget class="QLabel" name="buildDate"> <widget class="QLabel" name="buildDate">
<property name="text"> <property name="text">
<string>Compile Date</string> <string>Build Date</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0" colspan="2"> <item row="6" column="0">
<widget class="QLabel" name="commitTag"> <widget class="QLabel" name="commitTag">
<property name="text"> <property name="text">
<string>Commit tag:</string> <string>Commit tag</string>
</property> </property>
</widget> </widget>
</item> </item>

View File

@ -276,22 +276,31 @@ bool DFUObject::UploadData(qint32 const & numberOfBytes, QByteArray & data)
/** /**
Sends the firmware description to the device Sends the firmware description to the device
*/ */
OP_DFU::Status DFUObject::UploadDescription(QString description) OP_DFU::Status DFUObject::UploadDescription(QVariant desc)
{ {
cout<<"Starting uploading description\n"; cout<<"Starting uploading description\n";
if(description.length()%4!=0) QByteArray array;
{
int pad=description.length()/4; if (desc.type() == QMetaType::QString) {
pad=(pad+1)*4; QString description = desc.toString();
pad=pad-description.length(); if(description.length()%4!=0)
QString padding; {
padding.fill(' ',pad); int pad=description.length()/4;
description.append(padding); pad=(pad+1)*4;
pad=pad-description.length();
QString padding;
padding.fill(' ',pad);
description.append(padding);
}
array=description.toAscii();
} else if (desc.type() == QMetaType::QByteArray) {
array = desc.toByteArray();
} }
if(!StartUpload(description.length(),OP_DFU::Descript,0))
if(!StartUpload(array.length(),OP_DFU::Descript,0))
return OP_DFU::abort; return OP_DFU::abort;
QByteArray array=description.toAscii(); if(!UploadData(array.length(),array))
if(!UploadData(description.length(),array))
{ {
return OP_DFU::abort; return OP_DFU::abort;
} }
@ -301,6 +310,7 @@ OP_DFU::Status DFUObject::UploadDescription(QString description)
} }
OP_DFU::Status ret = StatusRequest(); OP_DFU::Status ret = StatusRequest();
if(debug) if(debug)
qDebug() << "Upload description Status=" << StatusToString(ret); qDebug() << "Upload description Status=" << StatusToString(ret);
return ret; return ret;
@ -321,6 +331,15 @@ QString DFUObject::DownloadDescription(int const & numberOfChars)
} }
QByteArray DFUObject::DownloadDescriptionAsBA(int const & numberOfChars)
{
QByteArray arr;
StartDownloadT(&arr, numberOfChars,OP_DFU::Descript);
return arr;
}
/** /**
Starts a firmware download Starts a firmware download
@param firmwareArray: pointer to the location where we should store the firmware @param firmwareArray: pointer to the location where we should store the firmware

View File

@ -12,6 +12,7 @@
#include <QMetaType> #include <QMetaType>
#include <QCryptographicHash> #include <QCryptographicHash>
#include <QList> #include <QList>
#include <QVariant>
#include <iostream> #include <iostream>
#include "delay.h" #include "delay.h"
#include <qextserialport/src/qextserialport.h> #include <qextserialport/src/qextserialport.h>
@ -124,12 +125,13 @@ namespace OP_DFU {
bool ready() { return mready; } bool ready() { return mready; }
// Upload (send to device) commands // Upload (send to device) commands
OP_DFU::Status UploadDescription(QString description); OP_DFU::Status UploadDescription(QVariant description);
bool UploadFirmware(const QString &sfile, const bool &verify,int device); bool UploadFirmware(const QString &sfile, const bool &verify,int device);
// Download (get from device) commands: // Download (get from device) commands:
// DownloadDescription is synchronous // DownloadDescription is synchronous
QString DownloadDescription(int const & numberOfChars); QString DownloadDescription(int const & numberOfChars);
QByteArray DownloadDescriptionAsBA(int const & numberOfChars);
// Asynchronous firmware download: initiates fw download, // Asynchronous firmware download: initiates fw download,
// and a downloadFinished signal is emitted when download // and a downloadFinished signal is emitted when download
// if finished: // if finished: