-change memory management

This commit is contained in:
Bernhard 2019-10-08 21:38:45 +02:00
parent 29ef91f2e0
commit afe3ae7936
26 changed files with 1112 additions and 67 deletions

View File

@ -84,15 +84,36 @@ int Esp32Platform::readBytes(uint8_t * buffer, uint16_t maxLen)
return len;
}
uint8_t * Esp32Platform::getEepromBuffer(uint16_t size)
bool Esp32Platform::writeNVMemory(uint32_t addr,uint8_t data)
{
EEPROM.begin(size);
return EEPROM.getDataPtr();
*((uint8_t*)addr) = data;
return true;
}
void Esp32Platform::commitToEeprom()
uint8_t Esp32Platform::readNVMemory(uint32_t addr)
{
return *((uint8_t*)addr);
}
uint32_t Esp32Platform::allocNVMemory(uint32_t size,uint32_t ID)
{
if(size > EEPROM_EMULATION_SIZE)
fatalError();
return (uint32_t)EEPROM.getDataPtr();
}
uint32_t Esp32Platform::reloadNVMemory(uint32_t ID)
{
EEPROM.begin(1024);
return (uint32_t)EEPROM.getDataPtr();
}
void Esp32Platform::finishNVMemory()
{
EEPROM.commit();
}
void Esp32Platform::freeNVMemory(uint32_t ID)
{
}
#endif

View File

@ -28,8 +28,12 @@ public:
int readBytes(uint8_t* buffer, uint16_t maxLen) override;
//memory
uint8_t* getEepromBuffer(uint16_t size);
void commitToEeprom();
bool writeNVMemory(uint32_t addr,uint8_t data);
uint8_t readNVMemory(uint32_t addr);
uint32_t allocNVMemory(uint32_t size,uint32_t ID);
uint32_t reloadNVMemory(uint32_t ID);
void finishNVMemory();
void freeNVMemory(uint32_t ID);
private:
WiFiUDP _udp;
};

View File

@ -85,14 +85,36 @@ int EspPlatform::readBytes(uint8_t * buffer, uint16_t maxLen)
return len;
}
uint8_t * EspPlatform::getEepromBuffer(uint16_t size)
bool EspPlatform::writeNVMemory(uint32_t addr,uint8_t data)
{
EEPROM.begin(size);
return EEPROM.getDataPtr();
*((uint8_t*)addr) = data;
return true;
}
void EspPlatform::commitToEeprom()
uint8_t EspPlatform::readNVMemory(uint32_t addr)
{
return *((uint8_t*)addr);
}
uint32_t EspPlatform::allocNVMemory(uint32_t size,uint32_t ID)
{
if(size > EEPROM_EMULATION_SIZE)
fatalError();
return (uint32_t)EEPROM.getDataPtr();
}
uint32_t EspPlatform::reloadNVMemory(uint32_t ID)
{
EEPROM.begin(1024);
return (uint32_t)EEPROM.getDataPtr();
}
void EspPlatform::finishNVMemory()
{
EEPROM.commit();
}
void EspPlatform::freeNVMemory(uint32_t ID)
{
}
#endif

View File

@ -29,8 +29,12 @@ class EspPlatform : public ArduinoPlatform
int readBytes(uint8_t* buffer, uint16_t maxLen) override;
//memory
uint8_t* getEepromBuffer(uint16_t size);
void commitToEeprom();
bool writeNVMemory(uint32_t addr,uint8_t data);
uint8_t readNVMemory(uint32_t addr);
uint32_t allocNVMemory(uint32_t size,uint32_t ID);
uint32_t reloadNVMemory(uint32_t ID);
void finishNVMemory();
void freeNVMemory(uint32_t ID);
private:
WiFiUDP _udp;
};

View File

@ -74,6 +74,35 @@ uint32_t ApplicationProgramObject::getInt(uint32_t addr)
return ::getInt(TableObject::data() + addr);
}
uint32_t ApplicationProgramObject::size(){
return sizeof(_programVersion)+TableObject::size();
}
uint8_t* ApplicationProgramObject::save()
{
if(TableObject::data() == NULL)
return NULL;
uint8_t* buffer;
uint32_t addr =(uint32_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]);
free (buffer);
}
return TableObject::save();
}
uint8_t* ApplicationProgramObject::save(uint8_t* buffer)
{
buffer = pushByteArray(_programVersion, 5, buffer);
@ -83,8 +112,8 @@ uint8_t* ApplicationProgramObject::save(uint8_t* buffer)
uint8_t* ApplicationProgramObject::restore(uint8_t* buffer)
{
TableObject::_dataComplete = buffer;
buffer = popByteArray(_programVersion, 5, buffer);
return TableObject::restore(buffer);
}

View File

@ -14,7 +14,9 @@ class ApplicationProgramObject : public TableObject
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);
uint32_t size();
protected:
uint8_t propertyCount();

View File

