delegate memory management for knx tables to Platform class. Preallocate memory for them on linux.

This commit is contained in:
Thomas Kunze 2018-12-12 23:17:42 +01:00
parent bdaca43642
commit bd93aa12fa
22 changed files with 107 additions and 48 deletions

View File

@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 2.7)
project(knx) project(knx)
set(LIBRARIES_FROM_REFERENCES "") set(LIBRARIES_FROM_REFERENCES "")
add_library(knx SHARED ../src/knx/address_table_object.cpp ../src/knx/apdu.cpp ../src/knx/application_layer.cpp ../src/knx/application_program_object.cpp ../src/knx/association_table_object.cpp ../src/knx/bau.cpp ../src/knx/bau07B0.cpp ../src/knx/bau57B0.cpp ../src/knx/bau_systemB.cpp ../src/knx/bits.cpp ../src/knx/cemi_frame.cpp ../src/knx/datapoint_types.cpp ../src/knx/data_link_layer.cpp ../src/knx/device_object.cpp ../src/knx/group_object.cpp ../src/knx/group_object_table_object.cpp ../src/knx/interface_object.cpp ../src/knx/ip_data_link_layer.cpp ../src/knx/ip_parameter_object.cpp ../src/knx/memory.cpp ../src/knx/network_layer.cpp ../src/knx/npdu.cpp ../src/knx/table_object.cpp ../src/knx/tpdu.cpp ../src/knx/tpuart_data_link_layer.cpp ../src/knx/transport_layer.cpp ../src/linux_platform.cpp knxmodule.cpp) add_library(knx SHARED ../src/knx/address_table_object.cpp ../src/knx/apdu.cpp ../src/knx/application_layer.cpp ../src/knx/application_program_object.cpp ../src/knx/association_table_object.cpp ../src/knx/bau.cpp ../src/knx/bau07B0.cpp ../src/knx/bau57B0.cpp ../src/knx/bau_systemB.cpp ../src/knx/bits.cpp ../src/knx/cemi_frame.cpp ../src/knx/datapoint_types.cpp ../src/knx/data_link_layer.cpp ../src/knx/device_object.cpp ../src/knx/group_object.cpp ../src/knx/group_object_table_object.cpp ../src/knx/interface_object.cpp ../src/knx/ip_data_link_layer.cpp ../src/knx/ip_parameter_object.cpp ../src/knx/memory.cpp ../src/knx/network_layer.cpp ../src/knx/npdu.cpp ../src/knx/platform.cpp ../src/knx/table_object.cpp ../src/knx/tpdu.cpp ../src/knx/tpuart_data_link_layer.cpp ../src/knx/transport_layer.cpp ../src/linux_platform.cpp knxmodule.cpp)
target_link_libraries(knx python3.5m "${LIBRARIES_FROM_REFERENCES}") target_link_libraries(knx python3.5m "${LIBRARIES_FROM_REFERENCES}")
include_directories(/usr/include/python3.5m ../src) include_directories(/usr/include/python3.5m ../src)
SET_TARGET_PROPERTIES(knx PROPERTIES PREFIX "") SET_TARGET_PROPERTIES(knx PROPERTIES PREFIX "")

View File

