mirror of
https://github.com/thelsing/knx.git
synced 2025-05-16 01:16:18 +02:00
-add saveLength to SaveRestore
-undo split of Restore from SaveRestore -add some dynamic memory management to memory-class
This commit is contained in:
parent
2770f5eaa9
commit
8421279d53
@ -78,6 +78,7 @@
|
|||||||
<ClInclude Include="..\src\knx\association_table_object.h" />
|
<ClInclude Include="..\src\knx\association_table_object.h" />
|
||||||
<ClInclude Include="..\src\knx\bau.h" />
|
<ClInclude Include="..\src\knx\bau.h" />
|
||||||
<ClInclude Include="..\src\knx\bau07B0.h" />
|
<ClInclude Include="..\src\knx\bau07B0.h" />
|
||||||
|
<ClInclude Include="..\src\knx\bau27B0.h" />
|
||||||
<ClInclude Include="..\src\knx\bau57B0.h" />
|
<ClInclude Include="..\src\knx\bau57B0.h" />
|
||||||
<ClInclude Include="..\src\knx\bau_systemB.h" />
|
<ClInclude Include="..\src\knx\bau_systemB.h" />
|
||||||
<ClInclude Include="..\src\knx\bits.h" />
|
<ClInclude Include="..\src\knx\bits.h" />
|
||||||
@ -98,6 +99,9 @@
|
|||||||
<ClInclude Include="..\src\knx\npdu.h" />
|
<ClInclude Include="..\src\knx\npdu.h" />
|
||||||
<ClInclude Include="..\src\knx\platform.h" />
|
<ClInclude Include="..\src\knx\platform.h" />
|
||||||
<ClInclude Include="..\src\knx\property_types.h" />
|
<ClInclude Include="..\src\knx\property_types.h" />
|
||||||
|
<ClInclude Include="..\src\knx\rf_data_link_layer.h" />
|
||||||
|
<ClInclude Include="..\src\knx\rf_medium_object.h" />
|
||||||
|
<ClInclude Include="..\src\knx\rf_physical_layer.h" />
|
||||||
<ClInclude Include="..\src\knx\save_restore.h" />
|
<ClInclude Include="..\src\knx\save_restore.h" />
|
||||||
<ClInclude Include="..\src\knx\table_object.h" />
|
<ClInclude Include="..\src\knx\table_object.h" />
|
||||||
<ClInclude Include="..\src\knx\tpdu.h" />
|
<ClInclude Include="..\src\knx\tpdu.h" />
|
||||||
@ -121,6 +125,7 @@
|
|||||||
<ClCompile Include="..\src\knx\association_table_object.cpp" />
|
<ClCompile Include="..\src\knx\association_table_object.cpp" />
|
||||||
<ClCompile Include="..\src\knx\bau.cpp" />
|
<ClCompile Include="..\src\knx\bau.cpp" />
|
||||||
<ClCompile Include="..\src\knx\bau07B0.cpp" />
|
<ClCompile Include="..\src\knx\bau07B0.cpp" />
|
||||||
|
<ClCompile Include="..\src\knx\bau27B0.cpp" />
|
||||||
<ClCompile Include="..\src\knx\bau57B0.cpp" />
|
<ClCompile Include="..\src\knx\bau57B0.cpp" />
|
||||||
<ClCompile Include="..\src\knx\bau_systemB.cpp" />
|
<ClCompile Include="..\src\knx\bau_systemB.cpp" />
|
||||||
<ClCompile Include="..\src\knx\bits.cpp" />
|
<ClCompile Include="..\src\knx\bits.cpp" />
|
||||||
@ -139,6 +144,9 @@
|
|||||||
<ClCompile Include="..\src\knx\network_layer.cpp" />
|
<ClCompile Include="..\src\knx\network_layer.cpp" />
|
||||||
<ClCompile Include="..\src\knx\npdu.cpp" />
|
<ClCompile Include="..\src\knx\npdu.cpp" />
|
||||||
<ClCompile Include="..\src\knx\platform.cpp" />
|
<ClCompile Include="..\src\knx\platform.cpp" />
|
||||||
|
<ClCompile Include="..\src\knx\rf_data_link_layer.cpp" />
|
||||||
|
<ClCompile Include="..\src\knx\rf_medium_object.cpp" />
|
||||||
|
<ClCompile Include="..\src\knx\rf_physical_layer.cpp" />
|
||||||
<ClCompile Include="..\src\knx\table_object.cpp" />
|
<ClCompile Include="..\src\knx\table_object.cpp" />
|
||||||
<ClCompile Include="..\src\knx\tpdu.cpp" />
|
<ClCompile Include="..\src\knx\tpdu.cpp" />
|
||||||
<ClCompile Include="..\src\knx\tpuart_data_link_layer.cpp" />
|
<ClCompile Include="..\src\knx\tpuart_data_link_layer.cpp" />
|
||||||
|
@ -137,6 +137,18 @@
|
|||||||
<ClInclude Include="..\src\knx\knx_value.h">
|
<ClInclude Include="..\src\knx\knx_value.h">
|
||||||
<Filter>Header files\knx</Filter>
|
<Filter>Header files\knx</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\src\knx\bau27B0.h">
|
||||||
|
<Filter>Header files\knx</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\src\knx\rf_data_link_layer.h">
|
||||||
|
<Filter>Header files\knx</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\src\knx\rf_medium_object.h">
|
||||||
|
<Filter>Header files\knx</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\src\knx\rf_physical_layer.h">
|
||||||
|
<Filter>Header files\knx</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\src\knx\address_table_object.cpp">
|
<ClCompile Include="..\src\knx\address_table_object.cpp">
|
||||||
@ -235,5 +247,17 @@
|
|||||||
<ClCompile Include="..\src\knx\knx_value.cpp">
|
<ClCompile Include="..\src\knx\knx_value.cpp">
|
||||||
<Filter>Source files\knx</Filter>
|
<Filter>Source files\knx</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\knx\bau27B0.cpp">
|
||||||
|
<Filter>Source files\knx</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\knx\rf_data_link_layer.cpp">
|
||||||
|
<Filter>Source files\knx</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\knx\rf_medium_object.cpp">
|
||||||
|
<Filter>Source files\knx</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\knx\rf_physical_layer.cpp">
|
||||||
|
<Filter>Source files\knx</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -50,11 +50,6 @@ uint16_t AddressTableObject::getTsap(uint16_t addr)
|
|||||||
|
|
||||||
#pragma region SaveRestore
|
#pragma region SaveRestore
|
||||||
|
|
||||||
uint8_t* AddressTableObject::save(uint8_t* buffer)
|
|
||||||
{
|
|
||||||
return TableObject::save(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* AddressTableObject::restore(uint8_t* buffer)
|
uint8_t* AddressTableObject::restore(uint8_t* buffer)
|
||||||
{
|
{
|
||||||
buffer = TableObject::restore(buffer);
|
buffer = TableObject::restore(buffer);
|
||||||
|
@ -19,8 +19,8 @@ class AddressTableObject : public TableObject
|
|||||||
*/
|
*/
|
||||||
AddressTableObject(Memory& memory);
|
AddressTableObject(Memory& memory);
|
||||||
void readProperty(PropertyID id, uint32_t start, uint32_t& count, uint8_t* data);
|
void readProperty(PropertyID id, uint32_t start, uint32_t& count, uint8_t* data);
|
||||||
uint8_t* save(uint8_t* buffer);
|
|
||||||
uint8_t* restore(uint8_t* buffer);
|
uint8_t* restore(uint8_t* buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the number of group addresses of the object.
|
* returns the number of group addresses of the object.
|
||||||
*/
|
*/
|
||||||
|
@ -110,3 +110,7 @@ PropertyDescription* ApplicationProgramObject::propertyDescriptions()
|
|||||||
return _propertyDescriptions;
|
return _propertyDescriptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t ApplicationProgramObject::saveSize()
|
||||||
|
{
|
||||||
|
return TableObject::saveSize() + 5;
|
||||||
|
}
|
@ -15,6 +15,7 @@ class ApplicationProgramObject : public TableObject
|
|||||||
uint32_t getInt(uint32_t addr);
|
uint32_t getInt(uint32_t addr);
|
||||||
uint8_t* save(uint8_t* buffer);
|
uint8_t* save(uint8_t* buffer);
|
||||||
uint8_t* restore(uint8_t* buffer);
|
uint8_t* restore(uint8_t* buffer);
|
||||||
|
uint16_t saveSize();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint8_t propertyCount();
|
uint8_t propertyCount();
|
||||||
|
@ -44,11 +44,6 @@ uint16_t AssociationTableObject::getASAP(uint16_t idx)
|
|||||||
return ntohs(_tableData[2 * idx + 2]);
|
return ntohs(_tableData[2 * idx + 2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* AssociationTableObject::save(uint8_t* buffer)
|
|
||||||
{
|
|
||||||
return TableObject::save(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* AssociationTableObject::restore(uint8_t* buffer)
|
uint8_t* AssociationTableObject::restore(uint8_t* buffer)
|
||||||
{
|
{
|
||||||
buffer = TableObject::restore(buffer);
|
buffer = TableObject::restore(buffer);
|
||||||
|
@ -8,7 +8,6 @@ class AssociationTableObject : public TableObject
|
|||||||
AssociationTableObject(Memory& memory);
|
AssociationTableObject(Memory& memory);
|
||||||
void readProperty(PropertyID id, uint32_t start, uint32_t& count, uint8_t* data);
|
void readProperty(PropertyID id, uint32_t start, uint32_t& count, uint8_t* data);
|
||||||
|
|
||||||
uint8_t* save(uint8_t* buffer);
|
|
||||||
uint8_t* restore(uint8_t* buffer);
|
uint8_t* restore(uint8_t* buffer);
|
||||||
|
|
||||||
int32_t translateAsap(uint16_t asap);
|
int32_t translateAsap(uint16_t asap);
|
||||||
|
@ -11,7 +11,7 @@ enum NmReadSerialNumberType
|
|||||||
NM_Read_SerialNumber_By_ManufacturerSpecific = 0xFE,
|
NM_Read_SerialNumber_By_ManufacturerSpecific = 0xFE,
|
||||||
};
|
};
|
||||||
|
|
||||||
BauSystemB::BauSystemB(Platform& platform): _memory(platform), _addrTable(_memory),
|
BauSystemB::BauSystemB(Platform& platform): _memory(platform, _deviceObj), _addrTable(_memory),
|
||||||
_assocTable(_memory), _groupObjTable(_memory), _appProgram(_memory),
|
_assocTable(_memory), _groupObjTable(_memory), _appProgram(_memory),
|
||||||
_platform(platform), _appLayer(_assocTable, *this),
|
_platform(platform), _appLayer(_assocTable, *this),
|
||||||
_transLayer(_appLayer, _addrTable), _netLayer(_transLayer)
|
_transLayer(_appLayer, _addrTable), _netLayer(_transLayer)
|
||||||
|
@ -295,3 +295,8 @@ PropertyDescription* DeviceObject::propertyDescriptions()
|
|||||||
{
|
{
|
||||||
return _propertyDescriptions;
|
return _propertyDescriptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t DeviceObject::saveSize()
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
@ -10,6 +10,7 @@ public:
|
|||||||
uint8_t propertySize(PropertyID id);
|
uint8_t propertySize(PropertyID id);
|
||||||
uint8_t* save(uint8_t* buffer);
|
uint8_t* save(uint8_t* buffer);
|
||||||
uint8_t* restore(uint8_t* buffer);
|
uint8_t* restore(uint8_t* buffer);
|
||||||
|
uint16_t saveSize();
|
||||||
void readPropertyDescription(uint8_t propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access);
|
void readPropertyDescription(uint8_t propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access);
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,13 +41,6 @@ GroupObject& GroupObjectTableObject::get(uint16_t asap)
|
|||||||
return _groupObjects[asap - 1];
|
return _groupObjects[asap - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t* GroupObjectTableObject::save(uint8_t* buffer)
|
|
||||||
{
|
|
||||||
return TableObject::save(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t* GroupObjectTableObject::restore(uint8_t* buffer)
|
uint8_t* GroupObjectTableObject::restore(uint8_t* buffer)
|
||||||
{
|
{
|
||||||
buffer = TableObject::restore(buffer);
|
buffer = TableObject::restore(buffer);
|
||||||
|
@ -16,11 +16,10 @@ class GroupObjectTableObject : public TableObject
|
|||||||
GroupObject& nextUpdatedObject(bool& valid);
|
GroupObject& nextUpdatedObject(bool& valid);
|
||||||
void groupObjects(GroupObject* objs, uint16_t size);
|
void groupObjects(GroupObject* objs, uint16_t size);
|
||||||
|
|
||||||
virtual uint8_t* save(uint8_t* buffer);
|
uint8_t* restore(uint8_t* buffer);
|
||||||
virtual uint8_t* restore(uint8_t* buffer);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void beforeStateChange(LoadState& newState);
|
void beforeStateChange(LoadState& newState);
|
||||||
uint8_t propertyCount();
|
uint8_t propertyCount();
|
||||||
PropertyDescription* propertyDescriptions();
|
PropertyDescription* propertyDescriptions();
|
||||||
|
|
||||||
|
@ -320,4 +320,9 @@ uint8_t IpParameterObject::propertyCount()
|
|||||||
PropertyDescription* IpParameterObject::propertyDescriptions()
|
PropertyDescription* IpParameterObject::propertyDescriptions()
|
||||||
{
|
{
|
||||||
return _propertyDescriptions;
|
return _propertyDescriptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t IpParameterObject::saveSize()
|
||||||
|
{
|
||||||
|
return 51;
|
||||||
|
}
|
||||||
|
@ -14,6 +14,7 @@ class IpParameterObject : public InterfaceObject
|
|||||||
|
|
||||||
uint8_t* save(uint8_t* buffer);
|
uint8_t* save(uint8_t* buffer);
|
||||||
uint8_t* restore(uint8_t* buffer);
|
uint8_t* restore(uint8_t* buffer);
|
||||||
|
uint16_t saveSize();
|
||||||
|
|
||||||
uint32_t multicastAddress() const;
|
uint32_t multicastAddress() const;
|
||||||
uint8_t ttl() const { return _ttl; }
|
uint8_t ttl() const { return _ttl; }
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "bits.h"
|
||||||
|
|
||||||
Memory::Memory(Platform & platform): _platform(platform)
|
Memory::Memory(Platform& platform, DeviceObject& deviceObject)
|
||||||
|
: _platform(platform), _deviceObject(deviceObject)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,18 +36,16 @@ void Memory::readMemory()
|
|||||||
|
|
||||||
void Memory::writeMemory()
|
void Memory::writeMemory()
|
||||||
{
|
{
|
||||||
_data[0] = 0x00;
|
uint8_t* buffer = _data;
|
||||||
_data[1] = 0xAD;
|
buffer = pushWord(_deviceObject.manufacturerId(), buffer);
|
||||||
_data[2] = 0xAF;
|
buffer = pushByteArray(_deviceObject.hardwareType(), 6, buffer);
|
||||||
_data[3] = 0xFE;
|
buffer = pushWord(_deviceObject.version(), buffer);
|
||||||
|
|
||||||
uint8_t* buffer = _data + 4;
|
|
||||||
int size = _saveCount;
|
int size = _saveCount;
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
SaveRestore* saveRestore = dynamic_cast<SaveRestore*>(_saveRestores[i]);
|
// TODO: Hande TableObject correctly, i.e. save the size of the buffer somewhere to, so that we can rebuild the usedList and freeList
|
||||||
if(saveRestore)
|
buffer = _saveRestores[i]->save(buffer);
|
||||||
buffer = saveRestore->save(buffer);
|
|
||||||
}
|
}
|
||||||
_platform.commitToEeprom();
|
_platform.commitToEeprom();
|
||||||
_modified = false;
|
_modified = false;
|
||||||
@ -63,13 +63,71 @@ void Memory::addSaveRestore(SaveRestore * obj)
|
|||||||
|
|
||||||
uint8_t* Memory::allocMemory(size_t size)
|
uint8_t* Memory::allocMemory(size_t size)
|
||||||
{
|
{
|
||||||
return _platform.allocMemory(size);
|
// always allocate aligned to 32 bit
|
||||||
|
size = (size + 3) & ~0x3;
|
||||||
|
|
||||||
|
MemoryBlock* freeBlock = _freeList;
|
||||||
|
MemoryBlock* blockToUse = 0;
|
||||||
|
|
||||||
|
// find the smallest possible block that is big enough
|
||||||
|
while (freeBlock)
|
||||||
|
{
|
||||||
|
if (freeBlock->size >= size)
|
||||||
|
{
|
||||||
|
if (blockToUse != 0 && (blockToUse->size - size) > (freeBlock->size - size))
|
||||||
|
blockToUse = freeBlock;
|
||||||
|
}
|
||||||
|
freeBlock = freeBlock->next;
|
||||||
|
}
|
||||||
|
if (!blockToUse)
|
||||||
|
{
|
||||||
|
println("No available non volatile memory!");
|
||||||
|
_platform.fatalError();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockToUse->size == size)
|
||||||
|
{
|
||||||
|
// use whole block
|
||||||
|
removeFromFreeList(blockToUse);
|
||||||
|
addToUsedList(blockToUse);
|
||||||
|
return blockToUse->address;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// split block
|
||||||
|
MemoryBlock* newBlock = new MemoryBlock();
|
||||||
|
newBlock->address = blockToUse->address;
|
||||||
|
newBlock->size = size;
|
||||||
|
addToUsedList(newBlock);
|
||||||
|
|
||||||
|
blockToUse->address += size;
|
||||||
|
blockToUse->size -= size;
|
||||||
|
|
||||||
|
return newBlock->address;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Memory::freeMemory(uint8_t* ptr)
|
void Memory::freeMemory(uint8_t* ptr)
|
||||||
{
|
{
|
||||||
return _platform.freeMemory(ptr);
|
MemoryBlock* block = _usedList;
|
||||||
|
MemoryBlock* found = 0;
|
||||||
|
while (_usedList)
|
||||||
|
{
|
||||||
|
if (block->address == ptr)
|
||||||
|
{
|
||||||
|
found = block;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
block = block->next;
|
||||||
|
}
|
||||||
|
if(!found)
|
||||||
|
{
|
||||||
|
println("freeMemory for not used pointer called");
|
||||||
|
_platform.fatalError();
|
||||||
|
}
|
||||||
|
removeFromUsedList(block);
|
||||||
|
addToFreeList(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Memory::writeMemory(uint32_t relativeAddress, size_t size, uint8_t* data)
|
void Memory::writeMemory(uint32_t relativeAddress, size_t size, uint8_t* data)
|
||||||
@ -81,11 +139,110 @@ void Memory::writeMemory(uint32_t relativeAddress, size_t size, uint8_t* data)
|
|||||||
|
|
||||||
uint8_t* Memory::toAbsolute(uint32_t relativeAddress)
|
uint8_t* Memory::toAbsolute(uint32_t relativeAddress)
|
||||||
{
|
{
|
||||||
return _platform.memoryReference() + (ptrdiff_t)relativeAddress;
|
return _data + (ptrdiff_t)relativeAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t Memory::toRelative(uint8_t* absoluteAddress)
|
uint32_t Memory::toRelative(uint8_t* absoluteAddress)
|
||||||
{
|
{
|
||||||
return absoluteAddress - _platform.memoryReference();
|
return absoluteAddress - _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryBlock* Memory::removeFromList(MemoryBlock* head, MemoryBlock* item)
|
||||||
|
{
|
||||||
|
if (head == item)
|
||||||
|
{
|
||||||
|
MemoryBlock* newHead = head->next;
|
||||||
|
head->next = 0;
|
||||||
|
return newHead;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!head || !item)
|
||||||
|
{
|
||||||
|
println("invalid parameters of Memory::removeFromList");
|
||||||
|
_platform.fatalError();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
while (head)
|
||||||
|
{
|
||||||
|
if (head->next == item)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
head->next = item->next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
head = head->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
println("tried to remove block from list not in it");
|
||||||
|
_platform.fatalError();
|
||||||
|
}
|
||||||
|
item->next = 0;
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Memory::removeFromFreeList(MemoryBlock* block)
|
||||||
|
{
|
||||||
|
_freeList = removeFromList(_freeList, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Memory::removeFromUsedList(MemoryBlock* block)
|
||||||
|
{
|
||||||
|
_usedList = removeFromList(_usedList, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Memory::addToUsedList(MemoryBlock* block)
|
||||||
|
{
|
||||||
|
block->next = _usedList;
|
||||||
|
_usedList = block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Memory::addToFreeList(MemoryBlock* block)
|
||||||
|
{
|
||||||
|
if (_freeList == 0)
|
||||||
|
{
|
||||||
|
_freeList = block;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// first insert free block in list
|
||||||
|
MemoryBlock* current = _freeList;
|
||||||
|
while (current)
|
||||||
|
{
|
||||||
|
if (current->address <= block->address && (block->next == 0 || block->address < current->next->address))
|
||||||
|
{
|
||||||
|
block->next = current->next;
|
||||||
|
current->next = block;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
// now check if we can merge the blocks
|
||||||
|
// first current an block
|
||||||
|
if ((current->address + current->size) == block->address)
|
||||||
|
{
|
||||||
|
current->size += block->size;
|
||||||
|
current->next = block->next;
|
||||||
|
delete block;
|
||||||
|
// check further if now current can be merged with current->next
|
||||||
|
block = current;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if block is the last one, we are done
|
||||||
|
if (block->next == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// now check block and block->next
|
||||||
|
if ((block->address + block->size) == block->next->address)
|
||||||
|
{
|
||||||
|
block->size += block->next->size;
|
||||||
|
block->next = block->next->next;
|
||||||
|
delete block->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,21 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "save_restore.h"
|
#include "save_restore.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
#include "device_object.h"
|
||||||
|
|
||||||
#define MAXSAVE 10
|
#define MAXSAVE 10
|
||||||
|
|
||||||
|
typedef struct _memoryBlock
|
||||||
|
{
|
||||||
|
uint8_t* address;
|
||||||
|
size_t size;
|
||||||
|
struct _memoryBlock* next;
|
||||||
|
} MemoryBlock;
|
||||||
|
|
||||||
class Memory
|
class Memory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Memory(Platform& platform);
|
Memory(Platform& platform, DeviceObject& deviceObject);
|
||||||
void memoryModified();
|
void memoryModified();
|
||||||
bool isMemoryModified();
|
bool isMemoryModified();
|
||||||
void readMemory();
|
void readMemory();
|
||||||
@ -23,9 +31,18 @@ public:
|
|||||||
uint32_t toRelative(uint8_t* absoluteAddress);
|
uint32_t toRelative(uint8_t* absoluteAddress);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void removeFromFreeList(MemoryBlock* block);
|
||||||
|
void addToUsedList(MemoryBlock* block);
|
||||||
|
void removeFromUsedList(MemoryBlock* block);
|
||||||
|
void addToFreeList(MemoryBlock* block);
|
||||||
|
MemoryBlock* removeFromList(MemoryBlock* head, MemoryBlock* item);
|
||||||
|
|
||||||
Platform& _platform;
|
Platform& _platform;
|
||||||
|
DeviceObject& _deviceObject;
|
||||||
bool _modified = false;
|
bool _modified = false;
|
||||||
Restore* _saveRestores[MAXSAVE] = {0};
|
SaveRestore* _saveRestores[MAXSAVE] = {0};
|
||||||
int _saveCount = 0;
|
int _saveCount = 0;
|
||||||
uint8_t* _data = 0;
|
uint8_t* _data = 0;
|
||||||
|
MemoryBlock* _freeList = 0;
|
||||||
|
MemoryBlock* _usedList = 0;
|
||||||
};
|
};
|
||||||
|
@ -8,19 +8,23 @@ class Platform
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Platform();
|
Platform();
|
||||||
|
// ip config
|
||||||
virtual uint32_t currentIpAddress() = 0;
|
virtual uint32_t currentIpAddress() = 0;
|
||||||
virtual uint32_t currentSubnetMask() = 0;
|
virtual uint32_t currentSubnetMask() = 0;
|
||||||
virtual uint32_t currentDefaultGateway() = 0;
|
virtual uint32_t currentDefaultGateway() = 0;
|
||||||
virtual void macAddress(uint8_t* data) = 0;
|
virtual void macAddress(uint8_t* data) = 0;
|
||||||
|
|
||||||
|
// basic stuff
|
||||||
virtual void restart() = 0;
|
virtual void restart() = 0;
|
||||||
virtual void fatalError() = 0;
|
virtual void fatalError() = 0;
|
||||||
|
|
||||||
|
//multicast socket
|
||||||
virtual void setupMultiCast(uint32_t addr, uint16_t port) = 0;
|
virtual void setupMultiCast(uint32_t addr, uint16_t port) = 0;
|
||||||
virtual void closeMultiCast() = 0;
|
virtual void closeMultiCast() = 0;
|
||||||
virtual bool sendBytes(uint8_t* buffer, uint16_t len) = 0;
|
virtual bool sendBytes(uint8_t* buffer, uint16_t len) = 0;
|
||||||
virtual int readBytes(uint8_t* buffer, uint16_t maxLen) = 0;
|
virtual int readBytes(uint8_t* buffer, uint16_t maxLen) = 0;
|
||||||
|
|
||||||
|
//UART
|
||||||
virtual void setupUart() = 0;
|
virtual void setupUart() = 0;
|
||||||
virtual void closeUart() = 0;
|
virtual void closeUart() = 0;
|
||||||
virtual int uartAvailable() = 0;
|
virtual int uartAvailable() = 0;
|
||||||
@ -29,10 +33,19 @@ class Platform
|
|||||||
virtual int readUart() = 0;
|
virtual int readUart() = 0;
|
||||||
virtual size_t readBytesUart(uint8_t* buffer, size_t length) = 0;
|
virtual size_t readBytesUart(uint8_t* buffer, size_t length) = 0;
|
||||||
|
|
||||||
|
// SPI
|
||||||
virtual void setupSpi() = 0;
|
virtual void setupSpi() = 0;
|
||||||
virtual void closeSpi() = 0;
|
virtual void closeSpi() = 0;
|
||||||
virtual int readWriteSpi (uint8_t *data, size_t len) = 0;
|
virtual int readWriteSpi (uint8_t *data, size_t len) = 0;
|
||||||
|
#if 0
|
||||||
|
// Flash memory
|
||||||
|
virtual size_t flashEraseBlockSize(); // in pages
|
||||||
|
virtual size_t flashPageSize(); // in bytes
|
||||||
|
virtual uint8_t* userFlashStart(); // start of user flash aligned to start of an erase block
|
||||||
|
virtual size_t userFlashSizeEraseBlocks(); // in eraseBlocks
|
||||||
|
virtual void flashErase(uint16_t eraseBlockNum); //relativ to userFlashStart
|
||||||
|
virtual void flashWritePage(uint16_t pageNumber, uint8_t* data); //write a single page to flash (pageNumber relative to userFashStart
|
||||||
|
#endif
|
||||||
virtual uint8_t* getEepromBuffer(uint16_t size) = 0;
|
virtual uint8_t* getEepromBuffer(uint16_t size) = 0;
|
||||||
virtual void commitToEeprom() = 0;
|
virtual void commitToEeprom() = 0;
|
||||||
|
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for classes that can restore data from a buffer.
|
|
||||||
*/
|
|
||||||
class Restore
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* This method is called when the object should restore its state from the buffer.
|
|
||||||
*
|
|
||||||
* @param buffer The buffer the object should restore its state from.
|
|
||||||
*
|
|
||||||
* @return The buffer plus the size of the object state. The next object will use this value as
|
|
||||||
* the start of its buffer.
|
|
||||||
*/
|
|
||||||
virtual uint8_t* restore(uint8_t* buffer) = 0;
|
|
||||||
};
|
|
@ -98,6 +98,11 @@ uint8_t* RfMediumObject::restore(uint8_t* buffer)
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t RfMediumObject::saveSize()
|
||||||
|
{
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t* RfMediumObject::rfDomainAddress()
|
uint8_t* RfMediumObject::rfDomainAddress()
|
||||||
{
|
{
|
||||||
return _rfDomainAddress;
|
return _rfDomainAddress;
|
||||||
|
@ -10,6 +10,7 @@ public:
|
|||||||
uint8_t propertySize(PropertyID id);
|
uint8_t propertySize(PropertyID id);
|
||||||
uint8_t* save(uint8_t* buffer);
|
uint8_t* save(uint8_t* buffer);
|
||||||
uint8_t* restore(uint8_t* buffer);
|
uint8_t* restore(uint8_t* buffer);
|
||||||
|
uint16_t saveSize();
|
||||||
void readPropertyDescription(uint8_t propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access);
|
void readPropertyDescription(uint8_t propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access);
|
||||||
|
|
||||||
uint8_t* rfDomainAddress();
|
uint8_t* rfDomainAddress();
|
||||||
@ -22,6 +23,4 @@ private:
|
|||||||
uint8_t _rfDomainAddress[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // see KNX RF S-Mode AN160 p.11
|
uint8_t _rfDomainAddress[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // see KNX RF S-Mode AN160 p.11
|
||||||
uint8_t _rfDiagSourceAddressFilterTable[24] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};
|
uint8_t _rfDiagSourceAddressFilterTable[24] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};
|
||||||
uint8_t _rfDiagLinkBudgetTable[24] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};
|
uint8_t _rfDiagLinkBudgetTable[24] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
@ -1,11 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "restore.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for classes that can save and restore data from a buffer.
|
* Interface for classes that can save and restore data from a buffer.
|
||||||
*/
|
*/
|
||||||
class SaveRestore : public Restore
|
class SaveRestore
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -17,4 +16,17 @@ class SaveRestore : public Restore
|
|||||||
* the start of its buffer.
|
* the start of its buffer.
|
||||||
*/
|
*/
|
||||||
virtual uint8_t* save(uint8_t* buffer) = 0;
|
virtual uint8_t* save(uint8_t* buffer) = 0;
|
||||||
|
/**
|
||||||
|
* This method is called when the object should restore its state from the buffer.
|
||||||
|
*
|
||||||
|
* @param buffer The buffer the object should restore its state from.
|
||||||
|
*
|
||||||
|
* @return The buffer plus the size of the object state. The next object will use this value as
|
||||||
|
* the start of its buffer.
|
||||||
|
*/
|
||||||
|
virtual uint8_t* restore(uint8_t* buffer) = 0;
|
||||||
|
/**
|
||||||
|
* @return The number of byte the object needs to save its state.
|
||||||
|
*/
|
||||||
|
virtual uint16_t saveSize() = 0;
|
||||||
};
|
};
|
@ -86,8 +86,11 @@ uint8_t* TableObject::save(uint8_t* buffer)
|
|||||||
{
|
{
|
||||||
buffer = pushByte(_state, buffer);
|
buffer = pushByte(_state, buffer);
|
||||||
buffer = pushByte(_errorCode, buffer);
|
buffer = pushByte(_errorCode, buffer);
|
||||||
buffer = pushInt(_size, buffer);
|
|
||||||
buffer = pushByteArray(_data, _size, buffer);
|
if (_data)
|
||||||
|
buffer = pushInt(_memory.toRelative(_data), buffer);
|
||||||
|
else
|
||||||
|
buffer = pushInt(0, buffer);
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
@ -102,18 +105,14 @@ uint8_t* TableObject::restore(uint8_t* buffer)
|
|||||||
_state = (LoadState)state;
|
_state = (LoadState)state;
|
||||||
_errorCode = (ErrorCode)errorCode;
|
_errorCode = (ErrorCode)errorCode;
|
||||||
|
|
||||||
buffer = popInt(_size, buffer);
|
uint32_t relativeAddress = 0;
|
||||||
|
buffer = popInt(relativeAddress, buffer);
|
||||||
|
|
||||||
if (_data)
|
if (relativeAddress != 0)
|
||||||
_memory.freeMemory(_data);
|
_data = _memory.toAbsolute(relativeAddress);
|
||||||
|
|
||||||
if (_size > 0)
|
|
||||||
_data = _memory.allocMemory(_size);
|
|
||||||
else
|
else
|
||||||
_data = 0;
|
_data = 0;
|
||||||
|
|
||||||
buffer = popByteArray(_data, _size, buffer);
|
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +127,6 @@ bool TableObject::allocTable(uint32_t size, bool doFill, uint8_t fillByte)
|
|||||||
{
|
{
|
||||||
_memory.freeMemory(_data);
|
_memory.freeMemory(_data);
|
||||||
_data = 0;
|
_data = 0;
|
||||||
_size = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
@ -138,8 +136,6 @@ bool TableObject::allocTable(uint32_t size, bool doFill, uint8_t fillByte)
|
|||||||
if (!_data)
|
if (!_data)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_size = size;
|
|
||||||
|
|
||||||
if (doFill)
|
if (doFill)
|
||||||
memset(_data, fillByte, size);
|
memset(_data, fillByte, size);
|
||||||
|
|
||||||
@ -277,12 +273,12 @@ uint8_t* TableObject::data()
|
|||||||
return _data;
|
return _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t TableObject::size()
|
|
||||||
{
|
|
||||||
return _size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TableObject::errorCode(ErrorCode errorCode)
|
void TableObject::errorCode(ErrorCode errorCode)
|
||||||
{
|
{
|
||||||
_errorCode = errorCode;
|
_errorCode = errorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t TableObject::saveSize()
|
||||||
|
{
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
@ -27,6 +27,7 @@ public:
|
|||||||
LoadState loadState();
|
LoadState loadState();
|
||||||
virtual uint8_t* save(uint8_t* buffer);
|
virtual uint8_t* save(uint8_t* buffer);
|
||||||
virtual uint8_t* restore(uint8_t* buffer);
|
virtual uint8_t* restore(uint8_t* buffer);
|
||||||
|
uint16_t saveSize();
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* This method is called before the interface object enters a new ::LoadState.
|
* This method is called before the interface object enters a new ::LoadState.
|
||||||
@ -40,10 +41,6 @@ protected:
|
|||||||
* must not be freed.
|
* must not be freed.
|
||||||
*/
|
*/
|
||||||
uint8_t* data();
|
uint8_t* data();
|
||||||
/**
|
|
||||||
* returns the size of the internal data of the interface object int byte.
|
|
||||||
*/
|
|
||||||
uint32_t size();
|
|
||||||
/**
|
/**
|
||||||
* Set the reason for a state change failure.
|
* Set the reason for a state change failure.
|
||||||
*/
|
*/
|
||||||
@ -69,6 +66,5 @@ protected:
|
|||||||
LoadState _state = LS_UNLOADED;
|
LoadState _state = LS_UNLOADED;
|
||||||
Memory& _memory;
|
Memory& _memory;
|
||||||
uint8_t *_data = 0;
|
uint8_t *_data = 0;
|
||||||
uint32_t _size = 0;
|
|
||||||
ErrorCode _errorCode = E_NO_FAULT;
|
ErrorCode _errorCode = E_NO_FAULT;
|
||||||
};
|
};
|
||||||
|
@ -285,6 +285,7 @@ template <class P, class B> class KnxFacade : private SaveRestore
|
|||||||
saveRestoreCallback _restoreCallback = 0;
|
saveRestoreCallback _restoreCallback = 0;
|
||||||
bool _toogleProgMode = false;
|
bool _toogleProgMode = false;
|
||||||
bool _progLedState = false;
|
bool _progLedState = false;
|
||||||
|
uint16_t _saveSize = 0;
|
||||||
|
|
||||||
uint8_t* save(uint8_t* buffer)
|
uint8_t* save(uint8_t* buffer)
|
||||||
{
|
{
|
||||||
@ -301,6 +302,16 @@ template <class P, class B> class KnxFacade : private SaveRestore
|
|||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t saveSize()
|
||||||
|
{
|
||||||
|
return _saveSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveSize(uint16_t size)
|
||||||
|
{
|
||||||
|
_saveSize = size;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef ARDUINO_ARCH_SAMD
|
#ifdef ARDUINO_ARCH_SAMD
|
||||||
|
Loading…
Reference in New Issue
Block a user