@ -5,7 +5,7 @@
BauSystemB::BauSystemB(Platform& platform): _memory(platform), _addrTable(platform),
_assocTable(platform), _groupObjTable(platform), _appProgram(platform),
_platform(platform), _appLayer(_assocTable, *this),
_transLayer(_appLayer, _addrTable), _netLayer(_transLayer)
_transLayer(_appLayer, _addrTable), _netLayer(_transLayer), _deviceObj(platform)
{
_appLayer.transportLayer(_transLayer);
_transLayer.networkLayer(_netLayer);
@ -139,7 +139,13 @@ 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)
{
memcpy(_platform.memoryReference() + memoryAddress, data, number);
if(_platform.NVMemoryType() == internalFlash){
for(uint8_t i=0;i<number;i++)
_platform.writeNVMemory((uint32_t)_platform.memoryReference() + memoryAddress+i, data[i]);
}
else
memcpy(_platform.memoryReference() + memoryAddress, data, number);
_memory.memoryModified();
if (_deviceObj.verifyMode())
@ -149,8 +155,17 @@ 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((uint32_t)_platform.memoryReference() + memoryAddress+i);
_appLayer.memoryReadResponse(AckRequested, priority, hopType, asap, number, memoryAddress,buffer);
}
else{
_appLayer.memoryReadResponse(AckRequested, priority, hopType, asap, number, memoryAddress,
_platform.memoryReference() + memoryAddress);
_platform.memoryReference() + memoryAddress);
}
}
void BauSystemB::restartRequestIndication(Priority priority, HopCountType hopType, uint16_t asap)
@ -167,13 +182,27 @@ void BauSystemB::authorizeIndication(Priority priority, HopCountType hopType, ui
void BauSystemB::userMemoryReadIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, uint32_t memoryAddress)
{
_appLayer.userMemoryReadResponse(AckRequested, priority, hopType, asap, number, memoryAddress,
_platform.memoryReference() + memoryAddress);
if(_platform.NVMemoryType() == internalFlash){
uint8_t* buffer = new uint8_t[number];
for(uint8_t i=0;i<number;i++)
buffer[i] = _platform.readNVMemory((uint32_t)_platform.memoryReference() + memoryAddress+i);
_appLayer.userMemoryReadResponse(AckRequested, priority, hopType, asap, number, memoryAddress,buffer);
}
else{
_appLayer.userMemoryReadResponse(AckRequested, priority, hopType, asap, number, memoryAddress,
_platform.memoryReference() + memoryAddress);
}
}
void BauSystemB::userMemoryWriteIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, uint32_t memoryAddress, uint8_t* data)
{
memcpy(_platform.memoryReference() + memoryAddress, data, number);
if(_platform.NVMemoryType() == internalFlash){
for(uint8_t i=0;i<number;i++)
_platform.writeNVMemory((uint32_t)_platform.memoryReference() + memoryAddress+i, data[i]);
}
else{
memcpy(_platform.memoryReference() + memoryAddress, data, number);
}
_memory.memoryModified();
if (_deviceObj.verifyMode())

View File

@ -2,6 +2,15 @@
#include "device_object.h"
#include "bits.h"
#define METADATA_SIZE (sizeof(_deviceControl)+sizeof(_routingCount)+sizeof(_ownAddress))
DeviceObject::DeviceObject(Platform& platform): _platform(platform)
{
for(int i = 0; i < 10; ++i)
_orderNumber[i] = 0;
for(int i = 0; i < 6; ++i)
_hardwareType[i] = 0;
}
void DeviceObject::readProperty(PropertyID propertyId, uint32_t start, uint32_t& count, uint8_t* data)
{
switch (propertyId)
@ -106,6 +115,32 @@ uint8_t DeviceObject::propertySize(PropertyID id)
return 0;
}
uint32_t DeviceObject::size(){
return METADATA_SIZE;
}
uint8_t* DeviceObject::save()
{
uint8_t* buffer = new uint8_t[METADATA_SIZE];
buffer = pushByte(_deviceControl, buffer);
buffer = pushByte(_routingCount, buffer);
buffer = pushWord(_ownAddress, buffer);
buffer -= METADATA_SIZE;
if(_platform.NVMemoryType() == internalFlash){
_platform.freeNVMemory(_ID);
uint32_t addr = _platform.allocNVMemory(METADATA_SIZE, _ID);
for(uint32_t i=0;i<METADATA_SIZE;i++)
_platform.writeNVMemory(addr+i, buffer[i]);
free (buffer);
return (uint8_t*)addr;
}
return buffer;
}
uint8_t* DeviceObject::save(uint8_t* buffer)
{
buffer = pushByte(_deviceControl, buffer);

View File

@ -1,15 +1,19 @@
#pragma once
#include "interface_object.h"
#include "platform.h"
class DeviceObject: public InterfaceObject
{
public:
DeviceObject(Platform& platform);
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);
uint32_t size();
void readPropertyDescription(uint8_t propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access);
@ -45,7 +49,8 @@ private:
uint16_t _ownAddress = 0;
uint16_t _manufacturerId = 0xfa; //Default to KNXA
uint32_t _bauNumber = 0;
char _orderNumber[10] = "";
uint8_t _hardwareType[6] = { 0, 0, 0, 0, 0, 0};
char _orderNumber[10];
uint8_t _hardwareType[6];
uint16_t _version = 0;
Platform& _platform;
};

View File

@ -1810,7 +1810,7 @@ void float16ToPayload(uint8_t* payload, size_t payload_length, int index, double
if (wasNegative)
mantissa *= -1;
println(mantissa);
// println(mantissa);
signed16ToPayload(payload, payload_length, index, mantissa, mask);
unsigned8ToPayload(payload, payload_length, index, exponent << 3, 0x78 & (mask >> 8));
@ -1839,4 +1839,4 @@ void bcdToPayload(uint8_t* payload, size_t payload_length, int index, uint8_t va
payload[index / 2] = (payload[index / 2] & 0xF0) | (value & 0x0F);
else
payload[index / 2] = (payload[index / 2] & 0x0F) | ((value << 4) & 0xF0);
}
}

View File

@ -5,6 +5,15 @@
//224.0.23.12
#define DEFAULT_MULTICAST_ADDR 0xE000170C
#define METADATA_SIZE ( sizeof(_projectInstallationId) \
+sizeof(_ipAssignmentMethod) \
+sizeof(_ipCapabilities) \
+sizeof(_ipAddress) \
+sizeof(_subnetMask) \
+sizeof(_defaultGateway) \
+sizeof(_multicastAddress) \
+sizeof(_ttl) \
+sizeof(_friendlyName))
IpParameterObject::IpParameterObject(DeviceObject& deviceObject, Platform& platform): _deviceObject(deviceObject),
_platform(platform)
@ -146,6 +155,38 @@ uint8_t IpParameterObject::propertySize(PropertyID id)
}
return 0;
}
uint32_t IpParameterObject::size(){
return METADATA_SIZE;
}
uint8_t* IpParameterObject::save()
{
uint8_t* buffer = new uint8_t[METADATA_SIZE];
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);
uint32_t addr = _platform.allocNVMemory(METADATA_SIZE, _ID);
for(uint32_t i=0;i<METADATA_SIZE;i++)
_platform.writeNVMemory(addr+i, buffer[i]);
free (buffer);
return (uint8_t*)addr;
}
return buffer;
}
uint8_t* IpParameterObject::save(uint8_t* buffer)
{
@ -320,4 +361,4 @@ uint8_t IpParameterObject::propertyCount()
PropertyDescription* IpParameterObject::propertyDescriptions()
{
return _propertyDescriptions;
}
}