@ -7,5 +7,5 @@ project(knx)
set(LIBRARIES_FROM_REFERENCES "") set(LIBRARIES_FROM_REFERENCES "")
add_library(knx SHARED ../src/knx/address_table_object.cpp ../src/knx/apdu.cpp ../src/knx/application_layer.cpp ../src/knx/application_program_object.cpp ../src/knx/association_table_object.cpp ../src/knx/bau.cpp ../src/knx/bau07B0.cpp ../src/knx/bau57B0.cpp ../src/knx/bau_systemB.cpp ../src/knx/bits.cpp ../src/knx/cemi_frame.cpp ../src/knx/datapoint_types.cpp ../src/knx/data_link_layer.cpp ../src/knx/device_object.cpp ../src/knx/group_object.cpp ../src/knx/group_object_table_object.cpp ../src/knx/interface_object.cpp ../src/knx/ip_data_link_layer.cpp ../src/knx/ip_parameter_object.cpp ../src/knx/memory.cpp ../src/knx/network_layer.cpp ../src/knx/npdu.cpp ../src/knx/table_object.cpp ../src/knx/tpdu.cpp ../src/knx/tpuart_data_link_layer.cpp ../src/knx/transport_layer.cpp ../src/linux_platform.cpp knxmodule.cpp) add_library(knx SHARED ../src/knx/address_table_object.cpp ../src/knx/apdu.cpp ../src/knx/application_layer.cpp ../src/knx/application_program_object.cpp ../src/knx/association_table_object.cpp ../src/knx/bau.cpp ../src/knx/bau07B0.cpp ../src/knx/bau57B0.cpp ../src/knx/bau_systemB.cpp ../src/knx/bits.cpp ../src/knx/cemi_frame.cpp ../src/knx/datapoint_types.cpp ../src/knx/data_link_layer.cpp ../src/knx/device_object.cpp ../src/knx/group_object.cpp ../src/knx/group_object_table_object.cpp ../src/knx/interface_object.cpp ../src/knx/ip_data_link_layer.cpp ../src/knx/ip_parameter_object.cpp ../src/knx/memory.cpp ../src/knx/network_layer.cpp ../src/knx/npdu.cpp ../src/knx/table_object.cpp ../src/knx/tpdu.cpp ../src/knx/tpuart_data_link_layer.cpp ../src/knx/transport_layer.cpp ../src/linux_platform.cpp knxmodule.cpp)
target_link_libraries(knx python3.5m "${LIBRARIES_FROM_REFERENCES}") target_link_libraries(knx python3.5m "${LIBRARIES_FROM_REFERENCES}")
include_directories(/usr/include/python3.5m) include_directories(/usr/include/python3.5m ../src)
SET_TARGET_PROPERTIES(knx PROPERTIES PREFIX "") SET_TARGET_PROPERTIES(knx PROPERTIES PREFIX "")

View File

@ -128,6 +128,7 @@
<ClCompile Include="..\src\knx\memory.cpp" /> <ClCompile Include="..\src\knx\memory.cpp" />
<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\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" />

View File

@ -122,6 +122,9 @@
<ClCompile Include="..\src\knx\transport_layer.cpp"> <ClCompile Include="..\src\knx\transport_layer.cpp">
<Filter>Source files\knx</Filter> <Filter>Source files\knx</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\src\knx\platform.cpp">
<Filter>Source files\knx</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\src\linux_platform.h"> <ClInclude Include="..\src\linux_platform.h">

View File

@ -171,4 +171,4 @@ size_t EspPlatform::readBytesUart(uint8_t *buffer, size_t length)
printHex("p>", buffer, length); printHex("p>", buffer, length);
return length; return length;
} }
#endif #endif

View File

@ -6,7 +6,8 @@
using namespace std; using namespace std;
AddressTableObject::AddressTableObject(uint8_t* memoryReference): TableObject(memoryReference) AddressTableObject::AddressTableObject(Platform& platform)
: TableObject(platform)
{ {
} }

View File

