knx
ETS configurable knx-stack
platform.cpp
Go to the documentation of this file.
1 #include "platform.h"
2 
3 #include "bits.h"
4 
5 #include <cstring>
6 #include <cstdlib>
7 
9 {
10  return _memoryType;
11 }
12 
14 {
15  _memoryType = type;
16 }
17 
19 {}
20 
22 {}
23 
24 int Platform::readWriteSpi(uint8_t* data, size_t len)
25 {
26  return 0;
27 }
28 
29 size_t Platform::readBytesUart(uint8_t* buffer, size_t length)
30 {
31  return 0;
32 }
33 
35 {
36  return -1;
37 }
38 
39 size_t Platform::writeUart(const uint8_t* buffer, size_t size)
40 {
41  return 0;
42 }
43 
44 size_t Platform::writeUart(const uint8_t data)
45 {
46  return 0;
47 }
48 
50 {
51  return 0;
52 }
53 
55 {}
56 
58 {}
59 
61 {
62  return false;
63 }
64 
66 {}
67 
69 {
70  return 0x01020304;
71 }
72 
74 {
75  return 0;
76 }
77 
79 {
80  return 0;
81 }
82 
83 void Platform::macAddress(uint8_t* data)
84 {}
85 
87 {
88  return 0x01020304;
89 }
90 
91 void Platform::setupMultiCast(uint32_t addr, uint16_t port)
92 {}
93 
95 {}
96 
97 bool Platform::sendBytesMultiCast(uint8_t* buffer, uint16_t len)
98 {
99  return false;
100 }
101 
102 bool Platform::sendBytesUniCast(uint32_t addr, uint16_t port, uint8_t* buffer, uint16_t len)
103 {
104  return false;
105 }
106 
107 int Platform::readBytesMultiCast(uint8_t* buffer, uint16_t maxLen)
108 {
109  return 0;
110 }
111 
112 int Platform::readBytesMultiCast(uint8_t* buffer, uint16_t maxLen, uint32_t& src_addr, uint16_t& src_port)
113 {
114  return readBytesMultiCast(buffer, maxLen);
115 }
116 
118 {
119  return 0;
120 }
121 
123 {
124  // align to 32bit as default for Eeprom Emulation plattforms
125  return 4;
126 }
127 
129 {
130  return nullptr;
131 }
132 
134 {
135  return 0;
136 }
137 
138 void Platform::flashErase(uint16_t eraseBlockNum)
139 {}
140 
141 void Platform::flashWritePage(uint16_t pageNumber, uint8_t* data)
142 {}
143 
144 uint8_t* Platform::getEepromBuffer(uint32_t size)
145 {
146  return nullptr;
147 }
148 
150 {}
151 
153 {
154  if (_memoryType == Flash)
155  return userFlashStart();
156 
157 #ifdef KNX_FLASH_CALLBACK
158  else if (_memoryType == Callback)
159  return _callbackFlashRead();
160 
161 #endif
162  else
163  return getEepromBuffer(KNX_FLASH_SIZE);
164 }
165 
167 {
168  if (_memoryType == Flash)
170 
171 #ifdef KNX_FLASH_CALLBACK
172  else if (_memoryType == Callback)
173  return _callbackFlashSize();
174 
175 #endif
176  else
177  return KNX_FLASH_SIZE;
178 }
179 
181 {
182  if (_memoryType == Flash)
183  {
185  {
187 
188  free(_eraseblockBuffer);
189  _eraseblockBuffer = nullptr;
190  _bufferedEraseblockNumber = -1; // does that make sense?
191  }
192  }
193 
194 #ifdef KNX_FLASH_CALLBACK
195  else if (_memoryType == Callback)
196  return _callbackFlashCommit();
197 
198 #endif
199  else
200  {
201  commitToEeprom();
202  }
203 }
204 
205 uint32_t Platform::writeNonVolatileMemory(uint32_t relativeAddress, uint8_t* buffer, size_t size)
206 {
207 #ifdef KNX_LOG_MEM
208  print("Platform::writeNonVolatileMemory relativeAddress ");
209  print(relativeAddress);
210  print(" size ");
211  println(size);
212 #endif
213 
214  if (_memoryType == Flash)
215  {
216  while (size > 0)
217  {
218  loadEraseblockContaining(relativeAddress);
220  uint32_t end = start + (flashEraseBlockSize() * flashPageSize());
221 
222  uint32_t offset = relativeAddress - start;
223  uint32_t length = end - relativeAddress;
224 
225  if (length > size)
226  length = size;
227 
228  memcpy(_eraseblockBuffer + offset, buffer, length);
230 
231  relativeAddress += length;
232  buffer += length;
233  size -= length;
234  }
235 
236  return relativeAddress;
237  }
238 
239 #ifdef KNX_FLASH_CALLBACK
240  else if (_memoryType == Callback)
241  return _callbackFlashWrite(relativeAddress, buffer, size);
242 
243 #endif
244  else
245  {
246  memcpy(getEepromBuffer(KNX_FLASH_SIZE) + relativeAddress, buffer, size);
247  return relativeAddress + size;
248  }
249 }
250 
251 uint32_t Platform::readNonVolatileMemory(uint32_t relativeAddress, uint8_t* buffer, size_t size)
252 {
253 #ifdef KNX_LOG_MEM
254  print("Platform::readNonVolatileMemory relativeAddress ");
255  print(relativeAddress);
256  print(" size ");
257  println(size);
258 #endif
259 
260  if (_memoryType == Flash)
261  {
262  uint32_t offset = 0;
263 
264  while (size > 0)
265  {
266  // bufferd block is "left" of requested memory, read until the end and return
267  if (_bufferedEraseblockNumber < getEraseBlockNumberOf(relativeAddress))
268  {
269  memcpy(buffer + offset, userFlashStart() + relativeAddress, size);
270  return relativeAddress + size;
271  }
272  // bufferd block is "right" of requested memory, and may interfere
273  else if (_bufferedEraseblockNumber > getEraseBlockNumberOf(relativeAddress))
274  {
275  // if the end of the requested memory is before the buffered block, read until the end and return
276  int32_t eraseblockNumberEnd = getEraseBlockNumberOf(relativeAddress + size - 1);
277 
278  if (_bufferedEraseblockNumber > eraseblockNumberEnd)
279  {
280  memcpy(buffer + offset, userFlashStart() + relativeAddress, size);
281  return relativeAddress + size;
282  }
283  // if not, read until the buffered block starts and loop through while again
284  else
285  {
286  uint32_t sizeToRead = (eraseblockNumberEnd * flashEraseBlockSize()) - relativeAddress;
287  memcpy(buffer + offset, userFlashStart() + relativeAddress, sizeToRead);
288  relativeAddress += sizeToRead;
289  size -= sizeToRead;
290  offset += sizeToRead;
291  }
292  }
293  // start of requested memory is within the buffered erase block
294  else
295  {
296  // if the end of the requested memory is also in the buffered block, read until the end and return
297  int32_t eraseblockNumberEnd = getEraseBlockNumberOf(relativeAddress + size - 1);
298 
299  if (_bufferedEraseblockNumber == eraseblockNumberEnd)
300  {
301  uint8_t* start = _eraseblockBuffer + (relativeAddress - _bufferedEraseblockNumber * flashEraseBlockSize());
302  memcpy(buffer + offset, start, size);
303  return relativeAddress + size;
304  }
305  // if not, read until the end of the buffered block and loop through while again
306  else
307  {
308  uint32_t offsetInBufferedBlock = relativeAddress - _bufferedEraseblockNumber * flashEraseBlockSize();
309  uint8_t* start = _eraseblockBuffer + offsetInBufferedBlock;
310  uint32_t sizeToRead = flashEraseBlockSize() - offsetInBufferedBlock;
311  memcpy(buffer + offset, start, sizeToRead);
312  relativeAddress += sizeToRead;
313  size -= sizeToRead;
314  offset += sizeToRead;
315  }
316  }
317  }
318 
319  return relativeAddress;
320  }
321  else
322  {
323  memcpy(buffer, getEepromBuffer(KNX_FLASH_SIZE) + relativeAddress, size);
324  return relativeAddress + size;
325  }
326 }
327 
328 // writes value repeat times into flash starting at relativeAddress
329 // returns next free relativeAddress
330 uint32_t Platform::writeNonVolatileMemory(uint32_t relativeAddress, uint8_t value, size_t repeat)
331 {
332  if (_memoryType == Flash)
333  {
334  while (repeat > 0)
335  {
336  loadEraseblockContaining(relativeAddress);
338  uint32_t end = start + (flashEraseBlockSize() * flashPageSize());
339 
340  uint32_t offset = relativeAddress - start;
341  uint32_t length = end - relativeAddress;
342 
343  if (length > repeat)
344  length = repeat;
345 
346  memset(_eraseblockBuffer + offset, value, length);
348 
349  relativeAddress += length;
350  repeat -= length;
351  }
352 
353  return relativeAddress;
354  }
355  else
356  {
357  memset(getEepromBuffer(KNX_FLASH_SIZE) + relativeAddress, value, repeat);
358  return relativeAddress + repeat;
359  }
360 }
361 
362 void Platform::loadEraseblockContaining(uint32_t relativeAddress)
363 {
364  int32_t blockNum = getEraseBlockNumberOf(relativeAddress);
365 
366  if (blockNum < 0)
367  {
368  println("loadEraseblockContaining could not get valid eraseblock number");
369  fatalError();
370  }
371 
374 
375  bufferEraseBlock(blockNum);
376 }
377 
378 int32_t Platform::getEraseBlockNumberOf(uint32_t relativeAddress)
379 {
380  return relativeAddress / (flashEraseBlockSize() * flashPageSize());
381 }
382 
383 
385 {
387  {
389 
390  for (uint32_t i = 0; i < flashEraseBlockSize(); i++)
391  {
392  int32_t pageNumber = _bufferedEraseblockNumber * flashEraseBlockSize() + i;
393  uint8_t* data = _eraseblockBuffer + flashPageSize() * i;
394  flashWritePage(pageNumber, data);
395  }
396 
397  _bufferedEraseblockDirty = false;
398  }
399 }
400 
401 
402 void Platform::bufferEraseBlock(int32_t eraseBlockNumber)
403 {
404  if (_bufferedEraseblockNumber == eraseBlockNumber)
405  return;
406 
407  if (_eraseblockBuffer == nullptr)
408  {
409  _eraseblockBuffer = (uint8_t*)malloc(flashEraseBlockSize() * flashPageSize());
410  }
411 
413 
414  _bufferedEraseblockNumber = eraseBlockNumber;
415  _bufferedEraseblockDirty = false;
416 }
417 
418 
419 #ifdef KNX_FLASH_CALLBACK
421  FlashCallbackSize callbackFlashSize,
422  FlashCallbackRead callbackFlashRead,
423  FlashCallbackWrite callbackFlashWrite,
424  FlashCallbackCommit callbackFlashCommit)
425 {
426  println("Set Callback");
433 }
434 
436 {
437  return _callbackFlashSize;
438 }
440 {
441  return _callbackFlashRead;
442 }
444 {
445  return _callbackFlashWrite;
446 }
448 {
449  return _callbackFlashCommit;
450 }
451 #endif
void print(const char *s)
void println(const char *s)
virtual uint8_t * getEepromBuffer(uint32_t size)
Definition: platform.cpp:144
int32_t getEraseBlockNumberOf(uint32_t relativeAddress)
Definition: platform.cpp:378
virtual void writeBufferedEraseBlock()
Definition: platform.cpp:384
virtual uint32_t currentIpAddress()
Definition: platform.cpp:68
virtual void flashErase(uint16_t eraseBlockNum)
Definition: platform.cpp:138
uint8_t * _eraseblockBuffer
Definition: platform.h:142
virtual bool sendBytesMultiCast(uint8_t *buffer, uint16_t len)
Definition: platform.cpp:97
NvMemoryType _memoryType
Definition: platform.h:130
void registerFlashCallbacks(FlashCallbackSize callbackFlashSize, FlashCallbackRead callbackFlashRead, FlashCallbackWrite callbackFlashWrite, FlashCallbackCommit callbackFlashCommit)
Definition: platform.cpp:420
virtual uint32_t currentSubnetMask()
Definition: platform.cpp:73
virtual void closeMultiCast()
Definition: platform.cpp:94
virtual void setupMultiCast(uint32_t addr, uint16_t port)
Definition: platform.cpp:91
virtual void fatalError()=0
virtual uint8_t * getNonVolatileMemoryStart()
Definition: platform.cpp:152
FlashCallbackCommit callbackFlashCommit()
Definition: platform.cpp:447
virtual int readWriteSpi(uint8_t *data, size_t len)
Definition: platform.cpp:24
virtual void flushUart()
Definition: platform.cpp:65
FlashCallbackSize callbackFlashSize()
Definition: platform.cpp:435
FlashCallbackSize _callbackFlashSize
Definition: platform.h:147
void loadEraseblockContaining(uint32_t relativeAddress)
Definition: platform.cpp:362
virtual uint32_t writeNonVolatileMemory(uint32_t relativeAddress, uint8_t *buffer, size_t size)
Definition: platform.cpp:205
void bufferEraseBlock(int32_t eraseBlockNumber)
Definition: platform.cpp:402
virtual void setupSpi()
Definition: platform.cpp:18
virtual uint32_t currentDefaultGateway()
Definition: platform.cpp:78
virtual void closeUart()
Definition: platform.cpp:54
virtual int readUart()
Definition: platform.cpp:34
virtual int uartAvailable()
Definition: platform.cpp:49
NvMemoryType NonVolatileMemoryType()
Definition: platform.cpp:8
virtual size_t flashEraseBlockSize()
Definition: platform.cpp:117
FlashCallbackRead callbackFlashRead()
Definition: platform.cpp:439
virtual size_t writeUart(const uint8_t data)
Definition: platform.cpp:44
virtual void commitToEeprom()
Definition: platform.cpp:149
virtual void flashWritePage(uint16_t pageNumber, uint8_t *data)
Definition: platform.cpp:141
FlashCallbackWrite _callbackFlashWrite
Definition: platform.h:149
FlashCallbackCommit _callbackFlashCommit
Definition: platform.h:150
int32_t _bufferedEraseblockNumber
Definition: platform.h:143
virtual size_t userFlashSizeEraseBlocks()
Definition: platform.cpp:133
virtual void setupUart()
Definition: platform.cpp:57
FlashCallbackWrite callbackFlashWrite()
Definition: platform.cpp:443
virtual void macAddress(uint8_t *data)
Definition: platform.cpp:83
virtual size_t flashPageSize()
Definition: platform.cpp:122
virtual bool overflowUart()
Definition: platform.cpp:60
virtual bool sendBytesUniCast(uint32_t addr, uint16_t port, uint8_t *buffer, uint16_t len)
Definition: platform.cpp:102
virtual size_t getNonVolatileMemorySize()
Definition: platform.cpp:166
virtual void commitNonVolatileMemory()
Definition: platform.cpp:180
bool _bufferedEraseblockDirty
Definition: platform.h:144
virtual uint32_t readNonVolatileMemory(uint32_t relativeAddress, uint8_t *buffer, size_t size)
Definition: platform.cpp:251
virtual void closeSpi()
Definition: platform.cpp:21
virtual size_t readBytesUart(uint8_t *buffer, size_t length)
Definition: platform.cpp:29
virtual uint8_t * userFlashStart()
Definition: platform.cpp:128
virtual uint32_t uniqueSerialNumber()
Definition: platform.cpp:86
FlashCallbackRead _callbackFlashRead
Definition: platform.h:148
virtual int readBytesMultiCast(uint8_t *buffer, uint16_t maxLen)
Definition: platform.cpp:107
void(* FlashCallbackCommit)()
Definition: platform.h:21
uint32_t(* FlashCallbackSize)()
Definition: platform.h:18
uint32_t(* FlashCallbackWrite)(uint32_t relativeAddress, uint8_t *buffer, size_t len)
Definition: platform.h:20
NvMemoryType
Definition: platform.h:25
@ Callback
Definition: platform.h:28
@ Flash
Definition: platform.h:27
uint8_t *(* FlashCallbackRead)()
Definition: platform.h:19