View File

@ -13,7 +13,9 @@ class IpParameterObject : public InterfaceObject
uint8_t propertySize(PropertyID id);
uint8_t* save(uint8_t* buffer);
uint8_t* save();
uint8_t* restore(uint8_t* buffer);
uint32_t size();
uint32_t multicastAddress() const;
uint8_t ttl() const { return _ttl; }

View File

@ -1,5 +1,7 @@
#include "memory.h"
#define BASE_ID 0xC0DE0000
Memory::Memory(Platform & platform): _platform(platform)
{
}
@ -14,9 +16,66 @@ bool Memory::isMemoryModified()
return _modified;
}
void Memory::readMemory()
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()
{
_data = _platform.getEepromBuffer(512);
for (int i = 0; i < _saveCount; i++)
{
uint8_t* data = (uint8_t*)_platform.reloadNVMemory(BASE_ID+i);
if(data == NULL)
continue;
_saveRestores[i]->restore(data);
}
}
void Memory::writeFlashMemory()
{
for (int i = 0; i < _saveCount; i++){
_saveRestores[i]->save();
}
_platform.finishNVMemory();
_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;
@ -26,11 +85,20 @@ void Memory::readMemory()
for (int i = 0; i < size; i++)
{
buffer = _saveRestores[i]->restore(buffer);
buffer = (uint8_t*)(((uint32_t)buffer + 3) / 4 * 4); //allign to 32bit
}
}
void Memory::writeMemory()
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;
@ -41,16 +109,103 @@ void Memory::writeMemory()
for (int i = 0; i < size; i++)
{
buffer = _saveRestores[i]->save(buffer);
buffer = (uint8_t*)(((uint32_t)buffer + 3) / 4 * 4); //allign to 32bit
}
_platform.commitToEeprom();
_platform.finishNVMemory();
_modified = false;
}
void Memory::readExternalMemory()
{
int size = _saveCount;
volatile uint32_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;
}
uint32_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)
return;
obj->memoryID(BASE_ID + _saveCount);
_saveRestores[_saveCount] = obj;
_saveCount += 1;
}

View File

@ -16,6 +16,12 @@ 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};

View File

@ -12,6 +12,8 @@ uint8_t* Platform::memoryReference()
uint8_t* Platform::allocMemory(size_t size)
{
uint8_t* address = (uint8_t*)malloc(size);
if(address == NULL)
fatalError();
// if (_memoryReference == 0 || address < _memoryReference)
// _memoryReference = address;
print("MemRef: ");

View File

@ -4,6 +4,13 @@
#include <stddef.h>
#include "save_restore.h"
typedef enum{
notDefined,
internalRam,
internalFlash,
external
}NVMemory_t;
class Platform
{
public:
@ -29,13 +36,18 @@ class Platform
virtual int readUart() = 0;
virtual size_t readBytesUart(uint8_t* buffer, size_t length) = 0;
virtual uint8_t* getEepromBuffer(uint16_t size) = 0;
virtual void commitToEeprom() = 0;
virtual bool writeNVMemory(uint32_t addr,uint8_t data) = 0;
virtual uint8_t readNVMemory(uint32_t addr) = 0;
virtual uint32_t allocNVMemory(uint32_t size,uint32_t ID) = 0;
virtual uint32_t reloadNVMemory(uint32_t ID) = 0;
virtual void finishNVMemory() = 0;
virtual void freeNVMemory(uint32_t ID) = 0;
virtual uint8_t* memoryReference();
virtual uint8_t* allocMemory(size_t size);
virtual void freeMemory(uint8_t* ptr);
NVMemory_t NVMemoryType(){return _NVMemoryType;}
protected:
uint8_t* _memoryReference = 0;
};
NVMemory_t _NVMemoryType = notDefined;
};

View File

@ -16,6 +16,7 @@ class SaveRestore
* the start of its buffer.
*/
virtual uint8_t* save(uint8_t* buffer) = 0;
virtual uint8_t* save() = 0;
/**
* This method is called when the object should restore its state from the buffer.
*
@ -25,4 +26,8 @@ class SaveRestore
* the start of its buffer.
*/
virtual uint8_t* restore(uint8_t* buffer) = 0;
virtual uint32_t size() = 0;
void memoryID (uint32_t ID){_ID = ID;}
protected:
uint32_t _ID;
};

