mirror of
				https://github.com/thelsing/knx.git
				synced 2025-10-26 10:26:25 +01: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