mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-18 03:52:11 +01:00
Merge branch 'pt/UAVO_Hash' of ssh://git.openpilot.org/OpenPilot into next
This commit is contained in:
commit
551c56f3c0
@ -52,8 +52,10 @@ const char * const GCS_YEAR = "2012";
|
||||
const char * const GCS_HELP = "http://wiki.openpilot.org";
|
||||
#ifdef GCS_REVISION
|
||||
const char * const GCS_REVISION_STR = STRINGIFY(GCS_REVISION);
|
||||
const char * const UAVOSHA1_STR = STRINGIFY(UAVO_HASH);
|
||||
#else
|
||||
const char * const GCS_REVISION_STR = "";
|
||||
const char * const UAVOSHA1_STR = "";
|
||||
#endif
|
||||
|
||||
#undef GCS_VERSION
|
||||
|
@ -12,12 +12,14 @@
|
||||
VERSION_INFO_SCRIPT = $$ROOT_DIR/make/scripts/version-info.py
|
||||
VERSION_INFO_TEMPLATE = $$ROOT_DIR/make/templates/gcsversioninfotemplate.h
|
||||
VERSION_INFO_COMMAND = python \"$$VERSION_INFO_SCRIPT\"
|
||||
UAVO_DEF_PATH = $$ROOT_DIR/shared/uavobjectdefinition
|
||||
|
||||
# Create custom version_info target which generates a header
|
||||
version_info.target = $$VERSION_INFO_HEADER
|
||||
version_info.commands = $$VERSION_INFO_COMMAND \
|
||||
--path=\"$$GCS_SOURCE_TREE\" \
|
||||
--template=\"$$VERSION_INFO_TEMPLATE\" \
|
||||
--uavodir=\"$$UAVO_DEF_PATH\" \
|
||||
--outfile=\"$$VERSION_INFO_HEADER\"
|
||||
version_info.depends = FORCE
|
||||
QMAKE_EXTRA_TARGETS += version_info
|
||||
|
@ -67,6 +67,26 @@ VersionDialog::VersionDialog(QWidget *parent)
|
||||
//: This gets conditionally inserted as argument %8 into the description string.
|
||||
ideRev = tr("From revision %1<br/>").arg(QString::fromLatin1(GCS_REVISION_STR).left(60));
|
||||
#endif
|
||||
QString uavoHashStr;
|
||||
#ifdef UAVO_HASH
|
||||
//: This gets conditionally inserted as argument %11 into the description string.
|
||||
QByteArray uavoHashArray;
|
||||
QString uavoHash = QString::fromLatin1(Core::Constants::UAVOSHA1_STR);
|
||||
uavoHash.chop(2);
|
||||
uavoHash.remove(0,2);
|
||||
uavoHash=uavoHash.trimmed();
|
||||
bool ok;
|
||||
foreach(QString str,uavoHash.split(","))
|
||||
{
|
||||
uavoHashArray.append(str.toInt(&ok,16));
|
||||
}
|
||||
QString gcsUavoHashStr;
|
||||
foreach(char i, uavoHashArray)
|
||||
{
|
||||
gcsUavoHashStr.append(QString::number(i,16).right(2));
|
||||
}
|
||||
uavoHashStr = tr("UAVO hash %1<br/>").arg(gcsUavoHashStr);
|
||||
#endif
|
||||
|
||||
const QString description = tr(
|
||||
"<h3>OpenPilot GCS %1 %9 (%10)</h3>"
|
||||
@ -76,6 +96,8 @@ VersionDialog::VersionDialog(QWidget *parent)
|
||||
"<br/>"
|
||||
"%8"
|
||||
"<br/>"
|
||||
"%11"
|
||||
"<br/>"
|
||||
"Copyright 2010-%6 %7. All rights reserved.<br/>"
|
||||
"<br/>"
|
||||
"<small>This program is free software; you can redistribute it and/or modify<br/>"
|
||||
@ -87,7 +109,7 @@ VersionDialog::VersionDialog(QWidget *parent)
|
||||
"PARTICULAR PURPOSE.</small><br/>")
|
||||
.arg(version, QLatin1String(QT_VERSION_STR), QString::number(QSysInfo::WordSize),
|
||||
QLatin1String(__DATE__), QLatin1String(__TIME__), QLatin1String(GCS_YEAR),
|
||||
(QLatin1String(GCS_AUTHOR)), ideRev).arg(QLatin1String(GCS_VERSION_TYPE), QLatin1String(GCS_VERSION_CODENAME));
|
||||
(QLatin1String(GCS_AUTHOR)), ideRev).arg(QLatin1String(GCS_VERSION_TYPE), QLatin1String(GCS_VERSION_CODENAME), uavoHashStr);
|
||||
|
||||
QLabel *copyRightLabel = new QLabel(description);
|
||||
copyRightLabel->setWordWrap(true);
|
||||
|
@ -92,6 +92,7 @@ plugin_uploader.subdir = uploader
|
||||
plugin_uploader.depends = plugin_coreplugin
|
||||
plugin_uploader.depends += plugin_uavobjects
|
||||
plugin_uploader.depends += plugin_rawhid
|
||||
plugin_uploader.depends += plugin_uavobjectutil
|
||||
SUBDIRS += plugin_uploader
|
||||
|
||||
#Dial gadget
|
||||
|
@ -8,6 +8,8 @@ public:
|
||||
QString gitHash;
|
||||
QString gitDate;
|
||||
QString gitTag;
|
||||
QByteArray fwHash;
|
||||
QByteArray uavoHash;
|
||||
int boardType;
|
||||
int boardRevision;
|
||||
static QString idToBoardName(int id)
|
||||
|
@ -257,7 +257,12 @@ FirmwareIAPObj::DataFields UAVObjectUtilManager::getFirmwareIap()
|
||||
int UAVObjectUtilManager::getBoardModel()
|
||||
{
|
||||
FirmwareIAPObj::DataFields firmwareIapData = getFirmwareIap();
|
||||
return (firmwareIapData.BoardType << 8) + firmwareIapData.BoardRevision;
|
||||
qDebug()<<"Board type="<<firmwareIapData.BoardType;
|
||||
qDebug()<<"Board revision="<<firmwareIapData.BoardRevision;
|
||||
int ret=firmwareIapData.BoardType <<8;
|
||||
ret = ret + firmwareIapData.BoardRevision;
|
||||
qDebug()<<"Board info="<<ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -625,11 +630,11 @@ int UAVObjectUtilManager::getTelemetrySerialPortSpeeds(QComboBox *comboBox)
|
||||
deviceDescriptorStruct UAVObjectUtilManager::getBoardDescriptionStruct()
|
||||
{
|
||||
deviceDescriptorStruct ret;
|
||||
descriptionToStructure(getBoardDescription(),&ret);
|
||||
descriptionToStructure(getBoardDescription(),ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool UAVObjectUtilManager::descriptionToStructure(QByteArray desc, deviceDescriptorStruct *struc)
|
||||
bool UAVObjectUtilManager::descriptionToStructure(QByteArray desc, deviceDescriptorStruct & struc)
|
||||
{
|
||||
if (desc.startsWith("OpFw")) {
|
||||
/*
|
||||
@ -639,9 +644,9 @@ bool UAVObjectUtilManager::descriptionToStructure(QByteArray desc, deviceDescrip
|
||||
* 4 bytes: Unix timestamp of last git commit
|
||||
* 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.
|
||||
* 20 bytes: SHA1 sum of the UAVO definition files.
|
||||
* 20 bytes: free for now.
|
||||
*/
|
||||
|
||||
// Note: the ARM binary is big-endian:
|
||||
@ -650,23 +655,26 @@ bool UAVObjectUtilManager::descriptionToStructure(QByteArray desc, deviceDescrip
|
||||
gitCommitHash = gitCommitHash << 8;
|
||||
gitCommitHash += desc.at(7-i) & 0xFF;
|
||||
}
|
||||
struc->gitHash = QString::number(gitCommitHash, 16);
|
||||
struc.gitHash = QString("%1").arg(gitCommitHash, 8, 16, QChar('0'));
|
||||
|
||||
quint32 gitDate = desc.at(11) & 0xFF;
|
||||
for (int i = 1; i < 4; i++) {
|
||||
gitDate = gitDate << 8;
|
||||
gitDate += desc.at(11-i) & 0xFF;
|
||||
}
|
||||
struc->gitDate = QDateTime::fromTime_t(gitDate).toUTC().toString("yyyyMMdd HH:mm");
|
||||
struc.gitDate = QDateTime::fromTime_t(gitDate).toUTC().toString("yyyyMMdd HH:mm");
|
||||
|
||||
QString gitTag = QString(desc.mid(14,26));
|
||||
struc->gitTag = gitTag;
|
||||
struc.gitTag = gitTag;
|
||||
|
||||
// TODO: check platform compatibility
|
||||
QByteArray targetPlatform = desc.mid(12,2);
|
||||
struc->boardType = (int)targetPlatform.at(0);
|
||||
struc->boardRevision = (int)targetPlatform.at(1);
|
||||
|
||||
struc.boardType = (int)targetPlatform.at(0);
|
||||
struc.boardRevision = (int)targetPlatform.at(1);
|
||||
struc.fwHash.clear();
|
||||
struc.fwHash=desc.mid(40,20);
|
||||
struc.uavoHash.clear();
|
||||
struc.uavoHash=desc.mid(60,20);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
quint32 getFirmwareCRC();
|
||||
QByteArray getBoardDescription();
|
||||
deviceDescriptorStruct getBoardDescriptionStruct();
|
||||
static bool descriptionToStructure(QByteArray desc,deviceDescriptorStruct * struc);
|
||||
static bool descriptionToStructure(QByteArray desc,deviceDescriptorStruct & struc);
|
||||
UAVObjectManager* getObjectManager();
|
||||
void saveObjectToSD(UAVObject *obj);
|
||||
protected:
|
||||
|
@ -154,7 +154,7 @@ void deviceWidget::freeze()
|
||||
*/
|
||||
bool deviceWidget::populateBoardStructuredDescription(QByteArray desc)
|
||||
{
|
||||
if(UAVObjectUtilManager::descriptionToStructure(desc,&onBoardDescription))
|
||||
if(UAVObjectUtilManager::descriptionToStructure(desc,onBoardDescription))
|
||||
{
|
||||
myDevice->lblGitTag->setText(onBoardDescription.gitHash);
|
||||
myDevice->lblBuildDate->setText(onBoardDescription.gitDate.insert(4,"-").insert(7,"-"));
|
||||
@ -184,7 +184,7 @@ bool deviceWidget::populateBoardStructuredDescription(QByteArray desc)
|
||||
}
|
||||
bool deviceWidget::populateLoadedStructuredDescription(QByteArray desc)
|
||||
{
|
||||
if(UAVObjectUtilManager::descriptionToStructure(desc,&LoadedDescription))
|
||||
if(UAVObjectUtilManager::descriptionToStructure(desc,LoadedDescription))
|
||||
{
|
||||
myDevice->lblGitTagL->setText(LoadedDescription.gitHash);
|
||||
myDevice->lblBuildDateL->setText( LoadedDescription.gitDate.insert(4,"-").insert(7,"-"));
|
||||
|
@ -101,7 +101,7 @@ void runningDeviceWidget::populate()
|
||||
|
||||
QByteArray description = utilMngr->getBoardDescription();
|
||||
deviceDescriptorStruct devDesc;
|
||||
if(UAVObjectUtilManager::descriptionToStructure(description,&devDesc))
|
||||
if(UAVObjectUtilManager::descriptionToStructure(description,devDesc))
|
||||
{
|
||||
if(devDesc.gitTag.startsWith("release",Qt::CaseInsensitive))
|
||||
{
|
||||
|
@ -650,18 +650,41 @@ void UploaderGadgetWidget::versionMatchCheck()
|
||||
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
||||
UAVObjectUtilManager *utilMngr = pm->getObject<UAVObjectUtilManager>();
|
||||
deviceDescriptorStruct boardDescription = utilMngr->getBoardDescriptionStruct();
|
||||
QByteArray uavoHashArray;
|
||||
QString uavoHash = QString::fromLatin1(Core::Constants::UAVOSHA1_STR);
|
||||
uavoHash.chop(2);
|
||||
uavoHash.remove(0,2);
|
||||
uavoHash=uavoHash.trimmed();
|
||||
bool ok;
|
||||
foreach(QString str,uavoHash.split(","))
|
||||
{
|
||||
uavoHashArray.append(str.toInt(&ok,16));
|
||||
}
|
||||
|
||||
QString gcsDescription = QString::fromLatin1(Core::Constants::GCS_REVISION_STR);
|
||||
QString gcsGitHash = gcsDescription.mid(gcsDescription.indexOf(":")+1, 8);
|
||||
gcsGitHash.remove( QRegExp("^[0]*") );
|
||||
QString gcsGitDate = gcsDescription.mid(gcsDescription.indexOf(" ")+1, 14);
|
||||
QString gcsVersion = gcsGitDate + " (" + gcsGitHash + ")";
|
||||
QString fwVersion = boardDescription.gitDate + " (" + boardDescription.gitHash + ")";
|
||||
QByteArray fwVersion=boardDescription.uavoHash;
|
||||
if (fwVersion != uavoHashArray) {
|
||||
|
||||
QString gcsDescription = QString::fromLatin1(Core::Constants::GCS_REVISION_STR);
|
||||
QString gcsGitHash = gcsDescription.mid(gcsDescription.indexOf(":")+1, 8);
|
||||
gcsGitHash.remove( QRegExp("^[0]*") );
|
||||
QString gcsGitDate = gcsDescription.mid(gcsDescription.indexOf(" ")+1, 14);
|
||||
|
||||
QString gcsUavoHashStr;
|
||||
QString fwUavoHashStr;
|
||||
foreach(char i, fwVersion)
|
||||
{
|
||||
fwUavoHashStr.append(QString::number(i,16).right(2));
|
||||
}
|
||||
foreach(char i, uavoHashArray)
|
||||
{
|
||||
gcsUavoHashStr.append(QString::number(i,16).right(2));
|
||||
}
|
||||
QString gcsVersion = gcsGitDate + " (" + gcsGitHash + "-"+ gcsUavoHashStr.right(8) + ")";
|
||||
QString fwVersion = boardDescription.gitDate + " (" + boardDescription.gitHash + "-" + fwUavoHashStr.right(8) + ")";
|
||||
|
||||
if (boardDescription.gitHash != gcsGitHash) {
|
||||
QString warning = QString(tr(
|
||||
"GCS and firmware versions do not match which can cause configuration problems. "
|
||||
"GCS version: %1. Firmware version: %2.")).arg(gcsVersion).arg(fwVersion);
|
||||
"GCS and firmware versions of the UAV objects set do not match which can cause configuration problems. "
|
||||
"GCS version: %1 Firmware version: %2.")).arg(gcsVersion).arg(fwVersion);
|
||||
msg->showMessage(warning);
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +131,8 @@ $(1).firmwareinfo.c: $(1) $(TOP)/make/templates/firmwareinfotemplate.c FORCE
|
||||
--outfile=$$@ \
|
||||
--image=$(1) \
|
||||
--type=$(2) \
|
||||
--revision=$(3)
|
||||
--revision=$(3) \
|
||||
--uavodir=$(TOP)/shared/uavobjectdefinition
|
||||
|
||||
$(eval $(call COMPILE_C_TEMPLATE, $(1).firmwareinfo.c))
|
||||
|
||||
|
@ -250,6 +250,57 @@ def xtrim(string, suffix, length):
|
||||
assert n > 0, "length of truncated string+suffix exceeds maximum length"
|
||||
return ''.join([string[:n], '+', suffix])
|
||||
|
||||
def GetHashofDirs(directory, verbose=0):
|
||||
import hashlib, os
|
||||
SHAhash = hashlib.sha1()
|
||||
if not os.path.exists (directory):
|
||||
return -1
|
||||
|
||||
try:
|
||||
for root, dirs, files in os.walk(directory):
|
||||
# os.walk() is unsorted. Must make sure we process files in sorted order so
|
||||
# that the hash is stable across invocations and across OSes.
|
||||
if files:
|
||||
files.sort()
|
||||
|
||||
for names in files:
|
||||
if verbose == 1:
|
||||
print 'Hashing', names
|
||||
filepath = os.path.join(root,names)
|
||||
try:
|
||||
f1 = open(filepath, 'rb')
|
||||
except:
|
||||
# You can't open the file for some reason
|
||||
f1.close()
|
||||
continue
|
||||
|
||||
# Compute file hash. Same as running "sha1sum <file>".
|
||||
f1hash = hashlib.sha1()
|
||||
while 1:
|
||||
# Read file in as little chunks
|
||||
buf = f1.read(4096)
|
||||
if not buf : break
|
||||
f1hash.update(buf)
|
||||
f1.close()
|
||||
|
||||
if verbose == 1:
|
||||
print 'Hash is', f1hash.hexdigest()
|
||||
|
||||
# Append the hex representation of the current file's hash into the cumulative hash
|
||||
SHAhash.update(f1hash.hexdigest())
|
||||
|
||||
except:
|
||||
import traceback
|
||||
# Print the stack traceback
|
||||
traceback.print_exc()
|
||||
return -2
|
||||
|
||||
if verbose == 1:
|
||||
print 'Final hash is', SHAhash.hexdigest()
|
||||
|
||||
hex_stream = lambda s:",".join(['0x'+hex(ord(c))[2:].zfill(2) for c in s])
|
||||
return hex_stream(SHAhash.digest())
|
||||
|
||||
def main():
|
||||
"""This utility uses git repository in the current working directory
|
||||
or from the given path to extract some info about it and HEAD commit.
|
||||
@ -302,7 +353,8 @@ dependent targets.
|
||||
help='board type, for example, 0x04 for CopterControl');
|
||||
parser.add_option('--revision', default = "",
|
||||
help='board revision, for example, 0x01');
|
||||
|
||||
parser.add_option('--uavodir', default = "",
|
||||
help='uav object definition directory');
|
||||
(args, positional_args) = parser.parse_args()
|
||||
if len(positional_args) != 0:
|
||||
parser.error("incorrect number of arguments, try --help for help")
|
||||
@ -328,6 +380,7 @@ dependent targets.
|
||||
BOARD_TYPE = args.type,
|
||||
BOARD_REVISION = args.revision,
|
||||
SHA1 = sha1(args.image),
|
||||
UAVOSHA1= GetHashofDirs(args.uavodir,0),
|
||||
)
|
||||
|
||||
if args.info:
|
||||
|
@ -30,8 +30,6 @@
|
||||
/**
|
||||
* We have 100 bytes for the whole description.
|
||||
*
|
||||
* Only the first 40 are visible on the FirmwareIAP uavobject, the remaining
|
||||
* 60 are ok to use for packaging and will be saved in the flash.
|
||||
*
|
||||
* Structure is:
|
||||
* 4 bytes: header: "OpFw".
|
||||
@ -39,9 +37,9 @@
|
||||
* 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 branch name. '-dirty' may be added if needed. Zero-padded.
|
||||
* ---- 40 bytes limit ---
|
||||
* 20 bytes: SHA1 sum of the firmware.
|
||||
* 40 bytes: free for now.
|
||||
* 20 bytes: SHA1 sum of the uavo definitions.
|
||||
* 20 bytes: free for now.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -53,7 +51,8 @@ struct __attribute__((packed)) fw_version_info {
|
||||
uint8_t board_revision;
|
||||
uint8_t commit_tag_name[26];
|
||||
uint8_t sha1sum[20];
|
||||
uint8_t pad[40];
|
||||
uint8_t uavosha1[20];
|
||||
uint8_t pad[20];
|
||||
};
|
||||
|
||||
const struct fw_version_info fw_version_blob __attribute__((used)) __attribute__((__section__(".fw_version_blob"))) = {
|
||||
@ -64,6 +63,7 @@ const struct fw_version_info fw_version_blob __attribute__((used)) __attribute__
|
||||
.board_revision = ${BOARD_REVISION},
|
||||
.commit_tag_name = "${FWTAG}",
|
||||
.sha1sum = { ${SHA1} },
|
||||
.uavosha1 = { ${UAVOSHA1} },
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -26,7 +26,7 @@
|
||||
*/
|
||||
|
||||
#define GCS_REVISION ${TAG_OR_BRANCH}:${HASH8}${DIRTY} ${DATETIME}
|
||||
|
||||
#define UAVO_HASH "{ ${UAVOSHA1} }"
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
@ -2,7 +2,7 @@
|
||||
<object name="FirmwareIAPObj" singleinstance="true" settings="false">
|
||||
<description>Queries board for SN, model, revision, and sends reset command</description>
|
||||
<field name="Command" units="" type="uint16" elements="1"/>
|
||||
<field name="Description" units="" type="uint8" elements="40"/>
|
||||
<field name="Description" units="" type="uint8" elements="100"/>
|
||||
<field name="CPUSerial" units="" type="uint8" elements="12" />
|
||||
<field name="BoardRevision" units="" type="uint16" elements="1"/>
|
||||
<field name="BoardType" units="" type="uint8" elements="1"/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user