View File

@ -3,6 +3,8 @@
#include "table_object.h"
#include "bits.h"
#define METADATA_SIZE (sizeof(_state)+sizeof(_errorCode)+sizeof(_size))
TableObject::TableObject(Platform& platform): _platform(platform)
{
@ -92,11 +94,40 @@ uint8_t* TableObject::save(uint8_t* buffer)
return buffer;
}
uint8_t* TableObject::save()
{
if(_data == NULL)
return NULL;
uint32_t addr;
uint8_t* buffer;
addr =(uint32_t)(_data - METADATA_SIZE);
if(_platform.NVMemoryType() == internalFlash)
buffer = new uint8_t[METADATA_SIZE];
else
buffer = (uint8_t*)addr;
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]);
free (buffer);
}
return _dataComplete;
}
uint8_t* TableObject::restore(uint8_t* buffer)
{
uint8_t state = 0;
uint8_t errorCode = 0;
if(_dataComplete == NULL)
_dataComplete = buffer;
buffer = popByte(state, buffer);
buffer = popByte(errorCode, buffer);
_state = (LoadState)state;
@ -104,15 +135,13 @@ uint8_t* TableObject::restore(uint8_t* buffer)
buffer = popInt(_size, buffer);
if (_data)
_platform.freeMemory(_data);
if (_size > 0)
_data = _platform.allocMemory(_size);
_data = buffer;
else
_data = 0;
buffer = popByteArray(_data, _size, buffer);
buffer += _size;
return buffer;
}
@ -124,9 +153,13 @@ uint32_t TableObject::tableReference()
bool TableObject::allocTable(uint32_t size, bool doFill, uint8_t fillByte)
{
if (_data)
if (_dataComplete)
{
_platform.freeMemory(_data);
if(_platform.NVMemoryType() == internalFlash)
_platform.freeNVMemory(_ID);
else if(_platform.NVMemoryType() == external)
_platform.freeMemory(_dataComplete);
_dataComplete = 0;
_data = 0;
_size = 0;
}
@ -134,15 +167,24 @@ bool TableObject::allocTable(uint32_t size, bool doFill, uint8_t fillByte)
if (size == 0)
return true;
_data = _platform.allocMemory(size);
if (!_data)
return false;
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
_size = size;
if (doFill)
memset(_data, fillByte, size);
if (doFill){
if(_platform.NVMemoryType() == internalFlash){
uint32_t addr = (uint32_t)_data;
for(uint32_t i=0; i<_size;i++)
_platform.writeNVMemory(addr++, fillByte);
}
else{
memset(_data, fillByte, _size);
}
}
return true;
}
@ -279,7 +321,12 @@ uint8_t* TableObject::data()
uint32_t TableObject::size()
{
return _size;
return _size + METADATA_SIZE;
}
uint32_t TableObject::sizeMetadata()
{
return METADATA_SIZE;
}
void TableObject::errorCode(ErrorCode errorCode)

View File

@ -26,7 +26,9 @@ public:
*/
LoadState loadState();
virtual uint8_t* save(uint8_t* buffer);
virtual uint8_t* save();
virtual uint8_t* restore(uint8_t* buffer);
virtual uint32_t size();
protected:
/**
* This method is called before the interface object enters a new ::LoadState.
@ -40,15 +42,18 @@ protected:
* must not be freed.
*/
uint8_t* data();
uint32_t sizeMetadata();
/**
* returns the size of the internal data of the interface object int byte.
*/
uint32_t size();
// uint32_t size();
/**
* Set the reason for a state change failure.
*/
void errorCode(ErrorCode errorCode);
Platform& _platform;
uint8_t *_dataComplete = 0;
private:
uint32_t tableReference();
bool allocTable(uint32_t size, bool doFill, uint8_t fillByte);
@ -67,7 +72,6 @@ protected:
*/
void loadState(LoadState newState);
LoadState _state = LS_UNLOADED;
Platform& _platform;
uint8_t *_data = 0;
uint32_t _size = 0;
ErrorCode _errorCode = E_NO_FAULT;

View File

@ -257,9 +257,16 @@ template <class P, class B> class KnxFacade : private SaveRestore
uint32_t _buttonPin = 0;
saveRestoreCallback _saveCallback = 0;
saveRestoreCallback _restoreCallback = 0;
uint32_t (*_sizeCallback)() = 0;
bool _toogleProgMode = false;
bool _progLedState = false;
uint32_t size(){
if (_sizeCallback != 0)
return _sizeCallback();
return 0;
}
uint8_t* save(uint8_t* buffer)
{
if (_saveCallback != 0)
@ -268,6 +275,7 @@ template <class P, class B> class KnxFacade : private SaveRestore
return buffer;
}
uint8_t* save(){};
uint8_t* restore(uint8_t* buffer)
{
if (_restoreCallback != 0)

View File

@ -200,22 +200,44 @@ int LinuxPlatform::readBytes(uint8_t * buffer, uint16_t maxLen)
return len;
}
uint8_t * LinuxPlatform::getEepromBuffer(uint16_t size)
bool LinuxPlatform::writeNVMemory(uint32_t addr,uint8_t data)
{
if (_fd < 0)
doMemoryMapping();
return _mappedFile + 2;
*((uint8_t*)addr) = data;
return true;
}
void LinuxPlatform::commitToEeprom()
uint8_t LinuxPlatform::readNVMemory(uint32_t addr)
{
return *((uint8_t*)addr);
}
uint32_t LinuxPlatform::allocNVMemory(uint32_t size,uint32_t ID)
{
if (_fd < 0)
doMemoryMapping();
return (uint32_t)_mappedFile + 2;
}
uint32_t LinuxPlatform::reloadNVMemory(uint32_t ID)
{
if (_fd < 0)
doMemoryMapping();
return (uint32_t)_mappedFile + 2;
}
void LinuxPlatform::finishNVMemory()
{
if (_fd < 0)
doMemoryMapping();
fsync(_fd);
}
void LinuxPlatform::freeNVMemory(uint32_t ID)
{
}
#define FLASHSIZE 0x10000
void LinuxPlatform::doMemoryMapping()
{

View File

@ -44,8 +44,12 @@ public:
size_t readBytesUart(uint8_t *buffer, size_t length) override;
//memory
uint8_t* getEepromBuffer(uint16_t size) override;
void commitToEeprom() override;
bool writeNVMemory(uint32_t addr,uint8_t data);
uint8_t readNVMemory(uint32_t addr);
uint32_t allocNVMemory(uint32_t size,uint32_t ID);
uint32_t reloadNVMemory(uint32_t ID);
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);

