mirror of
https://github.com/thelsing/knx.git
synced 2025-08-13 13:46:20 +02:00
put non-volatile memory type dependet stuff into platform
This commit is contained in:
parent
1226103126
commit
5386a3c833
@ -84,34 +84,132 @@ int Esp32Platform::readBytes(uint8_t * buffer, uint16_t maxLen)
|
||||
return len;
|
||||
}
|
||||
|
||||
bool Esp32Platform::writeNVMemory(uintptr_t addr,uint8_t data)
|
||||
bool Esp32Platform::writeNVMemory(uint8_t* addr,uint8_t data)
|
||||
{
|
||||
*((uint8_t*)addr) = data;
|
||||
*addr = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t Esp32Platform::readNVMemory(uintptr_t addr)
|
||||
uint8_t Esp32Platform::readNVMemory(uint8_t* addr)
|
||||
{
|
||||
return *((uint8_t*)addr);
|
||||
return *addr;
|
||||
}
|
||||
|
||||
uintptr_t Esp32Platform::allocNVMemory(size_t size,uint32_t ID)
|
||||
uint8_t* Esp32Platform::allocNVMemory(size_t size,uint32_t ID)
|
||||
{
|
||||
return (uintptr_t)EEPROM.getDataPtr();
|
||||
int i;
|
||||
for(i=0;i<MAX_MEMORY_BLOCKS;i++){
|
||||
if(_memoryBlocks[i].ID == 0)
|
||||
break;
|
||||
}
|
||||
if(i >= MAX_MEMORY_BLOCKS)
|
||||
fatalError();
|
||||
|
||||
|
||||
_memoryBlocks[i].data = (uint8_t*)malloc(size);
|
||||
if(_memoryBlocks[i].data == NULL)
|
||||
fatalError();
|
||||
|
||||
_memoryBlocks[i].ID = ID;
|
||||
_memoryBlocks[i].size = size;
|
||||
|
||||
return _memoryBlocks[i].data;
|
||||
}
|
||||
|
||||
uintptr_t Esp32Platform::reloadNVMemory(uint32_t ID)
|
||||
void Esp32Platform::initNVMemory()
|
||||
{
|
||||
EEPROM.begin(1024);
|
||||
return (uintptr_t)EEPROM.getDataPtr();
|
||||
uint32_t addr = 0;
|
||||
for (int i = 0; i < MAX_MEMORY_BLOCKS; i++){
|
||||
|
||||
if (EEPROM.read(addr++) != 0xBA || EEPROM.read(addr++) != 0xAD || EEPROM.read(addr++) != 0xC0 || EEPROM.read(addr++) != 0xDE){
|
||||
_memoryBlocks[i].ID = 0;
|
||||
_memoryBlocks[i].size = 0;
|
||||
_memoryBlocks[i].data = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
((uint8_t*)&_memoryBlocks[i].ID)[0] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].ID)[1] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].ID)[2] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].ID)[3] = EEPROM.read(addr++);
|
||||
|
||||
((uint8_t*)&_memoryBlocks[i].size)[0] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].size)[1] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].size)[2] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].size)[3] = EEPROM.read(addr++);
|
||||
|
||||
_memoryBlocks[i].data = EEPROM.getDataPtr() + addr;
|
||||
addr += _memoryBlocks[i].size;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* Esp32Platform::reloadNVMemory(uint32_t ID, bool pointerAccess)
|
||||
{
|
||||
if(!_MemoryInitialized)
|
||||
initNVMemory();
|
||||
|
||||
_MemoryInitialized=true;
|
||||
|
||||
int i;
|
||||
for(i=0;i<MAX_MEMORY_BLOCKS;i++){
|
||||
if(_memoryBlocks[i].ID == ID)
|
||||
break;
|
||||
}
|
||||
if(i >= MAX_MEMORY_BLOCKS)
|
||||
return 0;
|
||||
|
||||
|
||||
return _memoryBlocks[i].data;
|
||||
}
|
||||
|
||||
void Esp32Platform::finishNVMemory()
|
||||
{
|
||||
uint32_t addr = 0;
|
||||
|
||||
for (int i = 0; i < MAX_MEMORY_BLOCKS; i++)
|
||||
{
|
||||
if(_memoryBlocks[i].ID == 0)
|
||||
continue;
|
||||
|
||||
//write valid mask
|
||||
EEPROM.write(addr++,0xBA);
|
||||
EEPROM.write(addr++,0xAD);
|
||||
EEPROM.write(addr++,0xC0);
|
||||
EEPROM.write(addr++,0xDE);
|
||||
|
||||
//write ID
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].ID)[0]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].ID)[1]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].ID)[2]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].ID)[3]);
|
||||
|
||||
//write size
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].size)[0]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].size)[1]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].size)[2]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].size)[3]);
|
||||
|
||||
//write data
|
||||
for (uint32_t e=0;e<_memoryBlocks[i].size;e++){
|
||||
EEPROM.write(addr++,_memoryBlocks[i].data[e]);
|
||||
}
|
||||
}
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
void Esp32Platform::freeNVMemory(uint32_t ID)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<MAX_MEMORY_BLOCKS;i++){
|
||||
if(_memoryBlocks[i].ID == ID)
|
||||
break;
|
||||
}
|
||||
if(i >= MAX_MEMORY_BLOCKS)
|
||||
return;
|
||||
|
||||
_memoryBlocks[i].data = NULL;
|
||||
_memoryBlocks[i].size = 0;
|
||||
_memoryBlocks[i].ID = 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -3,6 +3,13 @@
|
||||
#include <WiFi.h>
|
||||
#include <WiFiUdp.h>
|
||||
|
||||
#define MAX_MEMORY_BLOCKS 6
|
||||
|
||||
typedef struct{
|
||||
uint32_t ID;
|
||||
size_t size;
|
||||
uint8_t* data;
|
||||
}MemoryBlock_t;
|
||||
|
||||
class Esp32Platform : public ArduinoPlatform
|
||||
{
|
||||
@ -28,14 +35,17 @@ public:
|
||||
int readBytes(uint8_t* buffer, uint16_t maxLen) override;
|
||||
|
||||
//memory
|
||||
bool writeNVMemory(uintptr_t addr,uint8_t data);
|
||||
uint8_t readNVMemory(uintptr_t addr);
|
||||
uintptr_t allocNVMemory(size_t size,uint32_t ID);
|
||||
uintptr_t reloadNVMemory(uint32_t ID);
|
||||
bool writeNVMemory(uint8_t* addr,uint8_t data);
|
||||
uint8_t readNVMemory(uint8_t* addr);
|
||||
uint8_t* allocNVMemory(size_t size,uint32_t ID);
|
||||
uint8_t* reloadNVMemory(uint32_t ID, bool pointerAccess);
|
||||
void finishNVMemory();
|
||||
void freeNVMemory(uint32_t ID);
|
||||
private:
|
||||
WiFiUDP _udp;
|
||||
void initNVMemory();
|
||||
MemoryBlock_t _memoryBlocks[MAX_MEMORY_BLOCKS];
|
||||
bool _MemoryInitialized = false;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -85,34 +85,132 @@ int EspPlatform::readBytes(uint8_t * buffer, uint16_t maxLen)
|
||||
return len;
|
||||
}
|
||||
|
||||
bool EspPlatform::writeNVMemory(uintptr_t addr,uint8_t data)
|
||||
bool EspPlatform::writeNVMemory(uint8_t* addr,uint8_t data)
|
||||
{
|
||||
*((uint8_t*)addr) = data;
|
||||
*addr = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t EspPlatform::readNVMemory(uintptr_t addr)
|
||||
uint8_t EspPlatform::readNVMemory(uint8_t* addr)
|
||||
{
|
||||
return *((uint8_t*)addr);
|
||||
return *addr;
|
||||
}
|
||||
|
||||
uintptr_t EspPlatform::allocNVMemory(size_t size,uint32_t ID)
|
||||
uint8_t* EspPlatform::allocNVMemory(size_t size,uint32_t ID)
|
||||
{
|
||||
return (uintptr_t)EEPROM.getDataPtr();
|
||||
int i;
|
||||
for(i=0;i<MAX_MEMORY_BLOCKS;i++){
|
||||
if(_memoryBlocks[i].ID == 0)
|
||||
break;
|
||||
}
|
||||
if(i >= MAX_MEMORY_BLOCKS)
|
||||
fatalError();
|
||||
|
||||
|
||||
_memoryBlocks[i].data = (uint8_t*)malloc(size);
|
||||
if(_memoryBlocks[i].data == NULL)
|
||||
fatalError();
|
||||
|
||||
_memoryBlocks[i].ID = ID;
|
||||
_memoryBlocks[i].size = size;
|
||||
|
||||
return _memoryBlocks[i].data;
|
||||
}
|
||||
|
||||
uintptr_t EspPlatform::reloadNVMemory(uint32_t ID)
|
||||
void EspPlatform::initNVMemory()
|
||||
{
|
||||
EEPROM.begin(1024);
|
||||
return (uintptr_t)EEPROM.getDataPtr();
|
||||
uint32_t addr = 0;
|
||||
for (int i = 0; i < MAX_MEMORY_BLOCKS; i++){
|
||||
|
||||
if (EEPROM.read(addr++) != 0xBA || EEPROM.read(addr++) != 0xAD || EEPROM.read(addr++) != 0xC0 || EEPROM.read(addr++) != 0xDE){
|
||||
_memoryBlocks[i].ID = 0;
|
||||
_memoryBlocks[i].size = 0;
|
||||
_memoryBlocks[i].data = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
((uint8_t*)&_memoryBlocks[i].ID)[0] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].ID)[1] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].ID)[2] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].ID)[3] = EEPROM.read(addr++);
|
||||
|
||||
((uint8_t*)&_memoryBlocks[i].size)[0] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].size)[1] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].size)[2] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].size)[3] = EEPROM.read(addr++);
|
||||
|
||||
_memoryBlocks[i].data = EEPROM.getDataPtr() + addr;
|
||||
addr += _memoryBlocks[i].size;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* EspPlatform::reloadNVMemory(uint32_t ID, bool pointerAccess)
|
||||
{
|
||||
if(!_MemoryInitialized)
|
||||
initNVMemory();
|
||||
|
||||
_MemoryInitialized=true;
|
||||
|
||||
int i;
|
||||
for(i=0;i<MAX_MEMORY_BLOCKS;i++){
|
||||
if(_memoryBlocks[i].ID == ID)
|
||||
break;
|
||||
}
|
||||
if(i >= MAX_MEMORY_BLOCKS)
|
||||
return 0;
|
||||
|
||||
|
||||
return _memoryBlocks[i].data;
|
||||
}
|
||||
|
||||
void EspPlatform::finishNVMemory()
|
||||
{
|
||||
uint32_t addr = 0;
|
||||
|
||||
for (int i = 0; i < MAX_MEMORY_BLOCKS; i++)
|
||||
{
|
||||
if(_memoryBlocks[i].ID == 0)
|
||||
continue;
|
||||
|
||||
//write valid mask
|
||||
EEPROM.write(addr++,0xBA);
|
||||
EEPROM.write(addr++,0xAD);
|
||||
EEPROM.write(addr++,0xC0);
|
||||
EEPROM.write(addr++,0xDE);
|
||||
|
||||
//write ID
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].ID)[0]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].ID)[1]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].ID)[2]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].ID)[3]);
|
||||
|
||||
//write size
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].size)[0]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].size)[1]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].size)[2]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].size)[3]);
|
||||
|
||||
//write data
|
||||
for (uint32_t e=0;e<_memoryBlocks[i].size;e++){
|
||||
EEPROM.write(addr++,_memoryBlocks[i].data[e]);
|
||||
}
|
||||
}
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
void EspPlatform::freeNVMemory(uint32_t ID)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<MAX_MEMORY_BLOCKS;i++){
|
||||
if(_memoryBlocks[i].ID == ID)
|
||||
break;
|
||||
}
|
||||
if(i >= MAX_MEMORY_BLOCKS)
|
||||
return;
|
||||
|
||||
_memoryBlocks[i].data = NULL;
|
||||
_memoryBlocks[i].size = 0;
|
||||
_memoryBlocks[i].ID = 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -3,6 +3,13 @@
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <WiFiUdp.h>
|
||||
|
||||
#define MAX_MEMORY_BLOCKS 6
|
||||
|
||||
typedef struct{
|
||||
uint32_t ID;
|
||||
size_t size;
|
||||
uint8_t* data;
|
||||
}MemoryBlock_t;
|
||||
|
||||
class EspPlatform : public ArduinoPlatform
|
||||
{
|
||||
@ -29,14 +36,17 @@ class EspPlatform : public ArduinoPlatform
|
||||
int readBytes(uint8_t* buffer, uint16_t maxLen) override;
|
||||
|
||||
//memory
|
||||
bool writeNVMemory(uintptr_t addr,uint8_t data);
|
||||
uint8_t readNVMemory(uintptr_t addr);
|
||||
uintptr_t allocNVMemory(size_t size,uint32_t ID);
|
||||
uintptr_t reloadNVMemory(uint32_t ID);
|
||||
bool writeNVMemory(uint8_t* addr,uint8_t data);
|
||||
uint8_t readNVMemory(uint8_t* addr);
|
||||
uint8_t* allocNVMemory(size_t size,uint32_t ID);
|
||||
uint8_t* reloadNVMemory(uint32_t ID, bool pointerAccess);
|
||||
void finishNVMemory();
|
||||
void freeNVMemory(uint32_t ID);
|
||||
private:
|
||||
WiFiUDP _udp;
|
||||
void initNVMemory();
|
||||
MemoryBlock_t _memoryBlocks[MAX_MEMORY_BLOCKS];
|
||||
bool _MemoryInitialized = false;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -51,18 +51,12 @@ uint16_t AddressTableObject::getTsap(uint16_t addr)
|
||||
|
||||
#pragma region SaveRestore
|
||||
|
||||
uint8_t* AddressTableObject::save(uint8_t* buffer)
|
||||
{
|
||||
return TableObject::save(buffer);
|
||||
}
|
||||
|
||||
uint8_t* AddressTableObject::restore(uint8_t* buffer)
|
||||
void AddressTableObject::restore(uint8_t* startAddr)
|
||||
{
|
||||
buffer = TableObject::restore(buffer);
|
||||
TableObject::restore(startAddr);
|
||||
|
||||
_groupAddresses = (uint16_t*)data();
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
@ -19,8 +19,7 @@ class AddressTableObject : public TableObject
|
||||
*/
|
||||
AddressTableObject(Platform& platform);
|
||||
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);
|
||||
void restore(uint8_t* startAddr);
|
||||
/**
|
||||
* returns the number of group addresses of the object.
|
||||
*/
|
||||
|
@ -61,17 +61,20 @@ uint8_t * ApplicationProgramObject::data(uint32_t addr)
|
||||
|
||||
uint8_t ApplicationProgramObject::getByte(uint32_t addr)
|
||||
{
|
||||
return *(TableObject::data() + addr);
|
||||
uint8_t* paddr = TableObject::data()+addr;
|
||||
return _platform.popNVMemoryByte(&paddr);
|
||||
}
|
||||
|
||||
uint16_t ApplicationProgramObject::getWord(uint32_t addr)
|
||||
{
|
||||
return ::getWord(TableObject::data() + addr);
|
||||
uint8_t* paddr = TableObject::data()+addr;
|
||||
return _platform.popNVMemoryWord(&paddr);
|
||||
}
|
||||
|
||||
uint32_t ApplicationProgramObject::getInt(uint32_t addr)
|
||||
{
|
||||
return ::getInt(TableObject::data() + addr);
|
||||
uint8_t* paddr = TableObject::data()+addr;
|
||||
return _platform.popNVMemoryInt(&paddr);
|
||||
}
|
||||
|
||||
uint32_t ApplicationProgramObject::size(){
|
||||
@ -79,42 +82,20 @@ uint32_t ApplicationProgramObject::size(){
|
||||
}
|
||||
|
||||
|
||||
uint8_t* ApplicationProgramObject::save()
|
||||
void ApplicationProgramObject::save()
|
||||
{
|
||||
if(TableObject::data() == NULL)
|
||||
return NULL;
|
||||
return ;
|
||||
|
||||
uint8_t* buffer;
|
||||
uintptr_t addr =(uintptr_t)(TableObject::data() - sizeof(_programVersion) - TableObject::sizeMetadata());
|
||||
if(TableObject::_platform.NVMemoryType() == internalFlash)
|
||||
buffer = new uint8_t[sizeof(_programVersion)];
|
||||
else
|
||||
buffer = (uint8_t*)addr;
|
||||
|
||||
pushByteArray(_programVersion, sizeof(_programVersion), buffer);
|
||||
|
||||
if(TableObject::_platform.NVMemoryType() == internalFlash){
|
||||
for(uint32_t i=0;i<sizeof(_programVersion);i++)
|
||||
TableObject::_platform.writeNVMemory(addr+i, buffer[i]);
|
||||
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
return TableObject::save();
|
||||
uint8_t* addr =TableObject::data() - sizeof(_programVersion) - TableObject::sizeMetadata();
|
||||
_platform.pushNVMemoryArray(_programVersion, &addr, sizeof(_programVersion));
|
||||
TableObject::save();
|
||||
}
|
||||
|
||||
uint8_t* ApplicationProgramObject::save(uint8_t* buffer)
|
||||
void ApplicationProgramObject::restore(uint8_t* startAddr)
|
||||
{
|
||||
buffer = pushByteArray(_programVersion, 5, buffer);
|
||||
|
||||
return TableObject::save(buffer);
|
||||
}
|
||||
|
||||
uint8_t* ApplicationProgramObject::restore(uint8_t* buffer)
|
||||
{
|
||||
TableObject::_dataComplete = buffer;
|
||||
buffer = popByteArray(_programVersion, 5, buffer);
|
||||
return TableObject::restore(buffer);
|
||||
_platform.popNVMemoryArray(_programVersion, &startAddr, sizeof(_programVersion));
|
||||
TableObject::restore(startAddr);
|
||||
}
|
||||
|
||||
static PropertyDescription _propertyDescriptions[] =
|
||||
|
@ -13,9 +13,8 @@ class ApplicationProgramObject : public TableObject
|
||||
uint8_t getByte(uint32_t addr);
|
||||
uint16_t getWord(uint32_t addr);
|
||||
uint32_t getInt(uint32_t addr);
|
||||
uint8_t* save(uint8_t* buffer);
|
||||
uint8_t* save();
|
||||
uint8_t* restore(uint8_t* buffer);
|
||||
void save();
|
||||
void restore(uint8_t* startAddr);
|
||||
uint32_t size();
|
||||
|
||||
protected:
|
||||
@ -24,4 +23,4 @@ class ApplicationProgramObject : public TableObject
|
||||
|
||||
private:
|
||||
uint8_t _programVersion[5] = {0, 0, 0, 0, 0};
|
||||
};
|
||||
};
|
||||
|
@ -45,16 +45,10 @@ uint16_t AssociationTableObject::getASAP(uint16_t idx)
|
||||
return ntohs(_tableData[2 * idx + 2]);
|
||||
}
|
||||
|
||||
uint8_t* AssociationTableObject::save(uint8_t* buffer)
|
||||
void AssociationTableObject::restore(uint8_t* startAddr)
|
||||
{
|
||||
return TableObject::save(buffer);
|
||||
}
|
||||
|
||||
uint8_t* AssociationTableObject::restore(uint8_t* buffer)
|
||||
{
|
||||
buffer = TableObject::restore(buffer);
|
||||
TableObject::restore(startAddr);
|
||||
_tableData = (uint16_t*)data();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// return type is int32 so that we can return uint16 and -1
|
||||
|
@ -8,8 +8,7 @@ class AssociationTableObject : public TableObject
|
||||
AssociationTableObject(Platform& platform);
|
||||
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);
|
||||
void restore(uint8_t* startAddr);
|
||||
|
||||
int32_t translateAsap(uint16_t asap);
|
||||
int32_t nextAsap(uint16_t tsap, uint16_t& startIdx);
|
||||
|
@ -9,11 +9,11 @@ BauSystemB::BauSystemB(Platform& platform): _memory(platform), _addrTable(platfo
|
||||
{
|
||||
_appLayer.transportLayer(_transLayer);
|
||||
_transLayer.networkLayer(_netLayer);
|
||||
_memory.addSaveRestore(&_deviceObj);
|
||||
_memory.addSaveRestore(&_appProgram);
|
||||
_memory.addSaveRestore(&_addrTable);
|
||||
_memory.addSaveRestore(&_assocTable);
|
||||
_memory.addSaveRestore(&_groupObjTable);
|
||||
_memory.addSaveRestore(&_deviceObj);
|
||||
_memory.addSaveRestore(&_appProgram);
|
||||
}
|
||||
|
||||
void BauSystemB::loop()
|
||||
@ -139,12 +139,9 @@ void BauSystemB::deviceDescriptorReadIndication(Priority priority, HopCountType
|
||||
void BauSystemB::memoryWriteIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t number,
|
||||
uint16_t memoryAddress, uint8_t * data)
|
||||
{
|
||||
if(_platform.NVMemoryType() == internalFlash){
|
||||
for(uint8_t i=0;i<number;i++)
|
||||
_platform.writeNVMemory((uintptr_t)_platform.memoryReference() + memoryAddress+i, data[i]);
|
||||
}
|
||||
else
|
||||
memcpy(_platform.memoryReference() + memoryAddress, data, number);
|
||||
|
||||
for(uint8_t i=0;i<number;i++)
|
||||
_platform.writeNVMemory(_platform.referenceNVMemory() + memoryAddress+i, data[i]);
|
||||
|
||||
_memory.memoryModified();
|
||||
|
||||
@ -155,18 +152,12 @@ void BauSystemB::memoryWriteIndication(Priority priority, HopCountType hopType,
|
||||
void BauSystemB::memoryReadIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t number,
|
||||
uint16_t memoryAddress)
|
||||
{
|
||||
if(_platform.NVMemoryType() == internalFlash){
|
||||
uint8_t* buffer = new uint8_t[number];
|
||||
for(uint8_t i=0;i<number;i++)
|
||||
buffer[i] = _platform.readNVMemory((uintptr_t)_platform.memoryReference() + memoryAddress+i);
|
||||
uint8_t* buffer = new uint8_t[number];
|
||||
for(uint8_t i=0;i<number;i++)
|
||||
buffer[i] = _platform.readNVMemory(_platform.referenceNVMemory() + memoryAddress+i);
|
||||
|
||||
_appLayer.memoryReadResponse(AckRequested, priority, hopType, asap, number, memoryAddress,buffer);
|
||||
delete[] buffer;
|
||||
}
|
||||
else{
|
||||
_appLayer.memoryReadResponse(AckRequested, priority, hopType, asap, number, memoryAddress,
|
||||
_platform.memoryReference() + memoryAddress);
|
||||
}
|
||||
_appLayer.memoryReadResponse(AckRequested, priority, hopType, asap, number, memoryAddress,buffer);
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
void BauSystemB::restartRequestIndication(Priority priority, HopCountType hopType, uint16_t asap)
|
||||
@ -183,30 +174,19 @@ void BauSystemB::authorizeIndication(Priority priority, HopCountType hopType, ui
|
||||
|
||||
void BauSystemB::userMemoryReadIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, uint32_t memoryAddress)
|
||||
{
|
||||
if(_platform.NVMemoryType() == internalFlash){
|
||||
uint8_t* buffer = new uint8_t[number];
|
||||
for(uint8_t i=0;i<number;i++)
|
||||
buffer[i] = _platform.readNVMemory((uintptr_t)_platform.memoryReference() + memoryAddress+i);
|
||||
_appLayer.userMemoryReadResponse(AckRequested, priority, hopType, asap, number, memoryAddress,buffer);
|
||||
delete[] buffer;
|
||||
}
|
||||
else{
|
||||
_appLayer.userMemoryReadResponse(AckRequested, priority, hopType, asap, number, memoryAddress,
|
||||
_platform.memoryReference() + memoryAddress);
|
||||
}
|
||||
uint8_t* buffer = new uint8_t[number];
|
||||
for(uint8_t i=0;i<number;i++)
|
||||
buffer[i] = _platform.readNVMemory(_platform.referenceNVMemory() + memoryAddress+i);
|
||||
_appLayer.userMemoryReadResponse(AckRequested, priority, hopType, asap, number, memoryAddress,buffer);
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
void BauSystemB::userMemoryWriteIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, uint32_t memoryAddress, uint8_t* data)
|
||||
{
|
||||
if(_platform.NVMemoryType() == internalFlash){
|
||||
for(uint8_t i=0;i<number;i++)
|
||||
_platform.writeNVMemory((uintptr_t)_platform.memoryReference() + memoryAddress+i, data[i]);
|
||||
}
|
||||
else{
|
||||
memcpy(_platform.memoryReference() + memoryAddress, data, number);
|
||||
}
|
||||
_memory.memoryModified();
|
||||
for(uint8_t i=0;i<number;i++)
|
||||
_platform.writeNVMemory(_platform.referenceNVMemory() + memoryAddress+i, data[i]);
|
||||
|
||||
_memory.memoryModified();
|
||||
if (_deviceObj.verifyMode())
|
||||
userMemoryReadIndication(priority, hopType, asap, number, memoryAddress);
|
||||
}
|
||||
|
@ -119,43 +119,23 @@ uint32_t DeviceObject::size(){
|
||||
return METADATA_SIZE;
|
||||
}
|
||||
|
||||
uint8_t* DeviceObject::save()
|
||||
void DeviceObject::save()
|
||||
{
|
||||
uint8_t* buffer = new uint8_t[METADATA_SIZE];
|
||||
_platform.freeNVMemory(_ID);
|
||||
uint8_t* addr = _platform.allocNVMemory(METADATA_SIZE, _ID);
|
||||
|
||||
buffer = pushByte(_deviceControl, buffer);
|
||||
buffer = pushByte(_routingCount, buffer);
|
||||
buffer = pushWord(_ownAddress, buffer);
|
||||
buffer -= METADATA_SIZE;
|
||||
|
||||
if(_platform.NVMemoryType() == internalFlash){
|
||||
_platform.freeNVMemory(_ID);
|
||||
uintptr_t addr = _platform.allocNVMemory(METADATA_SIZE, _ID);
|
||||
|
||||
for(size_t i=0;i<METADATA_SIZE;i++)
|
||||
_platform.writeNVMemory(addr+i, buffer[i]);
|
||||
|
||||
delete[] buffer;
|
||||
return (uint8_t*)addr;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
uint8_t* DeviceObject::save(uint8_t* buffer)
|
||||
{
|
||||
buffer = pushByte(_deviceControl, buffer);
|
||||
buffer = pushByte(_routingCount, buffer);
|
||||
buffer = pushWord(_ownAddress, buffer);
|
||||
return buffer;
|
||||
_platform.pushNVMemoryByte(_deviceControl, &addr);
|
||||
_platform.pushNVMemoryByte(_routingCount, &addr);
|
||||
_platform.pushNVMemoryWord(_ownAddress, &addr);
|
||||
}
|
||||
|
||||
uint8_t* DeviceObject::restore(uint8_t* buffer)
|
||||
void DeviceObject::restore(uint8_t* startAddr)
|
||||
{
|
||||
buffer = popByte(_deviceControl, buffer);
|
||||
buffer = popByte(_routingCount, buffer);
|
||||
buffer = popWord(_ownAddress, buffer);
|
||||
uint8_t* addr = startAddr;
|
||||
_deviceControl = _platform.popNVMemoryByte(&addr);
|
||||
_routingCount = _platform.popNVMemoryByte(&addr);
|
||||
_ownAddress = _platform.popNVMemoryWord(&addr);
|
||||
_prgMode = 0;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
uint16_t DeviceObject::induvidualAddress()
|
||||
|
@ -10,9 +10,8 @@ public:
|
||||
void readProperty(PropertyID id, uint32_t start, uint32_t& count, uint8_t* data);
|
||||
void writeProperty(PropertyID id, uint8_t start, uint8_t* data, uint8_t count);
|
||||
uint8_t propertySize(PropertyID id);
|
||||
uint8_t* save(uint8_t* buffer);
|
||||
uint8_t* save();
|
||||
uint8_t* restore(uint8_t* buffer);
|
||||
void save();
|
||||
void restore(uint8_t* startAddr);
|
||||
uint32_t size();
|
||||
void readPropertyDescription(uint8_t propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access);
|
||||
|
||||
|
@ -41,21 +41,12 @@ GroupObject& GroupObjectTableObject::get(uint16_t asap)
|
||||
return _groupObjects[asap - 1];
|
||||
}
|
||||
|
||||
|
||||
uint8_t* GroupObjectTableObject::save(uint8_t* buffer)
|
||||
void GroupObjectTableObject::restore(uint8_t* startAddr)
|
||||
{
|
||||
return TableObject::save(buffer);
|
||||
}
|
||||
|
||||
|
||||
uint8_t* GroupObjectTableObject::restore(uint8_t* buffer)
|
||||
{
|
||||
buffer = TableObject::restore(buffer);
|
||||
TableObject::restore(startAddr);
|
||||
|
||||
_tableData = (uint16_t*)data();
|
||||
initGroupObjects();
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
GroupObject& GroupObjectTableObject::nextUpdatedObject(bool& valid)
|
||||
|
@ -16,8 +16,7 @@ class GroupObjectTableObject : public TableObject
|
||||
GroupObject& nextUpdatedObject(bool& valid);
|
||||
void groupObjects(GroupObject* objs, uint16_t size);
|
||||
|
||||
virtual uint8_t* save(uint8_t* buffer);
|
||||
virtual uint8_t* restore(uint8_t* buffer);
|
||||
virtual void restore(uint8_t* startAddr);
|
||||
|
||||
protected:
|
||||
virtual void beforeStateChange(LoadState& newState);
|
||||
|
@ -159,63 +159,34 @@ uint32_t IpParameterObject::size(){
|
||||
return METADATA_SIZE;
|
||||
}
|
||||
|
||||
uint8_t* IpParameterObject::save()
|
||||
void IpParameterObject::save()
|
||||
{
|
||||
uint8_t* buffer = new uint8_t[METADATA_SIZE];
|
||||
_platform.freeNVMemory(_ID);
|
||||
uint8_t* addr = _platform.allocNVMemory(METADATA_SIZE, _ID);
|
||||
|
||||
buffer = pushWord(_projectInstallationId, buffer);
|
||||
buffer = pushByte(_ipAssignmentMethod, buffer);
|
||||
buffer = pushByte(_ipCapabilities, buffer);
|
||||
buffer = pushInt(_ipAddress, buffer);
|
||||
buffer = pushInt(_subnetMask, buffer);
|
||||
buffer = pushInt(_defaultGateway, buffer);
|
||||
buffer = pushInt(_multicastAddress, buffer);
|
||||
buffer = pushByte(_ttl, buffer);
|
||||
buffer = pushByteArray((uint8_t*)_friendlyName, 30, buffer);
|
||||
buffer -= METADATA_SIZE;
|
||||
|
||||
if(_platform.NVMemoryType() == internalFlash){
|
||||
_platform.freeNVMemory(_ID);
|
||||
uintptr_t addr = _platform.allocNVMemory(METADATA_SIZE, _ID);
|
||||
|
||||
for(size_t i=0;i<METADATA_SIZE;i++)
|
||||
_platform.writeNVMemory(addr+i, buffer[i]);
|
||||
|
||||
delete[] buffer;
|
||||
return (uint8_t*)addr;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
_platform.pushNVMemoryWord(_projectInstallationId, &addr);
|
||||
_platform.pushNVMemoryByte(_ipAssignmentMethod, &addr);
|
||||
_platform.pushNVMemoryByte(_ipCapabilities, &addr);
|
||||
_platform.pushNVMemoryInt(_ipAddress, &addr);
|
||||
_platform.pushNVMemoryInt(_subnetMask, &addr);
|
||||
_platform.pushNVMemoryInt(_defaultGateway, &addr);
|
||||
_platform.pushNVMemoryInt(_multicastAddress, &addr);
|
||||
_platform.pushNVMemoryByte(_ttl, &addr);
|
||||
_platform.pushNVMemoryArray((uint8_t*)_friendlyName, &addr, sizeof(_friendlyName));
|
||||
}
|
||||
|
||||
uint8_t* IpParameterObject::save(uint8_t* buffer)
|
||||
void IpParameterObject::restore(uint8_t* startAddr)
|
||||
{
|
||||
buffer = pushWord(_projectInstallationId, buffer);
|
||||
buffer = pushByte(_ipAssignmentMethod, buffer);
|
||||
buffer = pushByte(_ipCapabilities, buffer);
|
||||
buffer = pushInt(_ipAddress, buffer);
|
||||
buffer = pushInt(_subnetMask, buffer);
|
||||
buffer = pushInt(_defaultGateway, buffer);
|
||||
buffer = pushInt(_multicastAddress, buffer);
|
||||
buffer = pushByte(_ttl, buffer);
|
||||
buffer = pushByteArray((uint8_t*)_friendlyName, 30, buffer);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
uint8_t* IpParameterObject::restore(uint8_t* buffer)
|
||||
{
|
||||
buffer = popWord(_projectInstallationId, buffer);
|
||||
buffer = popByte(_ipAssignmentMethod, buffer);
|
||||
buffer = popByte(_ipCapabilities, buffer);
|
||||
buffer = popInt(_ipAddress, buffer);
|
||||
buffer = popInt(_subnetMask, buffer);
|
||||
buffer = popInt(_defaultGateway, buffer);
|
||||
buffer = popInt(_multicastAddress, buffer);
|
||||
buffer = popByte(_ttl, buffer);
|
||||
buffer = popByteArray((uint8_t*)_friendlyName, 30, buffer);
|
||||
|
||||
return buffer;
|
||||
uint8_t* addr = startAddr;
|
||||
_projectInstallationId = _platform.popNVMemoryWord(&addr);
|
||||
_ipAssignmentMethod = _platform.popNVMemoryByte(&addr);
|
||||
_ipCapabilities = _platform.popNVMemoryByte(&addr);
|
||||
_ipAddress = _platform.popNVMemoryInt(&addr);
|
||||
_subnetMask = _platform.popNVMemoryInt(&addr);
|
||||
_defaultGateway = _platform.popNVMemoryInt(&addr);
|
||||
_multicastAddress = _platform.popNVMemoryInt(&addr);
|
||||
_ttl = _platform.popNVMemoryByte(&addr);
|
||||
_platform.popNVMemoryArray((uint8_t*)_friendlyName, &addr, sizeof(_friendlyName));
|
||||
}
|
||||
|
||||
uint32_t IpParameterObject::multicastAddress() const
|
||||
|
@ -12,9 +12,8 @@ class IpParameterObject : public InterfaceObject
|
||||
void writeProperty(PropertyID id, uint8_t start, uint8_t* data, uint8_t count);
|
||||
uint8_t propertySize(PropertyID id);
|
||||
|
||||
uint8_t* save(uint8_t* buffer);
|
||||
uint8_t* save();
|
||||
uint8_t* restore(uint8_t* buffer);
|
||||
void save();
|
||||
void restore(uint8_t* startAddr);
|
||||
uint32_t size();
|
||||
|
||||
uint32_t multicastAddress() const;
|
||||
|
@ -16,54 +16,24 @@ bool Memory::isMemoryModified()
|
||||
return _modified;
|
||||
}
|
||||
|
||||
void Memory::readMemory(){
|
||||
switch (_platform.NVMemoryType()){
|
||||
case internalRam:
|
||||
readRamMemory();
|
||||
break;
|
||||
case internalFlash:
|
||||
readFlashMemory();
|
||||
break;
|
||||
case external:
|
||||
readExternalMemory();
|
||||
break;
|
||||
case notDefined:
|
||||
default:
|
||||
_platform.fatalError();
|
||||
}
|
||||
}
|
||||
|
||||
void Memory::writeMemory(){
|
||||
switch (_platform.NVMemoryType()){
|
||||
case internalRam:
|
||||
writeRamMemory();
|
||||
break;
|
||||
case internalFlash:
|
||||
writeFlashMemory();
|
||||
break;
|
||||
case external:
|
||||
writeExternalMemory();
|
||||
break;
|
||||
case notDefined:
|
||||
default:
|
||||
_platform.fatalError();
|
||||
}
|
||||
}
|
||||
|
||||
void Memory::readFlashMemory()
|
||||
void Memory::readMemory()
|
||||
{
|
||||
for (int i = 0; i < _saveCount; i++)
|
||||
{
|
||||
uint8_t* data = (uint8_t*)_platform.reloadNVMemory(BASE_ID+i);
|
||||
bool pointerAccess;
|
||||
if(i<=2)
|
||||
pointerAccess = true;
|
||||
else
|
||||
pointerAccess = false;
|
||||
uint8_t* data = _platform.reloadNVMemory(BASE_ID+i, pointerAccess);
|
||||
if(data == NULL)
|
||||
continue;
|
||||
|
||||
_saveRestores[i]->restore(data);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Memory::writeFlashMemory()
|
||||
void Memory::writeMemory()
|
||||
{
|
||||
for (int i = 0; i < _saveCount; i++){
|
||||
_saveRestores[i]->save();
|
||||
@ -73,133 +43,6 @@ void Memory::writeFlashMemory()
|
||||
_modified = false;
|
||||
}
|
||||
|
||||
void Memory::readRamMemory()
|
||||
{
|
||||
_data = (uint8_t*)_platform.reloadNVMemory(1);
|
||||
|
||||
if (_data[0] != 0x00 || _data[1] != 0xAD || _data[2] != 0xAF || _data[3] != 0xFE)
|
||||
return;
|
||||
|
||||
uint8_t* buffer = _data + 4;
|
||||
int size = _saveCount;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
buffer = _saveRestores[i]->restore(buffer);
|
||||
buffer = (uint8_t*)(((uintptr_t)buffer + 3) / 4 * 4); //allign to 32bit
|
||||
}
|
||||
}
|
||||
|
||||
void Memory::writeRamMemory()
|
||||
{
|
||||
uint32_t bytesToSave = 10;
|
||||
|
||||
for (int i = 0; i < _saveCount; i++){
|
||||
bytesToSave += _saveRestores[i]->size();
|
||||
}
|
||||
|
||||
_data = (uint8_t*)_platform.allocNVMemory(bytesToSave,BASE_ID);
|
||||
|
||||
_data[0] = 0x00;
|
||||
_data[1] = 0xAD;
|
||||
_data[2] = 0xAF;
|
||||
_data[3] = 0xFE;
|
||||
|
||||
uint8_t* buffer = _data + 4;
|
||||
int size = _saveCount;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
buffer = _saveRestores[i]->save(buffer);
|
||||
buffer = (uint8_t*)(((uintptr_t)buffer + 3) / 4 * 4); //allign to 32bit
|
||||
}
|
||||
_platform.finishNVMemory();
|
||||
_modified = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Memory::readExternalMemory()
|
||||
{
|
||||
|
||||
int size = _saveCount;
|
||||
volatile uintptr_t addr = _platform.reloadNVMemory(BASE_ID);
|
||||
volatile uint32_t bytesToRestore;
|
||||
|
||||
if(addr == 0)
|
||||
return;
|
||||
|
||||
|
||||
if (_platform.readNVMemory(addr++) != 0x00 || _platform.readNVMemory(addr++) != 0xAD || _platform.readNVMemory(addr++) != 0xAF || _platform.readNVMemory(addr++) != 0xFE)
|
||||
return;
|
||||
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
((uint8_t*)&bytesToRestore)[0] = _platform.readNVMemory(addr++);
|
||||
((uint8_t*)&bytesToRestore)[1] = _platform.readNVMemory(addr++);
|
||||
((uint8_t*)&bytesToRestore)[2] = _platform.readNVMemory(addr++);
|
||||
((uint8_t*)&bytesToRestore)[3] = _platform.readNVMemory(addr++);
|
||||
|
||||
if(bytesToRestore == 0)
|
||||
continue;
|
||||
_data = _platform.allocMemory(bytesToRestore);
|
||||
if(_data == NULL)
|
||||
_platform.fatalError();
|
||||
|
||||
for (uint32_t e=0;e<bytesToRestore;e++){
|
||||
_data[e] = _platform.readNVMemory(addr++);
|
||||
}
|
||||
_saveRestores[i]->restore(_data);
|
||||
}
|
||||
}
|
||||
|
||||
void Memory::writeExternalMemory()
|
||||
{
|
||||
uint32_t bytesToSave = 4;
|
||||
int size = _saveCount;
|
||||
|
||||
_platform.freeNVMemory(BASE_ID);
|
||||
|
||||
for (int i = 0; i < size; i++){
|
||||
bytesToSave += _saveRestores[i]->size() + 4;
|
||||
}
|
||||
|
||||
uintptr_t addr = _platform.allocNVMemory(bytesToSave,BASE_ID);
|
||||
|
||||
//write valid mask
|
||||
_platform.writeNVMemory(addr++,0x00);
|
||||
_platform.writeNVMemory(addr++,0xAD);
|
||||
_platform.writeNVMemory(addr++,0xAF);
|
||||
_platform.writeNVMemory(addr++,0xFE);
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
_data = _saveRestores[i]->save();
|
||||
if(_data == NULL)
|
||||
bytesToSave = 0;
|
||||
else
|
||||
bytesToSave = _saveRestores[i]->size();
|
||||
|
||||
//write size
|
||||
_platform.writeNVMemory(addr++,((uint8_t*)&bytesToSave)[0]);
|
||||
_platform.writeNVMemory(addr++,((uint8_t*)&bytesToSave)[1]);
|
||||
_platform.writeNVMemory(addr++,((uint8_t*)&bytesToSave)[2]);
|
||||
_platform.writeNVMemory(addr++,((uint8_t*)&bytesToSave)[3]);
|
||||
|
||||
if(bytesToSave == 0)
|
||||
continue;
|
||||
|
||||
|
||||
for (uint32_t e=0;e<bytesToSave;e++){
|
||||
_platform.writeNVMemory(addr++,_data[e]);
|
||||
}
|
||||
|
||||
_platform.freeMemory(_data);
|
||||
}
|
||||
|
||||
_platform.finishNVMemory();
|
||||
_modified = false;
|
||||
}
|
||||
void Memory::addSaveRestore(SaveRestore * obj)
|
||||
{
|
||||
if (_saveCount >= MAXSAVE - 1)
|
||||
|
@ -16,12 +16,6 @@ public:
|
||||
void writeMemory();
|
||||
void addSaveRestore(SaveRestore* obj);
|
||||
private:
|
||||
void readFlashMemory();
|
||||
void writeFlashMemory();
|
||||
void readRamMemory();
|
||||
void writeRamMemory();
|
||||
void readExternalMemory();
|
||||
void writeExternalMemory();
|
||||
Platform& _platform;
|
||||
bool _modified = false;
|
||||
SaveRestore* _saveRestores[MAXSAVE] = {0};
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
uint8_t* Platform::memoryReference()
|
||||
uint8_t* Platform::referenceNVMemory()
|
||||
{
|
||||
return _memoryReference;
|
||||
}
|
||||
@ -38,3 +38,58 @@ Platform::Platform()
|
||||
free(_memoryReference);
|
||||
_memoryReference -= 1024;
|
||||
}
|
||||
|
||||
uint8_t Platform::popNVMemoryByte(uint8_t** addr)
|
||||
{
|
||||
uint8_t val = readNVMemory(*addr);
|
||||
(*addr)+=1;
|
||||
return val;
|
||||
}
|
||||
|
||||
uint16_t Platform::popNVMemoryWord(uint8_t** addr)
|
||||
{
|
||||
uint16_t val = (readNVMemory(*addr) << 8) + readNVMemory((*addr)+1);
|
||||
(*addr)+=2;
|
||||
return val;
|
||||
}
|
||||
|
||||
uint32_t Platform::popNVMemoryInt(uint8_t** addr)
|
||||
{
|
||||
uint32_t val = (readNVMemory((*addr)) << 24) + (readNVMemory((*addr)+1) << 16) + (readNVMemory((*addr)+2) << 8) + readNVMemory((*addr)+3);
|
||||
(*addr)+=4;
|
||||
return val;
|
||||
}
|
||||
|
||||
void Platform::popNVMemoryArray(uint8_t* dest, uint8_t** addr, size_t size){
|
||||
for(size_t i=0;i<size;i++){
|
||||
dest[i] = readNVMemory((*addr)++);
|
||||
}
|
||||
}
|
||||
|
||||
void Platform::pushNVMemoryByte(uint8_t val, uint8_t** addr)
|
||||
{
|
||||
writeNVMemory((*addr), val);
|
||||
(*addr) += 1;
|
||||
}
|
||||
|
||||
void Platform::pushNVMemoryWord(uint16_t val, uint8_t** addr)
|
||||
{
|
||||
writeNVMemory((*addr), ((val >> 8) & 0xff));
|
||||
writeNVMemory((*addr)+1, (val & 0xff));
|
||||
(*addr) += 2;
|
||||
}
|
||||
|
||||
void Platform::pushNVMemoryInt(uint32_t val, uint8_t** addr)
|
||||
{
|
||||
writeNVMemory((*addr), ((val >> 24) & 0xff));
|
||||
writeNVMemory((*addr)+1, ((val >> 16) & 0xff));
|
||||
writeNVMemory((*addr)+2, ((val >> 8) & 0xff));
|
||||
writeNVMemory((*addr)+3, (val & 0xff));
|
||||
(*addr) += 4;
|
||||
}
|
||||
|
||||
void Platform::pushNVMemoryArray(uint8_t* src, uint8_t** addr, size_t size){
|
||||
for(size_t i=0;i<size;i++){
|
||||
writeNVMemory((*addr)++,src[i]);
|
||||
}
|
||||
}
|
||||
|
@ -4,13 +4,6 @@
|
||||
#include <stddef.h>
|
||||
#include "save_restore.h"
|
||||
|
||||
typedef enum{
|
||||
notDefined,
|
||||
internalRam,
|
||||
internalFlash,
|
||||
external
|
||||
}NVMemory_t;
|
||||
|
||||
class Platform
|
||||
{
|
||||
public:
|
||||
@ -36,18 +29,92 @@ class Platform
|
||||
virtual int readUart() = 0;
|
||||
virtual size_t readBytesUart(uint8_t* buffer, size_t length) = 0;
|
||||
|
||||
virtual bool writeNVMemory(uintptr_t addr,uint8_t data) = 0;
|
||||
virtual uint8_t readNVMemory(uintptr_t addr) = 0;
|
||||
virtual uintptr_t allocNVMemory(size_t size,uint32_t ID) = 0;
|
||||
virtual uintptr_t reloadNVMemory(uint32_t ID) = 0;
|
||||
/**
|
||||
* Provides a memory block for an interface object.
|
||||
* Hereby, the type of memory is not important, as long as at the latest with finishNVMemory(), the data is written to a non-volatile memory.
|
||||
* Is called by the stack every time ETS wants to store data (device, application, association, ....)
|
||||
* The data itself is then written by writeNVMemory()
|
||||
*
|
||||
* @param size The number of bytes to allocate
|
||||
*
|
||||
* @param ID Unique identifier that represents the new memory block, even after reset
|
||||
*
|
||||
* @return The start address of the created memory block
|
||||
*/
|
||||
virtual uint8_t* allocNVMemory(size_t size,uint32_t ID) = 0;
|
||||
|
||||
/**
|
||||
* Write one single byte to previously allocated (allocNVMemory()) or reloaded (reloadNVMemory()) memory block
|
||||
* Is called by the stack during ETS programming to store interface object data and before reset (save()) to store object status
|
||||
*
|
||||
* @param addr The address where to store the data
|
||||
*
|
||||
* @param data The value of the data which sould be stored
|
||||
*
|
||||
*/
|
||||
virtual bool writeNVMemory(uint8_t* addr,uint8_t data) = 0;
|
||||
|
||||
/**
|
||||
* Reads one single byte from previously allocated (allocNVMemory()) or reloaded (reloadNVMemory()) memory block
|
||||
* Is called by the stack during power up (restore()) and every time the application reads ETS parameter values (knx.paramByte())
|
||||
*
|
||||
* @param addr The address where to read from
|
||||
*
|
||||
* @return The value of the data byte which was read
|
||||
*
|
||||
*/
|
||||
virtual uint8_t readNVMemory(uint8_t* addr) = 0;
|
||||
|
||||
/**
|
||||
* Returns existing memory block identified by the ID, even after reset
|
||||
* Is called by the stack during power up (restore())
|
||||
*
|
||||
* @param ID Unique identifier that represents a previously allocated memory block
|
||||
*
|
||||
* @param pointerAccess TRUE if the memory block must be accessible through pointer dereferencing, otherwise FALSE
|
||||
*
|
||||
* @return The start address of the memory block represented by ID or NULL if ID is not available
|
||||
*
|
||||
*/
|
||||
virtual uint8_t* reloadNVMemory(uint32_t ID, bool pointerAccess) = 0;
|
||||
|
||||
/**
|
||||
* Is called by the stack after every ETS programming cycle (save())
|
||||
* This function may be used to write ram buffered memory block to a non-volatile one
|
||||
*
|
||||
*/
|
||||
virtual void finishNVMemory() = 0;
|
||||
|
||||
/**
|
||||
* Frees existing memory block identified by the ID
|
||||
* Is called by the stack every time ETS wants to store new data and before it allocates new one
|
||||
*
|
||||
* @param ID Unique identifier that represents a previously allocated memory block
|
||||
*
|
||||
*/
|
||||
virtual void freeNVMemory(uint32_t ID) = 0;
|
||||
|
||||
virtual uint8_t* memoryReference();
|
||||
/**
|
||||
* Provides the offset of the NVMemory address to the ETS address space (16bit)
|
||||
* highest NVMemory address - referenceNVMemory() <= 16bit
|
||||
*
|
||||
* @return The offset address if NVMemory address space is >16bit otherwise NULL
|
||||
*
|
||||
*/
|
||||
virtual uint8_t* referenceNVMemory();
|
||||
|
||||
|
||||
virtual uint8_t* allocMemory(size_t size);
|
||||
virtual void freeMemory(uint8_t* ptr);
|
||||
NVMemory_t NVMemoryType(){return _NVMemoryType;}
|
||||
|
||||
uint8_t popNVMemoryByte(uint8_t** addr);
|
||||
uint16_t popNVMemoryWord(uint8_t** addr);
|
||||
uint32_t popNVMemoryInt(uint8_t** addr);
|
||||
void popNVMemoryArray(uint8_t* dest, uint8_t** addr, size_t size);
|
||||
void pushNVMemoryByte(uint8_t val, uint8_t** addr);
|
||||
void pushNVMemoryWord(uint16_t val, uint8_t** addr);
|
||||
void pushNVMemoryInt(uint32_t val, uint8_t** addr);
|
||||
void pushNVMemoryArray(uint8_t* src, uint8_t** addr, size_t size);
|
||||
protected:
|
||||
uint8_t* _memoryReference = 0;
|
||||
NVMemory_t _NVMemoryType = notDefined;
|
||||
};
|
||||
|
@ -8,26 +8,18 @@ class SaveRestore
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This method is called when the object should save its state to the buffer.
|
||||
*
|
||||
* @param buffer The buffer the object should save its state to.
|
||||
*
|
||||
* @return The buffer plus the size of the object state. The next object will use this value as
|
||||
* the start of its buffer.
|
||||
* This method is called when the object should save its state.
|
||||
*/
|
||||
virtual uint8_t* save(uint8_t* buffer) = 0;
|
||||
virtual uint8_t* save() = 0;
|
||||
virtual void save() = 0;
|
||||
/**
|
||||
* This method is called when the object should restore its state from the buffer.
|
||||
* This method is called when the object should restore its state from the given address.
|
||||
*
|
||||
* @param buffer The buffer the object should restore its state from.
|
||||
* @param startAddr The startAddr 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;
|
||||
virtual void restore(uint8_t* startAddr) = 0;
|
||||
virtual uint32_t size() = 0;
|
||||
void memoryID (uint32_t ID){_ID = ID;}
|
||||
protected:
|
||||
uint32_t _ID;
|
||||
};
|
||||
};
|
||||
|
@ -83,83 +83,41 @@ void TableObject::loadState(LoadState newState)
|
||||
_state = newState;
|
||||
}
|
||||
|
||||
|
||||
uint8_t* TableObject::save(uint8_t* buffer)
|
||||
{
|
||||
buffer = pushByte(_state, buffer);
|
||||
buffer = pushByte(_errorCode, buffer);
|
||||
buffer = pushInt(_size, buffer);
|
||||
buffer = pushByteArray(_data, _size, buffer);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
uint8_t* TableObject::save()
|
||||
void TableObject::save()
|
||||
{
|
||||
if(_data == NULL)
|
||||
return NULL;
|
||||
return;
|
||||
|
||||
uintptr_t addr;
|
||||
uint8_t* buffer;
|
||||
addr =(uintptr_t)(_data - METADATA_SIZE);
|
||||
if(_platform.NVMemoryType() == internalFlash)
|
||||
buffer = new uint8_t[METADATA_SIZE];
|
||||
else
|
||||
buffer = (uint8_t*)addr;
|
||||
uint8_t* addr =_data - METADATA_SIZE;
|
||||
|
||||
buffer = pushByte(_state, buffer);
|
||||
buffer = pushByte(_errorCode, buffer);
|
||||
buffer = pushInt(_size, buffer);
|
||||
buffer -= METADATA_SIZE;
|
||||
|
||||
if(_platform.NVMemoryType() == internalFlash){
|
||||
for(uint32_t i=0;i<METADATA_SIZE;i++)
|
||||
_platform.writeNVMemory(addr+i, buffer[i]);
|
||||
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
return _dataComplete;
|
||||
_platform.pushNVMemoryByte(_state, &addr);
|
||||
_platform.pushNVMemoryByte(_errorCode, &addr);
|
||||
_platform.pushNVMemoryInt(_size, &addr);
|
||||
}
|
||||
|
||||
uint8_t* TableObject::restore(uint8_t* buffer)
|
||||
void TableObject::restore(uint8_t* startAddr)
|
||||
{
|
||||
uint8_t state = 0;
|
||||
uint8_t errorCode = 0;
|
||||
if(_dataComplete == NULL)
|
||||
_dataComplete = buffer;
|
||||
buffer = popByte(state, buffer);
|
||||
buffer = popByte(errorCode, buffer);
|
||||
_state = (LoadState)state;
|
||||
_errorCode = (ErrorCode)errorCode;
|
||||
|
||||
buffer = popInt(_size, buffer);
|
||||
uint8_t* addr = startAddr;
|
||||
_state = (LoadState)_platform.popNVMemoryByte(&addr);
|
||||
_errorCode = (ErrorCode)_platform.popNVMemoryByte(&addr);
|
||||
_size = _platform.popNVMemoryInt(&addr);
|
||||
|
||||
if (_size > 0)
|
||||
_data = buffer;
|
||||
|
||||
_data = addr;
|
||||
else
|
||||
_data = 0;
|
||||
|
||||
buffer += _size;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
uint32_t TableObject::tableReference()
|
||||
{
|
||||
return (uint32_t)(_data - _platform.memoryReference());
|
||||
return (uint32_t)(_data - _platform.referenceNVMemory());
|
||||
}
|
||||
|
||||
bool TableObject::allocTable(uint32_t size, bool doFill, uint8_t fillByte)
|
||||
{
|
||||
if (_dataComplete)
|
||||
if (_data)
|
||||
{
|
||||
if(_platform.NVMemoryType() == internalFlash)
|
||||
_platform.freeNVMemory(_ID);
|
||||
else if(_platform.NVMemoryType() == external)
|
||||
_platform.freeMemory(_dataComplete);
|
||||
_dataComplete = 0;
|
||||
_platform.freeNVMemory(_ID);
|
||||
_data = 0;
|
||||
_size = 0;
|
||||
}
|
||||
@ -167,23 +125,13 @@ bool TableObject::allocTable(uint32_t size, bool doFill, uint8_t fillByte)
|
||||
if (size == 0)
|
||||
return true;
|
||||
|
||||
if(_platform.NVMemoryType() == internalFlash){
|
||||
_dataComplete = (uint8_t*)_platform.allocNVMemory(size+this->size(), _ID);
|
||||
}
|
||||
else{
|
||||
_dataComplete = _platform.allocMemory(size+this->size());
|
||||
}
|
||||
_data = _dataComplete + this->size(); //skip metadata
|
||||
_data = _platform.allocNVMemory(size+this->size(), _ID);
|
||||
_data = _data + this->size(); //skip metadata
|
||||
_size = size;
|
||||
if (doFill){
|
||||
if(_platform.NVMemoryType() == internalFlash){
|
||||
uintptr_t addr = (uintptr_t)_data;
|
||||
for(size_t i=0; i<_size;i++)
|
||||
_platform.writeNVMemory(addr++, fillByte);
|
||||
}
|
||||
else{
|
||||
memset(_data, fillByte, _size);
|
||||
}
|
||||
uint8_t* addr = _data;
|
||||
for(size_t i=0; i<_size;i++)
|
||||
_platform.writeNVMemory(addr++, fillByte);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -25,9 +25,8 @@ public:
|
||||
* This method returns the ::LoadState of the interface object.
|
||||
*/
|
||||
LoadState loadState();
|
||||
virtual uint8_t* save(uint8_t* buffer);
|
||||
virtual uint8_t* save();
|
||||
virtual uint8_t* restore(uint8_t* buffer);
|
||||
virtual void save();
|
||||
virtual void restore(uint8_t* startAddr);
|
||||
virtual uint32_t size();
|
||||
protected:
|
||||
/**
|
||||
@ -53,7 +52,6 @@ protected:
|
||||
void errorCode(ErrorCode errorCode);
|
||||
|
||||
Platform& _platform;
|
||||
uint8_t *_dataComplete = 0;
|
||||
private:
|
||||
uint32_t tableReference();
|
||||
bool allocTable(uint32_t size, bool doFill, uint8_t fillByte);
|
||||
|
@ -19,7 +19,7 @@
|
||||
#endif
|
||||
|
||||
void buttonUp();
|
||||
typedef uint8_t* (*saveRestoreCallback)(uint8_t* buffer);
|
||||
typedef void (*saveRestoreCallback)(uint8_t* buffer);
|
||||
|
||||
template <class P, class B> class KnxFacade : private SaveRestore
|
||||
{
|
||||
@ -288,24 +288,18 @@ template <class P, class B> class KnxFacade : private SaveRestore
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t* save(uint8_t* buffer)
|
||||
void save()
|
||||
{
|
||||
if (_saveCallback != 0)
|
||||
return _saveCallback(buffer);
|
||||
|
||||
return buffer;
|
||||
_saveCallback(NULL);
|
||||
}
|
||||
|
||||
uint8_t* save()
|
||||
{
|
||||
};
|
||||
|
||||
uint8_t* restore(uint8_t* buffer)
|
||||
void restore(uint8_t* startAddr)
|
||||
{
|
||||
if (_restoreCallback != 0)
|
||||
return _restoreCallback(buffer);
|
||||
_restoreCallback(startAddr);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -200,31 +200,86 @@ int LinuxPlatform::readBytes(uint8_t * buffer, uint16_t maxLen)
|
||||
return len;
|
||||
}
|
||||
|
||||
bool LinuxPlatform::writeNVMemory(uintptr_t addr,uint8_t data)
|
||||
bool LinuxPlatform::writeNVMemory(uint8_t* addr,uint8_t data)
|
||||
{
|
||||
*((uint8_t*)addr) = data;
|
||||
*addr = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t LinuxPlatform::readNVMemory(uintptr_t addr)
|
||||
uint8_t LinuxPlatform::readNVMemory(uint8_t* addr)
|
||||
{
|
||||
return *((uint8_t*)addr);
|
||||
return *addr;
|
||||
}
|
||||
|
||||
uintptr_t LinuxPlatform::allocNVMemory(size_t size,uint32_t ID)
|
||||
uint8_t* LinuxPlatform::allocNVMemory(size_t size,uint32_t ID)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<MAX_MEMORY_BLOCKS;i++){
|
||||
if(_memoryBlocks[i].ID == 0)
|
||||
break;
|
||||
}
|
||||
if(i >= MAX_MEMORY_BLOCKS)
|
||||
fatalError();
|
||||
|
||||
|
||||
_memoryBlocks[i].data = (uint8_t*)malloc(size);
|
||||
if(_memoryBlocks[i].data == NULL)
|
||||
fatalError();
|
||||
|
||||
_memoryBlocks[i].ID = ID;
|
||||
_memoryBlocks[i].size = size;
|
||||
|
||||
return _memoryBlocks[i].data;
|
||||
}
|
||||
|
||||
void LinuxPlatform::initNVMemory()
|
||||
{
|
||||
if (_fd < 0)
|
||||
doMemoryMapping();
|
||||
|
||||
return (uintptr_t)(_mappedFile + 2);
|
||||
|
||||
uint8_t* addr = (_mappedFile + 2);
|
||||
|
||||
for (int i = 0; i < MAX_MEMORY_BLOCKS; i++){
|
||||
|
||||
if (*addr++ != 0xBA || *addr++ != 0xAD || *addr++ != 0xC0 || *addr++ != 0xDE){
|
||||
_memoryBlocks[i].ID = 0;
|
||||
_memoryBlocks[i].size = 0;
|
||||
_memoryBlocks[i].data = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
((uint8_t*)&_memoryBlocks[i].ID)[0] = *addr++;
|
||||
((uint8_t*)&_memoryBlocks[i].ID)[1] = *addr++;
|
||||
((uint8_t*)&_memoryBlocks[i].ID)[2] = *addr++;
|
||||
((uint8_t*)&_memoryBlocks[i].ID)[3] = *addr++;
|
||||
|
||||
((uint8_t*)&_memoryBlocks[i].size)[0] = *addr++;
|
||||
((uint8_t*)&_memoryBlocks[i].size)[1] = *addr++;
|
||||
((uint8_t*)&_memoryBlocks[i].size)[2] = *addr++;
|
||||
((uint8_t*)&_memoryBlocks[i].size)[3] = *addr++;
|
||||
|
||||
_memoryBlocks[i].data = addr;
|
||||
addr += _memoryBlocks[i].size;
|
||||
}
|
||||
}
|
||||
|
||||
uintptr_t LinuxPlatform::reloadNVMemory(uint32_t ID)
|
||||
uint8_t* LinuxPlatform::reloadNVMemory(uint32_t ID, bool pointerAccess)
|
||||
{
|
||||
if (_fd < 0)
|
||||
doMemoryMapping();
|
||||
|
||||
return (uintptr_t)(_mappedFile + 2);
|
||||
if(!_MemoryInitialized)
|
||||
initNVMemory();
|
||||
|
||||
_MemoryInitialized=true;
|
||||
|
||||
int i;
|
||||
for(i=0;i<MAX_MEMORY_BLOCKS;i++){
|
||||
if(_memoryBlocks[i].ID == ID)
|
||||
break;
|
||||
}
|
||||
if(i >= MAX_MEMORY_BLOCKS)
|
||||
return 0;
|
||||
|
||||
|
||||
return _memoryBlocks[i].data;
|
||||
}
|
||||
|
||||
void LinuxPlatform::finishNVMemory()
|
||||
@ -232,12 +287,55 @@ void LinuxPlatform::finishNVMemory()
|
||||
if (_fd < 0)
|
||||
doMemoryMapping();
|
||||
|
||||
uint8_t* addr = _mappedFile + 2;
|
||||
|
||||
|
||||
for (int i = 0; i < MAX_MEMORY_BLOCKS; i++)
|
||||
{
|
||||
if(_memoryBlocks[i].ID == 0)
|
||||
continue;
|
||||
|
||||
//write valid mask
|
||||
*addr++ = 0xBA;
|
||||
*addr++ = 0xAD;
|
||||
*addr++ = 0xC0;
|
||||
*addr++ = 0xDE;
|
||||
|
||||
//write ID
|
||||
*addr++ = ((uint8_t*)&_memoryBlocks[i].ID)[0]);
|
||||
*addr++ = ((uint8_t*)&_memoryBlocks[i].ID)[1]);
|
||||
*addr++ = ((uint8_t*)&_memoryBlocks[i].ID)[2]);
|
||||
*addr++ = ((uint8_t*)&_memoryBlocks[i].ID)[3]);
|
||||
|
||||
//write size
|
||||
*addr++ = ((uint8_t*)&_memoryBlocks[i].size)[0]);
|
||||
*addr++ = ((uint8_t*)&_memoryBlocks[i].size)[1]);
|
||||
*addr++ = ((uint8_t*)&_memoryBlocks[i].size)[2]);
|
||||
*addr++ = ((uint8_t*)&_memoryBlocks[i].size)[3]);
|
||||
|
||||
//write data
|
||||
for (uint32_t e=0;e<_memoryBlocks[i].size;e++){
|
||||
*addr++ = _memoryBlocks[i].data[e]);
|
||||
}
|
||||
}
|
||||
fsync(_fd);
|
||||
}
|
||||
|
||||
void LinuxPlatform::freeNVMemory(uint32_t ID)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<MAX_MEMORY_BLOCKS;i++){
|
||||
if(_memoryBlocks[i].ID == ID)
|
||||
break;
|
||||
}
|
||||
if(i >= MAX_MEMORY_BLOCKS)
|
||||
return;
|
||||
|
||||
_memoryBlocks[i].data = NULL;
|
||||
_memoryBlocks[i].size = 0;
|
||||
_memoryBlocks[i].ID = 0;
|
||||
}
|
||||
|
||||
#define FLASHSIZE 0x10000
|
||||
void LinuxPlatform::doMemoryMapping()
|
||||
{
|
||||
|
@ -5,6 +5,14 @@
|
||||
#include <string>
|
||||
#include "knx/platform.h"
|
||||
|
||||
#define MAX_MEMORY_BLOCKS 6
|
||||
|
||||
typedef struct{
|
||||
uint32_t ID;
|
||||
size_t size;
|
||||
uint8_t* data;
|
||||
}MemoryBlock_t;
|
||||
|
||||
class LinuxPlatform: public Platform
|
||||
{
|
||||
using Platform::_memoryReference;
|
||||
@ -44,12 +52,13 @@ public:
|
||||
size_t readBytesUart(uint8_t *buffer, size_t length) override;
|
||||
|
||||
//memory
|
||||
bool writeNVMemory(uintptr_t addr,uint8_t data);
|
||||
uint8_t readNVMemory(uintptr_t addr);
|
||||
uintptr_t allocNVMemory(size_t size,uint32_t ID);
|
||||
uintptr_t reloadNVMemory(uint32_t ID);
|
||||
bool writeNVMemory(uint8_t* addr,uint8_t data);
|
||||
uint8_t readNVMemory(uint8_t* addr);
|
||||
uint8_t* allocNVMemory(size_t size,uint32_t ID);
|
||||
uint8_t* reloadNVMemory(uint32_t ID, bool pointerAccess);
|
||||
void finishNVMemory();
|
||||
void freeNVMemory(uint32_t ID);
|
||||
|
||||
uint8_t* allocMemory(size_t size) override;
|
||||
void freeMemory(uint8_t* ptr) override;
|
||||
void cmdlineArgs(int argc, char** argv);
|
||||
@ -64,6 +73,9 @@ public:
|
||||
uint8_t* _currentMaxMem = 0;
|
||||
std::string _flashFilePath = "flash.bin";
|
||||
char** _args = 0;
|
||||
void initNVMemory();
|
||||
MemoryBlock_t _memoryBlocks[MAX_MEMORY_BLOCKS];
|
||||
bool _MemoryInitialized = false;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -24,8 +24,8 @@ SamdFlash::SamdFlash(){
|
||||
_info = (info_data_t*)getRowAddr(_pageSize*_pageCnt-1); //261888 (rowAddr of last row)
|
||||
}
|
||||
|
||||
uint32_t SamdFlash::getStartAddress(){
|
||||
return _info->freeMemoryStart;
|
||||
uint8_t* SamdFlash::getStartAddress(){
|
||||
return (uint8_t*)_info->freeMemoryStart;
|
||||
}
|
||||
|
||||
uint8_t SamdFlash::read(uint8_t* addr){
|
||||
|
@ -31,7 +31,7 @@ public:
|
||||
bool write(uint8_t* addr, uint8_t data);
|
||||
uint8_t read(uint8_t* addr);
|
||||
void finalise();
|
||||
uint32_t getStartAddress();
|
||||
uint8_t* getStartAddress();
|
||||
|
||||
private:
|
||||
uint8_t* forcemalloc(uint32_t size, uint32_t ID);
|
||||
|
@ -4,18 +4,27 @@
|
||||
#include <knx/bits.h>
|
||||
|
||||
#include <Arduino.h>
|
||||
#ifdef INTERN_FLASH_MEMORY
|
||||
#include "samd_flash.h"
|
||||
|
||||
SamdFlash Flash;
|
||||
#endif
|
||||
#ifdef EXTERN_EEPROM_MEMORY
|
||||
#include "FlashAsEEPROM.h"
|
||||
#endif
|
||||
#ifdef RAM_EMULATED_MEMORY
|
||||
#include "FlashAsEEPROM.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
SamdPlatform::SamdPlatform() : ArduinoPlatform(&Serial1)
|
||||
{
|
||||
Platform::_NVMemoryType = internalFlash;
|
||||
|
||||
}
|
||||
|
||||
SamdPlatform::SamdPlatform( HardwareSerial* s) : ArduinoPlatform(s)
|
||||
{
|
||||
Platform::_NVMemoryType = internalFlash;
|
||||
|
||||
}
|
||||
|
||||
void SamdPlatform::restart()
|
||||
@ -24,31 +33,31 @@ void SamdPlatform::restart()
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
|
||||
bool SamdPlatform::writeNVMemory(uintptr_t addr,uint8_t data)
|
||||
#ifdef INTERN_FLASH_MEMORY
|
||||
bool SamdPlatform::writeNVMemory(uint8_t* addr,uint8_t data)
|
||||
{
|
||||
if(Flash.write((uint8_t*)addr, data)==false)
|
||||
if(Flash.write(addr, data)==false)
|
||||
fatalError();
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t SamdPlatform::readNVMemory(uintptr_t addr)
|
||||
uint8_t SamdPlatform::readNVMemory(uint8_t* addr)
|
||||
{
|
||||
return Flash.read((uint8_t*)addr);
|
||||
return Flash.read(addr);
|
||||
}
|
||||
|
||||
uintptr_t SamdPlatform::allocNVMemory(size_t size,uint32_t ID)
|
||||
uint8_t* SamdPlatform::allocNVMemory(size_t size,uint32_t ID)
|
||||
{
|
||||
uintptr_t addr = (uintptr_t)Flash.malloc(size, ID);
|
||||
uint8_t* addr = Flash.malloc(size, ID);
|
||||
if(addr == 0)
|
||||
fatalError();
|
||||
return addr;
|
||||
}
|
||||
|
||||
uintptr_t SamdPlatform::reloadNVMemory(uint32_t ID)
|
||||
uint8_t* SamdPlatform::reloadNVMemory(uint32_t ID, bool pointerAccess)
|
||||
{
|
||||
// Flash.erase();
|
||||
return (uintptr_t)Flash.loadBlock(ID);
|
||||
return Flash.loadBlock(ID);
|
||||
}
|
||||
|
||||
void SamdPlatform::finishNVMemory()
|
||||
@ -59,85 +68,293 @@ void SamdPlatform::finishNVMemory()
|
||||
void SamdPlatform::freeNVMemory(uint32_t ID)
|
||||
{
|
||||
Flash.free(ID);
|
||||
// Flash.erase();
|
||||
}
|
||||
|
||||
uint8_t* SamdPlatform::memoryReference()
|
||||
uint8_t* SamdPlatform::referenceNVMemory()
|
||||
{
|
||||
return (uint8_t*)Flash.getStartAddress();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*************_NVMemoryType = internalRam*************************
|
||||
|
||||
bool SamdPlatform::writeNVMemory(uintptr_t addr,uint8_t data)
|
||||
#ifdef EXTERN_EEPROM_MEMORY
|
||||
bool SamdPlatform::writeNVMemory(uint8_t* addr,uint8_t data)
|
||||
{
|
||||
*((uint8_t*)addr) = data;
|
||||
*addr = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t SamdPlatform::readNVMemory(uintptr_t addr)
|
||||
uint8_t SamdPlatform::readNVMemory(uint8_t* addr)
|
||||
{
|
||||
return *((uint8_t*)addr);
|
||||
return *addr;
|
||||
}
|
||||
|
||||
uintptr_t SamdPlatform::allocNVMemory(size_t size,uint32_t ID)
|
||||
uint8_t* SamdPlatform::allocNVMemory(size_t size,uint32_t ID)
|
||||
{
|
||||
if(size > EEPROM_EMULATION_SIZE)
|
||||
int i;
|
||||
for(i=0;i<MAX_MEMORY_BLOCKS;i++){
|
||||
if(_memoryBlocks[i].ID == 0)
|
||||
break;
|
||||
}
|
||||
if(i >= MAX_MEMORY_BLOCKS)
|
||||
fatalError();
|
||||
return (uintptr_t)EEPROM.getDataPtr();
|
||||
|
||||
|
||||
_memoryBlocks[i].data = (uint8_t*)malloc(size);
|
||||
if(_memoryBlocks[i].data == NULL)
|
||||
fatalError();
|
||||
|
||||
_memoryBlocks[i].ID = ID;
|
||||
_memoryBlocks[i].size = size;
|
||||
|
||||
return _memoryBlocks[i].data;
|
||||
}
|
||||
|
||||
uintptr_t SamdPlatform::reloadNVMemory(uint32_t ID)
|
||||
void SamdPlatform::initNVMemory()
|
||||
{
|
||||
return (uintptr_t)EEPROM.getDataPtr();
|
||||
uint32_t addr = 0;
|
||||
for (int i = 0; i < MAX_MEMORY_BLOCKS; i++){
|
||||
|
||||
if (EEPROM.read(addr++) != 0xBA || EEPROM.read(addr++) != 0xAD || EEPROM.read(addr++) != 0xC0 || EEPROM.read(addr++) != 0xDE){
|
||||
_memoryBlocks[i].ID = 0;
|
||||
_memoryBlocks[i].size = 0;
|
||||
_memoryBlocks[i].data = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
((uint8_t*)&_memoryBlocks[i].ID)[0] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].ID)[1] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].ID)[2] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].ID)[3] = EEPROM.read(addr++);
|
||||
|
||||
((uint8_t*)&_memoryBlocks[i].size)[0] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].size)[1] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].size)[2] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].size)[3] = EEPROM.read(addr++);
|
||||
|
||||
_memoryBlocks[i].data = (uint8_t*)malloc(_memoryBlocks[i].size);
|
||||
if(_memoryBlocks[i].data == NULL)
|
||||
fatalError();
|
||||
|
||||
//read data
|
||||
for (uint32_t e=0;e<_memoryBlocks[i].size;e++){
|
||||
_memoryBlocks[i].data[e] = EEPROM.read(addr++);
|
||||
}
|
||||
}
|
||||
}
|
||||
uint8_t* SamdPlatform::reloadNVMemory(uint32_t ID, bool pointerAccess)
|
||||
{
|
||||
if(!_MemoryInitialized)
|
||||
initNVMemory();
|
||||
|
||||
_MemoryInitialized=true;
|
||||
|
||||
int i;
|
||||
for(i=0;i<MAX_MEMORY_BLOCKS;i++){
|
||||
if(_memoryBlocks[i].ID == ID)
|
||||
break;
|
||||
}
|
||||
if(i >= MAX_MEMORY_BLOCKS)
|
||||
return 0;
|
||||
|
||||
|
||||
return _memoryBlocks[i].data;
|
||||
}
|
||||
|
||||
void SamdPlatform::finishNVMemory()
|
||||
{
|
||||
uint32_t addr = 0;
|
||||
|
||||
for (int i = 0; i < MAX_MEMORY_BLOCKS; i++)
|
||||
{
|
||||
if(_memoryBlocks[i].ID == 0)
|
||||
continue;
|
||||
|
||||
//write valid mask
|
||||
EEPROM.write(addr++,0xBA);
|
||||
EEPROM.write(addr++,0xAD);
|
||||
EEPROM.write(addr++,0xC0);
|
||||
EEPROM.write(addr++,0xDE);
|
||||
|
||||
//write ID
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].ID)[0]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].ID)[1]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].ID)[2]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].ID)[3]);
|
||||
|
||||
//write size
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].size)[0]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].size)[1]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].size)[2]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].size)[3]);
|
||||
|
||||
//write data
|
||||
for (uint32_t e=0;e<_memoryBlocks[i].size;e++){
|
||||
EEPROM.write(addr++,_memoryBlocks[i].data[e]);
|
||||
}
|
||||
}
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
void SamdPlatform::freeNVMemory(uint32_t ID)
|
||||
{
|
||||
}
|
||||
/*
|
||||
int i;
|
||||
for(i=0;i<MAX_MEMORY_BLOCKS;i++){
|
||||
if(_memoryBlocks[i].ID == ID)
|
||||
break;
|
||||
}
|
||||
if(i >= MAX_MEMORY_BLOCKS)
|
||||
return;
|
||||
|
||||
/*************_NVMemoryType = external*************************
|
||||
bool SamdPlatform::writeNVMemory(uintptr_t addr,uint8_t data)
|
||||
free(_memoryBlocks[i].data);
|
||||
_memoryBlocks[i].data = NULL;
|
||||
_memoryBlocks[i].size = 0;
|
||||
_memoryBlocks[i].ID = 0;
|
||||
}
|
||||
|
||||
|
||||
uint8_t* SamdPlatform::referenceNVMemory()
|
||||
{
|
||||
EEPROM.write(addr-1, data);
|
||||
return (uint8_t*)0x20000000; //ram base address
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef RAM_EMULATED_MEMORY
|
||||
bool SamdPlatform::writeNVMemory(uint8_t* addr,uint8_t data)
|
||||
{
|
||||
*addr = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t SamdPlatform::readNVMemory(uintptr_t addr)
|
||||
uint8_t SamdPlatform::readNVMemory(uint8_t* addr)
|
||||
{
|
||||
return EEPROM.read(addr-1);
|
||||
return *addr;
|
||||
}
|
||||
|
||||
uintptr_t SamdPlatform::allocNVMemory(size_t size,uint32_t ID)
|
||||
uint8_t* SamdPlatform::allocNVMemory(size_t size,uint32_t ID)
|
||||
{
|
||||
if(size > EEPROM_EMULATION_SIZE)
|
||||
int i;
|
||||
for(i=0;i<MAX_MEMORY_BLOCKS;i++){
|
||||
if(_memoryBlocks[i].ID == 0)
|
||||
break;
|
||||
}
|
||||
if(i >= MAX_MEMORY_BLOCKS)
|
||||
fatalError();
|
||||
return 1;
|
||||
|
||||
|
||||
_memoryBlocks[i].data = (uint8_t*)malloc(size);
|
||||
if(_memoryBlocks[i].data == NULL)
|
||||
fatalError();
|
||||
|
||||
_memoryBlocks[i].ID = ID;
|
||||
_memoryBlocks[i].size = size;
|
||||
|
||||
return _memoryBlocks[i].data;
|
||||
}
|
||||
|
||||
uintptr_t SamdPlatform::reloadNVMemory(uint32_t ID)
|
||||
void SamdPlatform::initNVMemory()
|
||||
{
|
||||
return 1;
|
||||
uint32_t addr = 0;
|
||||
for (int i = 0; i < MAX_MEMORY_BLOCKS; i++){
|
||||
|
||||
if (EEPROM.read(addr++) != 0xBA || EEPROM.read(addr++) != 0xAD || EEPROM.read(addr++) != 0xC0 || EEPROM.read(addr++) != 0xDE){
|
||||
_memoryBlocks[i].ID = 0;
|
||||
_memoryBlocks[i].size = 0;
|
||||
_memoryBlocks[i].data = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
((uint8_t*)&_memoryBlocks[i].ID)[0] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].ID)[1] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].ID)[2] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].ID)[3] = EEPROM.read(addr++);
|
||||
|
||||
((uint8_t*)&_memoryBlocks[i].size)[0] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].size)[1] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].size)[2] = EEPROM.read(addr++);
|
||||
((uint8_t*)&_memoryBlocks[i].size)[3] = EEPROM.read(addr++);
|
||||
|
||||
_memoryBlocks[i].data = EEPROM.getDataPtr() + addr;
|
||||
addr += _memoryBlocks[i].size;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* SamdPlatform::reloadNVMemory(uint32_t ID, bool pointerAccess)
|
||||
{
|
||||
if(!_MemoryInitialized)
|
||||
initNVMemory();
|
||||
|
||||
_MemoryInitialized=true;
|
||||
|
||||
int i;
|
||||
for(i=0;i<MAX_MEMORY_BLOCKS;i++){
|
||||
if(_memoryBlocks[i].ID == ID)
|
||||
break;
|
||||
}
|
||||
if(i >= MAX_MEMORY_BLOCKS)
|
||||
return 0;
|
||||
|
||||
|
||||
return _memoryBlocks[i].data;
|
||||
}
|
||||
|
||||
void SamdPlatform::finishNVMemory()
|
||||
{
|
||||
uint32_t addr = 0;
|
||||
|
||||
for (int i = 0; i < MAX_MEMORY_BLOCKS; i++)
|
||||
{
|
||||
if(_memoryBlocks[i].ID == 0)
|
||||
continue;
|
||||
|
||||
//write valid mask
|
||||
EEPROM.write(addr++,0xBA);
|
||||
EEPROM.write(addr++,0xAD);
|
||||
EEPROM.write(addr++,0xC0);
|
||||
EEPROM.write(addr++,0xDE);
|
||||
|
||||
//write ID
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].ID)[0]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].ID)[1]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].ID)[2]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].ID)[3]);
|
||||
|
||||
//write size
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].size)[0]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].size)[1]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].size)[2]);
|
||||
EEPROM.write(addr++,((uint8_t*)&_memoryBlocks[i].size)[3]);
|
||||
|
||||
//write data
|
||||
for (uint32_t e=0;e<_memoryBlocks[i].size;e++){
|
||||
EEPROM.write(addr++,_memoryBlocks[i].data[e]);
|
||||
}
|
||||
}
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
void SamdPlatform::freeNVMemory(uint32_t ID)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<MAX_MEMORY_BLOCKS;i++){
|
||||
if(_memoryBlocks[i].ID == ID)
|
||||
break;
|
||||
}
|
||||
if(i >= MAX_MEMORY_BLOCKS)
|
||||
return;
|
||||
|
||||
_memoryBlocks[i].data = NULL;
|
||||
_memoryBlocks[i].size = 0;
|
||||
_memoryBlocks[i].ID = 0;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
uint8_t* SamdPlatform::referenceNVMemory()
|
||||
{
|
||||
return (uint8_t*)0x20000000; //ram base address
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -4,6 +4,21 @@
|
||||
|
||||
#ifdef ARDUINO_ARCH_SAMD
|
||||
|
||||
//define which memory type is used for non-volatile memory
|
||||
#define INTERN_FLASH_MEMORY
|
||||
//#define EXTERN_EEPROM_MEMORY
|
||||
//#define RAM_EMULATED_MEMORY //like FlashStorage lib
|
||||
|
||||
#ifndef INTERN_FLASH_MEMORY
|
||||
#define MAX_MEMORY_BLOCKS 6
|
||||
|
||||
typedef struct{
|
||||
uint32_t ID;
|
||||
size_t size;
|
||||
uint8_t* data;
|
||||
}MemoryBlock_t;
|
||||
#endif
|
||||
|
||||
class SamdPlatform : public ArduinoPlatform
|
||||
{
|
||||
public:
|
||||
@ -11,13 +26,19 @@ public:
|
||||
SamdPlatform( HardwareSerial* s);
|
||||
|
||||
void restart();
|
||||
bool writeNVMemory(uintptr_t addr,uint8_t data);
|
||||
uint8_t readNVMemory(uintptr_t addr);
|
||||
uintptr_t allocNVMemory(size_t size,uint32_t ID);
|
||||
uintptr_t reloadNVMemory(uint32_t ID);
|
||||
bool writeNVMemory(uint8_t* addr,uint8_t data);
|
||||
uint8_t readNVMemory(uint8_t* addr);
|
||||
uint8_t* allocNVMemory(size_t size,uint32_t ID);
|
||||
uint8_t* reloadNVMemory(uint32_t ID, bool pointerAccess);
|
||||
void finishNVMemory();
|
||||
void freeNVMemory(uint32_t ID);
|
||||
uint8_t* memoryReference();
|
||||
uint8_t* referenceNVMemory();
|
||||
private:
|
||||
#ifndef INTERN_FLASH_MEMORY
|
||||
void initNVMemory();
|
||||
MemoryBlock_t _memoryBlocks[MAX_MEMORY_BLOCKS];
|
||||
bool _MemoryInitialized = false;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user