mirror of
https://github.com/thelsing/knx.git
synced 2024-12-18 19:08:18 +01:00
Openknx version support (#190)
* Feature: Allow additional version check on startup - added versionCheckCallback - added apiVersion to DeviceObject - added new versionCheck to memory,cpp * updated source code formatting * changes for PR - (old) version is again part of version check - naming conventions * forgotten parameter in callback * correct wrong buffer initialization * version <-> apiVersion swapped Co-authored-by: Waldemar Porscha <waldemar.porscha@sap.com>
This commit is contained in:
parent
a10fa20bde
commit
22af8267c3
@ -614,6 +614,16 @@ Memory& BauSystemB::memory()
|
|||||||
return _memory;
|
return _memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BauSystemB::versionCheckCallback(VersionCheckCallback func)
|
||||||
|
{
|
||||||
|
_memory.versionCheckCallback(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
VersionCheckCallback BauSystemB::versionCheckCallback()
|
||||||
|
{
|
||||||
|
return _memory.versionCheckCallback();
|
||||||
|
}
|
||||||
|
|
||||||
void BauSystemB::beforeRestartCallback(BeforeRestartCallback func)
|
void BauSystemB::beforeRestartCallback(BeforeRestartCallback func)
|
||||||
{
|
{
|
||||||
_beforeRestart = func;
|
_beforeRestart = func;
|
||||||
|
@ -38,6 +38,8 @@ class BauSystemB : protected BusAccessUnit
|
|||||||
void propertyValueWrite(ObjectType objectType, uint8_t objectInstance, uint8_t propertyId,
|
void propertyValueWrite(ObjectType objectType, uint8_t objectInstance, uint8_t propertyId,
|
||||||
uint8_t& numberOfElements, uint16_t startIndex,
|
uint8_t& numberOfElements, uint16_t startIndex,
|
||||||
uint8_t* data, uint32_t length) override;
|
uint8_t* data, uint32_t length) override;
|
||||||
|
void versionCheckCallback(VersionCheckCallback func);
|
||||||
|
VersionCheckCallback versionCheckCallback();
|
||||||
void beforeRestartCallback(BeforeRestartCallback func);
|
void beforeRestartCallback(BeforeRestartCallback func);
|
||||||
BeforeRestartCallback beforeRestartCallback();
|
BeforeRestartCallback beforeRestartCallback();
|
||||||
|
|
||||||
|
@ -7,6 +7,10 @@
|
|||||||
class DeviceObject: public InterfaceObject
|
class DeviceObject: public InterfaceObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
// increase this version anytime DeviceObject-API changes
|
||||||
|
// the following value represents the serialized representation of DeviceObject.
|
||||||
|
const uint16_t apiVersion = 1;
|
||||||
|
|
||||||
DeviceObject();
|
DeviceObject();
|
||||||
uint8_t* save(uint8_t* buffer) override;
|
uint8_t* save(uint8_t* buffer) override;
|
||||||
const uint8_t* restore(const uint8_t* buffer) override;
|
const uint8_t* restore(const uint8_t* buffer) override;
|
||||||
|
@ -29,38 +29,68 @@ void Memory::readMemory()
|
|||||||
|
|
||||||
_freeList = new MemoryBlock(flashStart + metadataBlockSize, flashSize - metadataBlockSize);
|
_freeList = new MemoryBlock(flashStart + metadataBlockSize, flashSize - metadataBlockSize);
|
||||||
|
|
||||||
|
uint16_t apiVersion = 0;
|
||||||
|
const uint8_t* buffer = popWord(apiVersion, flashStart);
|
||||||
|
|
||||||
uint16_t manufacturerId = 0;
|
uint16_t manufacturerId = 0;
|
||||||
const uint8_t* buffer = popWord(manufacturerId, flashStart);
|
buffer = popWord(manufacturerId, buffer);
|
||||||
|
|
||||||
uint8_t hardwareType[LEN_HARDWARE_TYPE] = {0};
|
uint8_t hardwareType[LEN_HARDWARE_TYPE] = {0};
|
||||||
buffer = popByteArray(hardwareType, LEN_HARDWARE_TYPE, buffer);
|
buffer = popByteArray(hardwareType, LEN_HARDWARE_TYPE, buffer);
|
||||||
|
|
||||||
uint16_t version = 0;
|
uint16_t version = 0;
|
||||||
buffer = popWord(version, buffer);
|
buffer = popWord(version, buffer);
|
||||||
|
|
||||||
|
VersionCheckResult versionCheck = FlashAllInvalid;
|
||||||
|
|
||||||
if (_deviceObject.manufacturerId() != manufacturerId
|
// first check correct format of deviceObject-API
|
||||||
|| _deviceObject.version() != version
|
if (_deviceObject.apiVersion == apiVersion)
|
||||||
|| memcmp(_deviceObject.hardwareType(), hardwareType, LEN_HARDWARE_TYPE) != 0)
|
|
||||||
{
|
{
|
||||||
println("saved memory doesn't match manufacturerId, version or hardwaretype");
|
if (_versionCheckCallback != 0) {
|
||||||
print("manufacturerId: ");
|
versionCheck = _versionCheckCallback(manufacturerId, hardwareType, version);
|
||||||
print(manufacturerId, HEX);
|
// callback should provide infomation about version check failure reasons
|
||||||
print(" ");
|
}
|
||||||
println(_deviceObject.manufacturerId(), HEX);
|
else if (_deviceObject.manufacturerId() == manufacturerId &&
|
||||||
print("version: ");
|
memcmp(_deviceObject.hardwareType(), hardwareType, LEN_HARDWARE_TYPE) == 0)
|
||||||
print(version, HEX);
|
{
|
||||||
print(" ");
|
if (_deviceObject.version() == version) {
|
||||||
println(_deviceObject.version(), HEX);
|
versionCheck = FlashValid;
|
||||||
print("hardwareType: ");
|
}
|
||||||
printHex("", hardwareType, LEN_HARDWARE_TYPE);
|
else
|
||||||
print(" ");
|
{
|
||||||
printHex("", _deviceObject.hardwareType(), LEN_HARDWARE_TYPE);
|
versionCheck = FlashTablesInvalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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(apiVersion, HEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (versionCheck == FlashAllInvalid)
|
||||||
|
{
|
||||||
|
println("ETS has to reprogram PA and application!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
println("manufacturerId, version and hardwareType matches");
|
println("restoring data from flash...");
|
||||||
print("saverestores ");
|
print("saverestores ");
|
||||||
println(_saveCount);
|
println(_saveCount);
|
||||||
for (int i = 0; i < _saveCount; i++)
|
for (int i = 0; i < _saveCount; i++)
|
||||||
@ -70,6 +100,11 @@ void Memory::readMemory()
|
|||||||
buffer = _saveRestores[i]->restore(buffer);
|
buffer = _saveRestores[i]->restore(buffer);
|
||||||
}
|
}
|
||||||
println("restored saveRestores");
|
println("restored saveRestores");
|
||||||
|
if (versionCheck == FlashTablesInvalid)
|
||||||
|
{
|
||||||
|
println("TableObjects are referring to an older firmware version and are not loaded");
|
||||||
|
return;
|
||||||
|
}
|
||||||
print("tableObjs ");
|
print("tableObjs ");
|
||||||
println(_tableObjCount);
|
println(_tableObjCount);
|
||||||
for (int i = 0; i < _tableObjCount; i++)
|
for (int i = 0; i < _tableObjCount; i++)
|
||||||
@ -103,6 +138,7 @@ void Memory::writeMemory()
|
|||||||
uint32_t flashPos = 0;
|
uint32_t flashPos = 0;
|
||||||
uint8_t* bufferPos = buffer;
|
uint8_t* bufferPos = buffer;
|
||||||
|
|
||||||
|
bufferPos = pushWord(_deviceObject.apiVersion, bufferPos);
|
||||||
bufferPos = pushWord(_deviceObject.manufacturerId(), bufferPos);
|
bufferPos = pushWord(_deviceObject.manufacturerId(), bufferPos);
|
||||||
bufferPos = pushByteArray(_deviceObject.hardwareType(), LEN_HARDWARE_TYPE, bufferPos);
|
bufferPos = pushByteArray(_deviceObject.hardwareType(), LEN_HARDWARE_TYPE, bufferPos);
|
||||||
bufferPos = pushWord(_deviceObject.version(), bufferPos);
|
bufferPos = pushWord(_deviceObject.version(), bufferPos);
|
||||||
@ -451,3 +487,13 @@ void Memory::addNewUsedBlock(uint8_t* address, size_t size)
|
|||||||
MemoryBlock* newUsedBlock = new MemoryBlock(address, size);
|
MemoryBlock* newUsedBlock = new MemoryBlock(address, size);
|
||||||
addToUsedList(newUsedBlock);
|
addToUsedList(newUsedBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Memory::versionCheckCallback(VersionCheckCallback func)
|
||||||
|
{
|
||||||
|
_versionCheckCallback = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
VersionCheckCallback Memory::versionCheckCallback()
|
||||||
|
{
|
||||||
|
return _versionCheckCallback;
|
||||||
|
}
|
||||||
|
@ -24,6 +24,15 @@ class MemoryBlock
|
|||||||
MemoryBlock* next = nullptr;
|
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, uint16_t version);
|
||||||
|
|
||||||
class Memory
|
class Memory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -41,6 +50,9 @@ public:
|
|||||||
uint8_t* toAbsolute(uint32_t relativeAddress);
|
uint8_t* toAbsolute(uint32_t relativeAddress);
|
||||||
uint32_t toRelative(uint8_t* absoluteAddress);
|
uint32_t toRelative(uint8_t* absoluteAddress);
|
||||||
|
|
||||||
|
void versionCheckCallback(VersionCheckCallback func);
|
||||||
|
VersionCheckCallback versionCheckCallback();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void removeFromFreeList(MemoryBlock* block);
|
void removeFromFreeList(MemoryBlock* block);
|
||||||
void addToUsedList(MemoryBlock* block);
|
void addToUsedList(MemoryBlock* block);
|
||||||
@ -56,6 +68,7 @@ public:
|
|||||||
uint8_t* eraseBlockEnd(uint32_t blockNum);
|
uint8_t* eraseBlockEnd(uint32_t blockNum);
|
||||||
void saveBufferdEraseBlock();
|
void saveBufferdEraseBlock();
|
||||||
|
|
||||||
|
VersionCheckCallback _versionCheckCallback = 0;
|
||||||
Platform& _platform;
|
Platform& _platform;
|
||||||
DeviceObject& _deviceObject;
|
DeviceObject& _deviceObject;
|
||||||
SaveRestore* _saveRestores[MAXSAVE] = {0};
|
SaveRestore* _saveRestores[MAXSAVE] = {0};
|
||||||
@ -64,5 +77,5 @@ public:
|
|||||||
uint8_t _tableObjCount = 0;
|
uint8_t _tableObjCount = 0;
|
||||||
MemoryBlock* _freeList = nullptr;
|
MemoryBlock* _freeList = nullptr;
|
||||||
MemoryBlock* _usedList = nullptr;
|
MemoryBlock* _usedList = nullptr;
|
||||||
uint16_t _metadataSize = 4 + LEN_HARDWARE_TYPE; // accounting for 2x pushWord and pushByteArray of length LEN_HARDWARE_TYPE
|
uint16_t _metadataSize = 6 + LEN_HARDWARE_TYPE; // accounting for 3x pushWord and pushByteArray of length LEN_HARDWARE_TYPE
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user