416
src/samd_flash.cpp Normal file
View File

@ -0,0 +1,416 @@
#include <Arduino.h>
#include "samd_flash.h"
#define VALID (0xDEADC0DE)
extern uint32_t __etext;
extern uint32_t __data_start__;
extern uint32_t __data_end__;
static const uint32_t pageSizes[] = { 8, 16, 32, 64, 128, 256, 512, 1024 };
SamdFlash::SamdFlash(){
_pageSize = pageSizes[NVMCTRL->PARAM.bit.PSZ];
_pageCnt = NVMCTRL->PARAM.bit.NVMP;
_rowSize = PAGES_PER_ROW * _pageSize;
_rowBuffer = new uint8_t[_rowSize];
//find end of program flash and set limit to next row
uint32_t endEddr = (uint32_t)(&__etext + (&__data_end__ - &__data_start__)); //text + data MemoryBlock
_MemoryEnd = getRowAddr(endEddr) + _rowSize-1; //23295
//map info structure to last row in flash
_info = (info_data_t*)getRowAddr(_pageSize*_pageCnt-1); //261888 (rowAddr of last row)
}
uint32_t SamdFlash::getStartAddress(){
return _info->freeMemoryStart;
}
uint8_t SamdFlash::read(uint8_t* addr){
if(_rowBufferModified == false)
return *addr;
if(getRowAddr((uint32_t)addr) != _rowBufferAddr)
return *addr;
//return data from buffer because flash data is not up to date
return _rowBuffer[(uint32_t)addr-_rowBufferAddr];
}
bool SamdFlash::write(uint8_t* addr, uint8_t data){
//Check if the destination address is valid
if ((uint32_t)addr >= (_pageSize * _pageCnt) || (uint32_t)addr <= _MemoryEnd)
return false;
uint32_t newRowAddr = getRowAddr((uint32_t)addr);
//if the row changed, write old Buffer and init new
if(newRowAddr != _rowBufferAddr){
uploadRowBuffer(_rowBufferAddr);
downloadRowBuffer(newRowAddr);
_rowBufferAddr = newRowAddr;
}
_rowBuffer[(uint32_t)addr-_rowBufferAddr] = data;
_rowBufferModified = true;
return true;
}
void SamdFlash::uploadRowBuffer(uint32_t rowAddr){
if(!_rowBufferModified) return;
eraseRow(rowAddr);
//Clear Page Buffer
NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_PBC;
while (NVMCTRL->INTFLAG.bit.READY == 0) {}
// Disable automatic page write
NVMCTRL->CTRLB.bit.MANW = 1;
volatile uint32_t* src_addr = (volatile uint32_t*)_rowBuffer;
volatile uint32_t* dst_addr = (volatile uint32_t *)rowAddr;
for(uint32_t p=0;p<PAGES_PER_ROW;p++){
for (uint32_t i=0; i<(_pageSize/4); i++) {
*dst_addr = *src_addr;
dst_addr++;
src_addr++;
}
// Execute "WP" Write Page
NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_WP;
while (NVMCTRL->INTFLAG.bit.READY == 0) { }
}
}
void SamdFlash::downloadRowBuffer(uint32_t rowAddr){
volatile uint32_t* src_addr = (volatile uint32_t*)rowAddr;
volatile uint32_t* dst_addr = (volatile uint32_t *)_rowBuffer;
for(uint32_t p=0;p<PAGES_PER_ROW;p++){
for (uint32_t i=0; i<(_pageSize/4); i++) {
*dst_addr = *src_addr;
dst_addr++;
src_addr++;
}
}
_rowBufferModified = false;
}
uint32_t SamdFlash::getRowAddr(uint32_t flasAddr){
return flasAddr & ~(_rowSize-1);
}
void SamdFlash::finalise(){
uploadRowBuffer(_rowBufferAddr);
}
void SamdFlash::eraseRow(uint32_t rowAddr){
NVMCTRL->ADDR.reg = rowAddr/2;
NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_ER;
while (!NVMCTRL->INTFLAG.bit.READY) { }
}
void SamdFlash::erase(){
uint32_t rowAddr = getRowAddr((uint32_t)_info);
uint32_t nextrowAddr = getRowAddr(_MemoryEnd);
while(rowAddr != nextrowAddr){
eraseRow(rowAddr);
rowAddr = rowAddr - _rowSize;
}
}
void SamdFlash::erase(uint32_t ID){
block_meta_data_t ramCopy;
block_meta_data_t* block = getBlock(ID);
if(block == NULL)
return;
ramCopy = *block;
uint32_t rowAddr = (uint32_t)block;
uint32_t nextrowAddr = getRowAddr(rowAddr + block->size - 1 +sizeof(block_meta_data_t));
while(rowAddr != nextrowAddr){
eraseRow(nextrowAddr);
nextrowAddr = nextrowAddr - _rowSize;
}
uploadRowBuffer(_rowBufferAddr);
_rowBufferAddr = rowAddr;
downloadRowBuffer(_rowBufferAddr);
//map block meta structure into ram copy
block = (block_meta_data_t*)_rowBuffer;
//copy into row buffer
*block = ramCopy;
_rowBufferModified = true;
uploadRowBuffer(_rowBufferAddr);
}
void SamdFlash::copyAndFree(block_meta_data_t* src, block_meta_data_t* dst){
block_meta_data_t metaDataRamCopy;
block_meta_data_t* tempBlock;
if(src == NULL || dst == NULL)
return;
metaDataRamCopy = *dst;
uint32_t lastRow = getRowAddr((uint32_t)src + src->size -1 + sizeof(block_meta_data_t));
uint32_t srcRow = (uint32_t)src;
uint32_t dstRow = (uint32_t)dst;
while(srcRow <= lastRow){
downloadRowBuffer(srcRow);
//if first row copy meta data too
if(srcRow == (uint32_t)src){
//map block meta structure into ram copy
tempBlock = (block_meta_data_t*)_rowBuffer;
//copy into row buffer
*tempBlock = metaDataRamCopy;
}
_rowBufferModified = true;
uploadRowBuffer(dstRow);
srcRow = srcRow + _rowSize;
dstRow = dstRow + _rowSize;
}
//free src
downloadRowBuffer((uint32_t)src);
//map block meta structure into ram copy
tempBlock = (block_meta_data_t*)_rowBuffer;
tempBlock->ID = 0;
_rowBufferModified = true;
uploadRowBuffer((uint32_t)src);
}
block_meta_data_t* SamdFlash::findEmptyBlock(uint32_t size,uint32_t* compSize, uint32_t* previousBlockAddr){
block_meta_data_t* block = _info->firstBlock;
block_meta_data_t* preblock = NULL;
block_meta_data_t* conblock = NULL;
if(block != NULL && block->validMask == VALID){
do{
if(block->ID == 0){
if(block->size >= size){
*compSize = 0;
return block;
}
//ceck if we can merge next empty blocks
else if(block->next != NULL){
conblock = block->next;
*compSize = block->size;
while(conblock != NULL && conblock->ID == 0){
*compSize += conblock->size + sizeof(block_meta_data_t);
if(*compSize >= size){
*previousBlockAddr = (uint32_t)preblock;
return conblock;
}
conblock = conblock->next;
}
}
//block is last one
else{
*compSize = 0;
*previousBlockAddr = (uint32_t)preblock;
return block;
}
}
preblock = block;
block = block->next;
}while(block != NULL && block->validMask == VALID);
}
return NULL;
}
uint8_t* SamdFlash::loadBlock(uint32_t ID){
block_meta_data_t* block = _info->firstBlock;
if(block == (block_meta_data_t*)0xFFFFFFFF)
return NULL;
if(block != NULL && block->validMask == VALID){
do{
if(block->ID == ID){
return ((uint8_t*)block)+sizeof(block_meta_data_t);
}
block = block->next;
}while(block != NULL && block->validMask == VALID);
}
return NULL;
}
block_meta_data_t* SamdFlash::getBlock(uint32_t ID){
uint8_t* block = loadBlock(ID);
if(block == NULL)
return NULL;
return (block_meta_data_t*)(block-sizeof(block_meta_data_t));
}
block_meta_data_t* SamdFlash::findLastBlock(){
block_meta_data_t* block = _info->firstBlock;
if(block == (block_meta_data_t*)0xFFFFFFFF || block == NULL)
return NULL;
while(block->next != NULL && block->next->validMask == VALID){
block = block->next;
}
return block;
}
void SamdFlash::free(uint32_t ID){
block_meta_data_t* block = getBlock(ID);
if(block != NULL){
//upload actual rowBuffer if necessary
uploadRowBuffer(_rowBufferAddr);
//download block into ram buffer
_rowBufferAddr = (uint32_t)block;
downloadRowBuffer(_rowBufferAddr);
//map block structure into ram copy
block = (block_meta_data_t*)_rowBuffer;
//mark the block as empty and write to flash
block->ID = 0;
_rowBufferModified = true;
uploadRowBuffer(_rowBufferAddr);
}
}
uint8_t* SamdFlash::malloc(uint32_t size, uint32_t ID){
//check if ID is already present
if(loadBlock(ID) != NULL)
return NULL;
return forcemalloc(size, ID);
}
uint8_t* SamdFlash::forcemalloc(uint32_t size, uint32_t ID){
uploadRowBuffer(_rowBufferAddr);
//download actual info row into ram buffer
_rowBufferAddr = (uint32_t)_info; //261888
downloadRowBuffer(_rowBufferAddr);
//map info structure into ram copy
_info = (info_data_t*)_rowBuffer;
//create new info if actual is not valid (all data got lost)
if(_info->validMask != VALID){
_info->validMask = VALID;
_info->freeMemoryStart = getRowAddr(_pageSize*_pageCnt-1)-1; //161887
_info->firstBlock = NULL;
}
//create ram copies for further usage
block_meta_data_t newBlock;
block_meta_data_t previousBlock;
uint32_t newBlockFlashAddr;
uint32_t previousBlockFlashAddr = 0;
block_meta_data_t* tempBlock;
//check if we can use an existing empty block or allocate a new one
uint32_t newSize;
tempBlock = findEmptyBlock(size,&newSize,&previousBlockFlashAddr);
if(tempBlock != NULL){
//copy found block into ram
newBlock = *tempBlock;
newBlockFlashAddr = (uint32_t)tempBlock;
//two ore more empty blocks were connected
if(newSize != 0){
newBlock.size = newSize;
if(previousBlockFlashAddr == 0){
_info->firstBlock = (block_meta_data_t*)newBlockFlashAddr;
}
else{
//copy found block into ram
previousBlock = *((block_meta_data_t*)previousBlockFlashAddr);
previousBlock.next = (block_meta_data_t*)newBlockFlashAddr;
}
}
//newBlock is last one in list an can be extended
if(newBlock.size < size){
if(previousBlockFlashAddr == 0){
newBlockFlashAddr = getRowAddr(getRowAddr(_pageSize*_pageCnt-1) - (size+sizeof(block_meta_data_t)));
newBlock.size = getRowAddr(_pageSize*_pageCnt-1)-newBlockFlashAddr-sizeof(block_meta_data_t); //1008
//update newBlockAddr in list
_info->firstBlock = (block_meta_data_t*)newBlockFlashAddr;
}
else{
newBlockFlashAddr = getRowAddr(previousBlockFlashAddr - (size+sizeof(block_meta_data_t)));
newBlock.size = previousBlockFlashAddr-newBlockFlashAddr-sizeof(block_meta_data_t); //1008
//copy found block into ram and update newBlockAddr in list
previousBlock = *((block_meta_data_t*)previousBlockFlashAddr);
previousBlock.next = (block_meta_data_t*)newBlockFlashAddr;
}
//set MemoryStart to end of new block
_info->freeMemoryStart = newBlockFlashAddr-1; //260863
}
//fill meta data of new block
newBlock.validMask = VALID;
newBlock.ID = ID;
}
else{
//check if size fits into free area
if(_info->freeMemoryStart - (size+sizeof(block_meta_data_t)) <= _MemoryEnd)
return NULL;
//get start address of new block
newBlockFlashAddr = getRowAddr(_info->freeMemoryStart +1 - (size+sizeof(block_meta_data_t))); //260864 (size= 1024-16=1008)
newBlock.size = _info->freeMemoryStart-newBlockFlashAddr+1-sizeof(block_meta_data_t); //1008
newBlock.next = NULL;
//set MemoryStart to end of new block
_info->freeMemoryStart = newBlockFlashAddr-1; //260863
//fill meta data of new block
newBlock.validMask = VALID;
newBlock.ID = ID;
//add block to end of list
tempBlock = findLastBlock();//(block_meta_data_t*)previousBlockFlashAddr;
if(tempBlock == NULL){
_info->firstBlock = (block_meta_data_t*)newBlockFlashAddr;
}
else{
//copy found block into ram
previousBlock = *tempBlock;
previousBlock.next = (block_meta_data_t*)newBlockFlashAddr;
previousBlockFlashAddr = (uint32_t)tempBlock;
}
}
//write modified ram info structure into last flash row
_rowBufferModified = true;
uploadRowBuffer(_rowBufferAddr);
//write modified ram copy of last block meta into flash
if(previousBlockFlashAddr != 0){
_rowBufferAddr = previousBlockFlashAddr;
downloadRowBuffer(_rowBufferAddr);
//map block meta structure into ram copy
tempBlock = (block_meta_data_t*)_rowBuffer;
//copy into row buffer
*tempBlock = previousBlock;
_rowBufferModified = true;
uploadRowBuffer(_rowBufferAddr);
}
//write ram copy of new block meta into flash
_rowBufferAddr = newBlockFlashAddr;
downloadRowBuffer(_rowBufferAddr);
//map block meta structure into ram copy
tempBlock = (block_meta_data_t*)_rowBuffer;
//copy into row buffer
*tempBlock = newBlock;
_rowBufferModified = true;
uploadRowBuffer(_rowBufferAddr);
//config structure now points into updated flash again
_info = (info_data_t*)getRowAddr(_pageSize*_pageCnt-1);
return (uint8_t*)(newBlockFlashAddr+sizeof(block_meta_data_t));
}
uint8_t* SamdFlash::realloc(uint32_t size, uint32_t ID){
uint32_t newBlockFlashAddr;
block_meta_data_t* actualBlock;
actualBlock = getBlock(ID);
//check if ID is presenty
if(actualBlock == NULL)
return malloc(size, ID);
//if size already fits into block, nothing to do otherwise alloc block with new size
if(actualBlock->size >= size)
return loadBlock(ID);
newBlockFlashAddr = (uint32_t)(forcemalloc(size, ID)-sizeof(block_meta_data_t));
copyAndFree(actualBlock, (block_meta_data_t*)newBlockFlashAddr);
return (uint8_t*)(newBlockFlashAddr+sizeof(block_meta_data_t));
}