@ -5,11 +5,8 @@
class AddressTableObject: public TableObject class AddressTableObject: public TableObject
{ {
public: public:
AddressTableObject(uint8_t* memoryReference); AddressTableObject(Platform& platform);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Woverloaded-virtual"
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);
#pragma GCC diagnostic pop
uint16_t entryCount(); uint16_t entryCount();
uint16_t getGa(uint16_t tsap); uint16_t getGa(uint16_t tsap);
uint16_t getTsap(uint16_t ga); uint16_t getTsap(uint16_t ga);

View File

@ -1,7 +1,8 @@
#include "application_program_object.h" #include "application_program_object.h"
#include "bits.h" #include "bits.h"
ApplicationProgramObject::ApplicationProgramObject(uint8_t* memoryReference): TableObject(memoryReference) ApplicationProgramObject::ApplicationProgramObject(Platform& platform)
: TableObject(platform)
{ {
} }

View File

@ -5,11 +5,8 @@
class ApplicationProgramObject: public TableObject class ApplicationProgramObject: public TableObject
{ {
public: public:
ApplicationProgramObject(uint8_t* memoryReference); ApplicationProgramObject(Platform& platform);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Woverloaded-virtual"
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);
#pragma GCC diagnostic pop
void writeProperty(PropertyID id, uint8_t start, uint8_t* data, uint8_t count); void writeProperty(PropertyID id, uint8_t start, uint8_t* data, uint8_t count);
uint8_t propertySize(PropertyID id); uint8_t propertySize(PropertyID id);
uint8_t* data(uint32_t addr); uint8_t* data(uint32_t addr);

View File

@ -6,7 +6,8 @@
using namespace std; using namespace std;
AssociationTableObject::AssociationTableObject(uint8_t* memoryReference): TableObject(memoryReference) AssociationTableObject::AssociationTableObject(Platform& platform)
: TableObject(platform)
{ {
} }

View File

@ -5,11 +5,8 @@
class AssociationTableObject: public TableObject class AssociationTableObject: public TableObject
{ {
public: public:
AssociationTableObject(uint8_t* memoryReference); AssociationTableObject(Platform& platform);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Woverloaded-virtual"
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);
#pragma GCC diagnostic pop
uint16_t entryCount(); uint16_t entryCount();
uint16_t operator[](uint16_t idx); uint16_t operator[](uint16_t idx);
uint8_t* save(uint8_t* buffer); uint8_t* save(uint8_t* buffer);

View File

@ -2,8 +2,8 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
BauSystemB::BauSystemB(Platform& platform): _memoryReference((uint8_t*)&_deviceObj), _memory(platform), _addrTable(_memoryReference), BauSystemB::BauSystemB(Platform& platform): _memory(platform), _addrTable(platform),
_assocTable(_memoryReference), _groupObjTable(_memoryReference), _appProgram(_memoryReference), _assocTable(platform), _groupObjTable(platform), _appProgram(platform),
_platform(platform), _appLayer(_assocTable, *this), _platform(platform), _appLayer(_assocTable, *this),
_transLayer(_appLayer, _addrTable, _platform), _netLayer(_transLayer) _transLayer(_appLayer, _addrTable, _platform), _netLayer(_transLayer)
{ {
@ -138,7 +138,7 @@ void BauSystemB::deviceDescriptorReadIndication(Priority priority, HopCountType
void BauSystemB::memoryWriteIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, void BauSystemB::memoryWriteIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t number,
uint16_t memoryAddress, uint8_t * data) uint16_t memoryAddress, uint8_t * data)
{ {
memcpy(_memoryReference + memoryAddress, data, number); memcpy(_platform.memoryReference() + memoryAddress, data, number);
_memory.memoryModified(); _memory.memoryModified();
if (_deviceObj.verifyMode()) if (_deviceObj.verifyMode())
@ -149,7 +149,7 @@ void BauSystemB::memoryReadIndication(Priority priority, HopCountType hopType, u
uint16_t memoryAddress) uint16_t memoryAddress)
{ {
_appLayer.memoryReadResponse(AckRequested, priority, hopType, asap, number, memoryAddress, _appLayer.memoryReadResponse(AckRequested, priority, hopType, asap, number, memoryAddress,
_memoryReference + memoryAddress); _platform.memoryReference() + memoryAddress);
} }
void BauSystemB::restartRequestIndication(Priority priority, HopCountType hopType, uint16_t asap) void BauSystemB::restartRequestIndication(Priority priority, HopCountType hopType, uint16_t asap)
@ -160,6 +160,7 @@ void BauSystemB::restartRequestIndication(Priority priority, HopCountType hopTyp
_platform.restart(); _platform.restart();
// for platforms that don't really restart // for platforms that don't really restart
_memory.readMemory();
_deviceObj.progMode(false); _deviceObj.progMode(false);
_configured = true; _configured = true;
} }
@ -172,12 +173,12 @@ void BauSystemB::authorizeIndication(Priority priority, HopCountType hopType, ui
void BauSystemB::userMemoryReadIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, uint32_t memoryAddress) void BauSystemB::userMemoryReadIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, uint32_t memoryAddress)
{ {
_appLayer.userMemoryReadResponse(AckRequested, priority, hopType, asap, number, memoryAddress, _appLayer.userMemoryReadResponse(AckRequested, priority, hopType, asap, number, memoryAddress,
_memoryReference + memoryAddress); _platform.memoryReference() + memoryAddress);
} }
void BauSystemB::userMemoryWriteIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, uint32_t memoryAddress, uint8_t* data) void BauSystemB::userMemoryWriteIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, uint32_t memoryAddress, uint8_t* data)
{ {
memcpy(_memoryReference + memoryAddress, data, number); memcpy(_platform.memoryReference() + memoryAddress, data, number);
_memory.memoryModified(); _memory.memoryModified();
if (_deviceObj.verifyMode()) if (_deviceObj.verifyMode())

View File

@ -62,9 +62,6 @@ protected:
void updateGroupObject(GroupObject& go, uint8_t* data, uint8_t length); void updateGroupObject(GroupObject& go, uint8_t* data, uint8_t length);
DeviceObject _deviceObj; DeviceObject _deviceObj;
// pointer to first private variable as reference to memory read/write commands
// addesses are to big for memory read/write calls on 64bit systems otherwise
uint8_t* _memoryReference;
Memory _memory; Memory _memory;
AddressTableObject _addrTable; AddressTableObject _addrTable;
AssociationTableObject _assocTable; AssociationTableObject _assocTable;

View File

@ -4,7 +4,8 @@
#include "group_object.h" #include "group_object.h"
#include "bits.h" #include "bits.h"
GroupObjectTableObject::GroupObjectTableObject(uint8_t* memoryReference): TableObject(memoryReference) GroupObjectTableObject::GroupObjectTableObject(Platform& platform)
: TableObject(platform)
{ {
_groupObjects = 0; _groupObjects = 0;
_groupObjectCount = 0; _groupObjectCount = 0;

View File

@ -8,11 +8,8 @@ class GroupObjectTableObject: public TableObject
friend class GroupObject; friend class GroupObject;
public: public:
GroupObjectTableObject(uint8_t* memoryReference); GroupObjectTableObject(Platform& platform);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Woverloaded-virtual"
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);
#pragma GCC diagnostic pop
uint16_t entryCount(); uint16_t entryCount();
GroupObject& get(uint16_t asap); GroupObject& get(uint16_t asap);
GroupObject& nextUpdatedObject(bool& valid); GroupObject& nextUpdatedObject(bool& valid);

23
src/knx/platform.cpp Normal file
View File

@ -0,0 +1,23 @@
#include "platform.h"
#include <cstdlib>
uint8_t* Platform::memoryReference()
{
return _memoryReference;
}
uint8_t* Platform::allocMemory(size_t size)
{
uint8_t* address = (uint8_t*)malloc(size);
if (_memoryReference == 0)
_memoryReference = address;
return address;
}
void Platform::freeMemory(uint8_t* ptr)
{
free(ptr);
}

View File

@ -32,4 +32,10 @@ public:
virtual uint8_t* getEepromBuffer(uint16_t size) = 0; virtual uint8_t* getEepromBuffer(uint16_t size) = 0;
virtual void commitToEeprom() = 0; virtual void commitToEeprom() = 0;
virtual uint8_t* memoryReference();
virtual uint8_t* allocMemory(size_t size);
virtual void freeMemory(uint8_t* ptr);
protected:
uint8_t* _memoryReference = 0;
}; };

View File

@ -1,10 +1,9 @@
#include <stdlib.h>
#include <string.h> #include <string.h>
#include "table_object.h" #include "table_object.h"
#include "bits.h" #include "bits.h"
TableObject::TableObject(uint8_t* memoryReference): _memoryReference(memoryReference) TableObject::TableObject(Platform& platform): _platform(platform)
{ {
} }
@ -61,7 +60,7 @@ uint8_t TableObject::propertySize(PropertyID id)
TableObject::~TableObject() TableObject::~TableObject()
{ {
if (_data != 0) if (_data != 0)
free(_data); _platform.freeMemory(_data);
} }
LoadState TableObject::loadState() LoadState TableObject::loadState()
@ -101,9 +100,9 @@ uint8_t* TableObject::restore(uint8_t* buffer)
buffer = popInt(_size, buffer); buffer = popInt(_size, buffer);
if (_data) if (_data)
free(_data); _platform.freeMemory(_data);
_data = (uint8_t*) malloc(_size); _data = _platform.allocMemory(_size);
buffer = popByteArray(_data, _size, buffer); buffer = popByteArray(_data, _size, buffer);
@ -112,21 +111,22 @@ uint8_t* TableObject::restore(uint8_t* buffer)
uint32_t TableObject::tableReference() uint32_t TableObject::tableReference()
{ {
return (uint32_t)(_data - _memoryReference); return (uint32_t)(_data - _platform.memoryReference());
} }
bool TableObject::allocTable(uint32_t size, bool doFill, uint8_t fillByte) bool TableObject::allocTable(uint32_t size, bool doFill, uint8_t fillByte)
{ {
if (_data) if (_data)
{ {
free(_data); _platform.freeMemory(_data);
_data = 0;
_size = 0; _size = 0;
} }
if (size == 0) if (size == 0)
return true; return true;
_data = (uint8_t*)malloc(size); _data = _platform.allocMemory(size);
if (!_data) if (!_data)
return false; return false;

View File

@ -1,11 +1,12 @@
#pragma once #pragma once
#include "interface_object.h" #include "interface_object.h"
#include "platform.h"
class TableObject: public InterfaceObject class TableObject: public InterfaceObject
{ {
public: public:
TableObject(uint8_t* memoryReference); TableObject(Platform& platform);
virtual void readProperty(PropertyID id, uint32_t start, uint32_t count, uint8_t* data); virtual void readProperty(PropertyID id, uint32_t start, uint32_t count, uint8_t* data);
virtual void writeProperty(PropertyID id, uint8_t start, uint8_t* data, uint8_t count); virtual void writeProperty(PropertyID id, uint8_t start, uint8_t* data, uint8_t count);
virtual uint8_t propertySize(PropertyID id); virtual uint8_t propertySize(PropertyID id);
@ -29,5 +30,5 @@ private:
void additionalLoadControls(uint8_t* data); void additionalLoadControls(uint8_t* data);
void loadState(LoadState newState); void loadState(LoadState newState);
LoadState _state = LS_UNLOADED; LoadState _state = LS_UNLOADED;
uint8_t* _memoryReference; Platform& _platform;
}; };

View File

@ -1,13 +1,16 @@
#include "linux_platform.h" #include "linux_platform.h"
#ifdef __linux__ #ifdef __linux__
#include <stdio.h> #include <cstdio>
#include <string> #include <string>
#include <string.h> #include <cstring>
#include <cstdlib>
#include <stdexcept>
#include <cmath>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <math.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
@ -23,9 +26,13 @@
#include "knx/application_program_object.h" #include "knx/application_program_object.h"
#include "knx/ip_parameter_object.h" #include "knx/ip_parameter_object.h"
#define MAX_MEM 4096
LinuxPlatform::LinuxPlatform() LinuxPlatform::LinuxPlatform()
{ {
doMemoryMapping(); doMemoryMapping();
Platform::_memoryReference = (uint8_t*)malloc(MAX_MEM);
_currentMaxMem = Platform::_memoryReference;
} }
uint32_t LinuxPlatform::currentIpAddress() uint32_t LinuxPlatform::currentIpAddress()
@ -72,7 +79,13 @@ void LinuxPlatform::macAddress(uint8_t* data)
void LinuxPlatform::restart() void LinuxPlatform::restart()
{ {
// do nothing // clear alocated memory
if(_memoryReference != 0)
{
free(_memoryReference);
Platform::_memoryReference = (uint8_t*)malloc(MAX_MEM);
_currentMaxMem = Platform::_memoryReference;
}
} }
void LinuxPlatform::fatalError() void LinuxPlatform::fatalError()
@ -276,4 +289,23 @@ void LinuxPlatform::closeUart()
void LinuxPlatform::setupUart() void LinuxPlatform::setupUart()
{ {
} }
#endif
/*
* On linux the memory addresses from malloc may be to big for usermermory_write.
* So we allocate some memory at the beginning and use it for address table, group object table etc.
*
**/
uint8_t* LinuxPlatform::allocMemory(size_t size)
{
uint8_t* addr = _currentMaxMem;
_currentMaxMem += size;
if ((_currentMaxMem - Platform::_memoryReference) > MAX_MEM)
throw std::overflow_error("MAX_MEM was to small");
return addr;
}
#endif
void LinuxPlatform::freeMemory(uint8_t* ptr)
{
/* do nothing. Memory is freed on restart()*/
}

View File

@ -6,6 +6,7 @@
class LinuxPlatform: public Platform class LinuxPlatform: public Platform
{ {
using Platform::_memoryReference;
public: public:
LinuxPlatform(); LinuxPlatform();
@ -39,6 +40,8 @@ public:
//memory //memory
uint8_t* getEepromBuffer(uint16_t size); uint8_t* getEepromBuffer(uint16_t size);
void commitToEeprom(); void commitToEeprom();
uint8_t* allocMemory(size_t size);
void freeMemory(uint8_t* ptr);
private: private:
uint32_t _multicastAddr; uint32_t _multicastAddr;
uint16_t _port; uint16_t _port;
@ -46,6 +49,7 @@ private:
void doMemoryMapping(); void doMemoryMapping();
uint8_t* _mappedFile; uint8_t* _mappedFile;
int _fd; int _fd;
uint8_t* _currentMaxMem = 0;
}; };
#endif #endif

View File

@ -153,5 +153,4 @@ size_t SamdPlatform::readBytesUart(uint8_t *buffer, size_t length)
//printHex("p>", buffer, length); //printHex("p>", buffer, length);
return length; return length;
} }
#endif #endif