mirror of
https://github.com/thelsing/knx.git
synced 2025-08-31 13:47:01 +02:00
Feature: Allow additional version check on startup
- added versionCheckCallback - added apiVersion to DeviceObject - added new versionCheck to memory,cpp
This commit is contained in:
parent
f4d7f604be
commit
82c41bfbf6
@ -611,3 +611,13 @@ Memory& BauSystemB::memory()
|
||||
{
|
||||
return _memory;
|
||||
}
|
||||
|
||||
void BauSystemB::addVersionCheckCallback(versionCheckCallback func)
|
||||
{
|
||||
_memory.addVersionCheckCallback(func);
|
||||
}
|
||||
|
||||
versionCheckCallback BauSystemB::getVersionCheckCallback()
|
||||
{
|
||||
return _memory.getVersionCheckCallback();
|
||||
}
|
@ -38,6 +38,8 @@ class BauSystemB : protected BusAccessUnit
|
||||
void propertyValueWrite(ObjectType objectType, uint8_t objectInstance, uint8_t propertyId,
|
||||
uint8_t& numberOfElements, uint16_t startIndex,
|
||||
uint8_t* data, uint32_t length) override;
|
||||
void addVersionCheckCallback(versionCheckCallback func);
|
||||
versionCheckCallback getVersionCheckCallback();
|
||||
|
||||
protected:
|
||||
virtual ApplicationLayer& applicationLayer() = 0;
|
||||
|
@ -7,36 +7,40 @@
|
||||
class DeviceObject: public InterfaceObject
|
||||
{
|
||||
public:
|
||||
DeviceObject();
|
||||
uint8_t* save(uint8_t* buffer) override;
|
||||
const uint8_t* restore(const uint8_t* buffer) override;
|
||||
uint16_t saveSize() override;
|
||||
// increase this version anytime DeviceObject-API changes
|
||||
// the following value represents the serialized representation of DeviceObject.
|
||||
const uint16_t apiVersion = 1;
|
||||
|
||||
DeviceObject();
|
||||
uint8_t* save(uint8_t* buffer) override;
|
||||
const uint8_t* restore(const uint8_t* buffer) override;
|
||||
uint16_t saveSize() override;
|
||||
|
||||
uint16_t individualAddress();
|
||||
void individualAddress(uint16_t value);
|
||||
uint16_t individualAddress();
|
||||
void individualAddress(uint16_t value);
|
||||
|
||||
void individualAddressDuplication(bool value);
|
||||
bool verifyMode();
|
||||
void verifyMode(bool value);
|
||||
bool progMode();
|
||||
void progMode(bool value);
|
||||
uint16_t manufacturerId();
|
||||
void manufacturerId(uint16_t value);
|
||||
uint32_t bauNumber();
|
||||
void bauNumber(uint32_t value);
|
||||
const uint8_t* orderNumber();
|
||||
void orderNumber(const uint8_t* value);
|
||||
const uint8_t* hardwareType();
|
||||
void hardwareType(const uint8_t* value);
|
||||
uint16_t version();
|
||||
void version(uint16_t value);
|
||||
uint16_t maskVersion();
|
||||
void maskVersion(uint16_t value);
|
||||
uint16_t maxApduLength();
|
||||
void maxApduLength(uint16_t value);
|
||||
const uint8_t* rfDomainAddress();
|
||||
void rfDomainAddress(uint8_t* value);
|
||||
uint8_t defaultHopCount();
|
||||
void individualAddressDuplication(bool value);
|
||||
bool verifyMode();
|
||||
void verifyMode(bool value);
|
||||
bool progMode();
|
||||
void progMode(bool value);
|
||||
uint16_t manufacturerId();
|
||||
void manufacturerId(uint16_t value);
|
||||
uint32_t bauNumber();
|
||||
void bauNumber(uint32_t value);
|
||||
const uint8_t* orderNumber();
|
||||
void orderNumber(const uint8_t* value);
|
||||
const uint8_t* hardwareType();
|
||||
void hardwareType(const uint8_t* value);
|
||||
uint16_t version();
|
||||
void version(uint16_t value);
|
||||
uint16_t maskVersion();
|
||||
void maskVersion(uint16_t value);
|
||||
uint16_t maxApduLength();
|
||||
void maxApduLength(uint16_t value);
|
||||
const uint8_t* rfDomainAddress();
|
||||
void rfDomainAddress(uint8_t* value);
|
||||
uint8_t defaultHopCount();
|
||||
private:
|
||||
uint8_t _prgMode = 0;
|
||||
uint16_t _ownAddress = 65535; // 15.15.255;
|
||||
|
@ -37,30 +37,51 @@ void Memory::readMemory()
|
||||
|
||||
uint16_t version = 0;
|
||||
buffer = popWord(version, buffer);
|
||||
|
||||
|
||||
|
||||
if (_deviceObject.manufacturerId() != manufacturerId
|
||||
|| _deviceObject.version() != version
|
||||
|| memcmp(_deviceObject.hardwareType(), hardwareType, LEN_HARDWARE_TYPE) != 0)
|
||||
|
||||
VersionCheckResult versionCheck = FlashAllInvalid;
|
||||
|
||||
// first check correct format of deviceObject-API
|
||||
if (_deviceObject.apiVersion == version)
|
||||
{
|
||||
println("saved memory doesn't match manufacturerId, version or hardwaretype");
|
||||
print("manufacturerId: ");
|
||||
print(manufacturerId, HEX);
|
||||
print(" ");
|
||||
println(_deviceObject.manufacturerId(), HEX);
|
||||
print("version: ");
|
||||
print(version, HEX);
|
||||
print(" ");
|
||||
println(_deviceObject.version(), HEX);
|
||||
print("hardwareType: ");
|
||||
printHex("", hardwareType, LEN_HARDWARE_TYPE);
|
||||
print(" ");
|
||||
printHex("", _deviceObject.hardwareType(), LEN_HARDWARE_TYPE);
|
||||
if (_versionCheckCallback != 0) {
|
||||
versionCheck = _versionCheckCallback(manufacturerId, hardwareType);
|
||||
// callback should provide infomation about version check failure reasons
|
||||
}
|
||||
else if (_deviceObject.manufacturerId() == manufacturerId &&
|
||||
memcmp(_deviceObject.hardwareType(), hardwareType, LEN_HARDWARE_TYPE) == 0)
|
||||
{
|
||||
versionCheck = FlashValid;
|
||||
}
|
||||
else
|
||||
{
|
||||
println("manufacturerId or hardwareType are different");
|
||||
print("expexted manufacturerId: ");
|
||||
print(_deviceObject.manufacturerId(), HEX);
|
||||
print(", stored manufacturerId: ");
|
||||
println(manufacturerId, HEX);
|
||||
print("expexted hardwareType: ");
|
||||
printHex("", _deviceObject.hardwareType(), LEN_HARDWARE_TYPE);
|
||||
print(", stored hardwareType: ");
|
||||
printHex("", hardwareType, LEN_HARDWARE_TYPE);
|
||||
println("");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
println("DataObject api changed, any data stored in flash is invalid.");
|
||||
print("expexted DataObject api version: ");
|
||||
print(_deviceObject.apiVersion, HEX);
|
||||
print(", stored api version: ");
|
||||
println(version, HEX);
|
||||
}
|
||||
|
||||
if (versionCheck == FlashAllInvalid)
|
||||
{
|
||||
println("ETS has to reprogram PA and application!");
|
||||
return;
|
||||
}
|
||||
|
||||
println("manufacturerId, version and hardwareType matches");
|
||||
println("restoring data from flash...");
|
||||
print("saverestores ");
|
||||
println(_saveCount);
|
||||
for (int i = 0; i < _saveCount; i++)
|
||||
@ -70,6 +91,11 @@ void Memory::readMemory()
|
||||
buffer = _saveRestores[i]->restore(buffer);
|
||||
}
|
||||
println("restored saveRestores");
|
||||
if (versionCheck == FlashTablesInvalid)
|
||||
{
|
||||
println("TableObjects are referring to an older firmware version and are not loaded");
|
||||
return;
|
||||
}
|
||||
print("tableObjs ");
|
||||
println(_tableObjCount);
|
||||
for (int i = 0; i < _tableObjCount; i++)
|
||||
@ -105,7 +131,7 @@ void Memory::writeMemory()
|
||||
|
||||
bufferPos = pushWord(_deviceObject.manufacturerId(), bufferPos);
|
||||
bufferPos = pushByteArray(_deviceObject.hardwareType(), LEN_HARDWARE_TYPE, bufferPos);
|
||||
bufferPos = pushWord(_deviceObject.version(), bufferPos);
|
||||
bufferPos = pushWord(_deviceObject.apiVersion, bufferPos);
|
||||
|
||||
flashPos = _platform.writeNonVolatileMemory(flashPos, buffer, bufferPos - buffer);
|
||||
|
||||
@ -451,3 +477,13 @@ void Memory::addNewUsedBlock(uint8_t* address, size_t size)
|
||||
MemoryBlock* newUsedBlock = new MemoryBlock(address, size);
|
||||
addToUsedList(newUsedBlock);
|
||||
}
|
||||
|
||||
void Memory::addVersionCheckCallback(versionCheckCallback func)
|
||||
{
|
||||
_versionCheckCallback = func;
|
||||
}
|
||||
|
||||
versionCheckCallback Memory::getVersionCheckCallback()
|
||||
{
|
||||
return _versionCheckCallback;
|
||||
}
|
||||
|
@ -24,6 +24,15 @@ class MemoryBlock
|
||||
MemoryBlock* next = nullptr;
|
||||
};
|
||||
|
||||
enum VersionCheckResult
|
||||
{
|
||||
FlashAllInvalid = 0, //!< All flash content is not valid for this firmware, we delete it
|
||||
FlashTablesInvalid = 1,//!< All table objects are invalid for this firmware, device object and saveRestores are OK
|
||||
FlashValid = 2 //!< Flash content is valid and will be used
|
||||
};
|
||||
|
||||
typedef VersionCheckResult (*versionCheckCallback)(uint16_t manufacturerId, uint8_t* hardwareType);
|
||||
|
||||
class Memory
|
||||
{
|
||||
public:
|
||||
@ -41,6 +50,9 @@ public:
|
||||
uint8_t* toAbsolute(uint32_t relativeAddress);
|
||||
uint32_t toRelative(uint8_t* absoluteAddress);
|
||||
|
||||
void addVersionCheckCallback(versionCheckCallback func);
|
||||
versionCheckCallback getVersionCheckCallback();
|
||||
|
||||
private:
|
||||
void removeFromFreeList(MemoryBlock* block);
|
||||
void addToUsedList(MemoryBlock* block);
|
||||
@ -56,6 +68,7 @@ public:
|
||||
uint8_t* eraseBlockEnd(uint32_t blockNum);
|
||||
void saveBufferdEraseBlock();
|
||||
|
||||
versionCheckCallback _versionCheckCallback = 0;
|
||||
Platform& _platform;
|
||||
DeviceObject& _deviceObject;
|
||||
SaveRestore* _saveRestores[MAXSAVE] = {0};
|
||||
|
Loading…
Reference in New Issue
Block a user