59
src/samd_flash.h Normal file
View File

@ -0,0 +1,59 @@
#ifndef SAMD_FLASH_H
#define SAMD_FLASH_H
#include <Arduino.h>
#define PAGES_PER_ROW 4
typedef struct block_meta_data{
uint32_t validMask;
uint32_t ID;
uint32_t size;
struct block_meta_data *next;
}__attribute__((__packed__))block_meta_data_t;
typedef struct {
uint32_t validMask;
uint32_t freeMemoryStart;
block_meta_data_t* firstBlock;
}__attribute__((__packed__))info_data_t;
class SamdFlash{
public:
SamdFlash();
void erase();
void erase(uint32_t ID);
void free(uint32_t ID);
uint8_t* malloc(uint32_t size, uint32_t ID);
uint8_t* realloc(uint32_t size, uint32_t ID);
uint8_t* loadBlock(uint32_t ID);
bool write(uint8_t* addr, uint8_t data);
uint8_t read(uint8_t* addr);
void finalise();
uint32_t getStartAddress();
private:
uint8_t* forcemalloc(uint32_t size, uint32_t ID);
void uploadRowBuffer(uint32_t rowAddr);
void downloadRowBuffer(uint32_t rowAddr);
uint32_t getRowAddr(uint32_t flasAddr);
void eraseRow(uint32_t rowAddr);
void copyAndFree(block_meta_data_t* src, block_meta_data_t* dst);
block_meta_data_t* findEmptyBlock(uint32_t size,uint32_t* compSize, uint32_t* nextBlockAddr);
block_meta_data_t* findLastBlock();
block_meta_data_t* getBlock(uint32_t ID);
uint32_t _MemoryEnd=0;
uint32_t _pageSize;
uint32_t _rowSize;
uint32_t _pageCnt;
uint8_t* _rowBuffer;
bool _rowBufferModified = false;
uint32_t _rowBufferAddr;
volatile info_data_t* _info;
};
#endif /* SAMD_FLASH_H */

View File

@ -4,14 +4,18 @@
#include <knx/bits.h>
#include <Arduino.h>
#include <FlashAsEEPROM.h>
#include "samd_flash.h"
SamdFlash Flash;
SamdPlatform::SamdPlatform() : ArduinoPlatform(&Serial1)
{
Platform::_NVMemoryType = internalFlash;
}
SamdPlatform::SamdPlatform( HardwareSerial* s) : ArduinoPlatform(s)
{
Platform::_NVMemoryType = internalFlash;
}
void SamdPlatform::restart()
@ -20,19 +24,121 @@ void SamdPlatform::restart()
NVIC_SystemReset();
}
uint8_t * SamdPlatform::getEepromBuffer(uint16_t size)
bool SamdPlatform::writeNVMemory(uint32_t addr,uint8_t data)
{
//EEPROM.begin(size);
if(size > EEPROM_EMULATION_SIZE)
if(Flash.write((uint8_t*)addr, data)==false)
fatalError();
return EEPROM.getDataPtr();
return true;
}
void SamdPlatform::commitToEeprom()
uint8_t SamdPlatform::readNVMemory(uint32_t addr)
{
return Flash.read((uint8_t*)addr);
}
uint32_t SamdPlatform::allocNVMemory(uint32_t size,uint32_t ID)
{
uint32_t addr = (uint32_t)Flash.malloc(size, ID);
if(addr == 0)
fatalError();
return addr;
}
uint32_t SamdPlatform::reloadNVMemory(uint32_t ID)
{
// Flash.erase();
return (uint32_t)Flash.loadBlock(ID);
}
void SamdPlatform::finishNVMemory()
{
Flash.finalise();
}
void SamdPlatform::freeNVMemory(uint32_t ID)
{
Flash.free(ID);
// Flash.erase();
}
uint8_t* SamdPlatform::memoryReference()
{
return (uint8_t*)Flash.getStartAddress();
}
/*************_NVMemoryType = internalRam*************************
bool SamdPlatform::writeNVMemory(uint32_t addr,uint8_t data)
{
*((uint8_t*)addr) = data;
return true;
}
uint8_t SamdPlatform::readNVMemory(uint32_t addr)
{
return *((uint8_t*)addr);
}
uint32_t SamdPlatform::allocNVMemory(uint32_t size,uint32_t ID)
{
if(size > EEPROM_EMULATION_SIZE)
fatalError();
return (uint32_t)EEPROM.getDataPtr();
}
uint32_t SamdPlatform::reloadNVMemory(uint32_t ID)
{
return (uint32_t)EEPROM.getDataPtr();
}
void SamdPlatform::finishNVMemory()
{
EEPROM.commit();
}
void SamdPlatform::freeNVMemory(uint32_t ID)
{
}
/*
/*************_NVMemoryType = external*************************
bool SamdPlatform::writeNVMemory(uint32_t addr,uint8_t data)
{
EEPROM.write(addr-1, data);
return true;
}
uint8_t SamdPlatform::readNVMemory(uint32_t addr)
{
return EEPROM.read(addr-1);
}
uint32_t SamdPlatform::allocNVMemory(uint32_t size,uint32_t ID)
{
if(size > EEPROM_EMULATION_SIZE)
fatalError();
return 1;
}
uint32_t SamdPlatform::reloadNVMemory(uint32_t ID)
{
return 1;
}
void SamdPlatform::finishNVMemory()
{
EEPROM.commit();
}
void SamdPlatform::freeNVMemory(uint32_t ID)
{
}
*/
#endif

View File

@ -11,8 +11,13 @@ public:
SamdPlatform( HardwareSerial* s);
void restart();
uint8_t* getEepromBuffer(uint16_t size);
void commitToEeprom();
bool writeNVMemory(uint32_t addr,uint8_t data);
uint8_t readNVMemory(uint32_t addr);
uint32_t allocNVMemory(uint32_t size,uint32_t ID);
uint32_t reloadNVMemory(uint32_t ID);
void finishNVMemory();
void freeNVMemory(uint32_t ID);
uint8_t* memoryReference();
};
#endif