NVProperty generic key value store using the MCU flash area.

Dependents:   Turtle_RadioShuttle

Committer:
Helmut Tschemernjak
Date:
Mon Apr 22 12:29:12 2019 +0200
Revision:
16:24a9d3ecee7b
Parent:
14:96400e56a1ad
Added NTP to the editor

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Helmut Tschemernjak 4:eb6850e3bc21 1 /*
Helmut Tschemernjak 4:eb6850e3bc21 2 * This is an unpublished work copyright
Helmut Tschemernjak 4:eb6850e3bc21 3 * (c) 2019 Helmut Tschemernjak
Helmut Tschemernjak 4:eb6850e3bc21 4 * 30826 Garbsen (Hannover) Germany
Helmut Tschemernjak 4:eb6850e3bc21 5 *
Helmut Tschemernjak 4:eb6850e3bc21 6 *
Helmut Tschemernjak 4:eb6850e3bc21 7 * Use is granted to registered RadioShuttle licensees only.
Helmut Tschemernjak 4:eb6850e3bc21 8 * Licensees must own a valid serial number and product code.
Helmut Tschemernjak 4:eb6850e3bc21 9 * Details see: www.radioshuttle.de
Helmut Tschemernjak 4:eb6850e3bc21 10 */
Helmut Tschemernjak 4:eb6850e3bc21 11
Helmut Tschemernjak 4:eb6850e3bc21 12 #ifdef __MBED__
Helmut Tschemernjak 4:eb6850e3bc21 13
Helmut Tschemernjak 4:eb6850e3bc21 14 #include <mbed.h>
Helmut Tschemernjak 4:eb6850e3bc21 15 #include "main.h"
Helmut Tschemernjak 4:eb6850e3bc21 16 #include "arch.h"
Helmut Tschemernjak 4:eb6850e3bc21 17 #include <algorithm>
Helmut Tschemernjak 4:eb6850e3bc21 18 #include <NVPropertyProviderInterface.h>
Helmut Tschemernjak 4:eb6850e3bc21 19 #include <NVProperty_MBEDFlash.h>
Helmut Tschemernjak 4:eb6850e3bc21 20 #include <NVProperty.h>
Helmut Tschemernjak 4:eb6850e3bc21 21
Helmut Tschemernjak 4:eb6850e3bc21 22
Helmut Tschemernjak 5:2560e615ccd5 23 #if 0 // sample test code for a main app.
Helmut Tschemernjak 4:eb6850e3bc21 24 {
Helmut Tschemernjak 5:2560e615ccd5 25 NVProperty p;
Helmut Tschemernjak 5:2560e615ccd5 26 p.OpenPropertyStore(true);
Helmut Tschemernjak 5:2560e615ccd5 27
Helmut Tschemernjak 5:2560e615ccd5 28 dprintf("LORA_REMOTE_ID: %d", p.GetProperty(p.LORA_REMOTE_ID, 0));
Helmut Tschemernjak 5:2560e615ccd5 29 p.SetProperty(p.LORA_REMOTE_ID, p.T_32BIT, 123);
Helmut Tschemernjak 5:2560e615ccd5 30 dprintf("LORA_REMOTE_ID: %d", p.GetProperty(p.LORA_REMOTE_ID, 0));
Helmut Tschemernjak 5:2560e615ccd5 31 dprintf("Host: %s", p.GetProperty(p.HOSTNAME, "MyHost"));
Helmut Tschemernjak 5:2560e615ccd5 32 p.SetProperty(p.HOSTNAME, p.T_STR, "Wunstorf", p.S_FLASH);
Helmut Tschemernjak 5:2560e615ccd5 33 dprintf("Host: %s", p.GetProperty(p.HOSTNAME, "MyHost"));
Helmut Tschemernjak 5:2560e615ccd5 34 p.SetProperty(p.LORA_REMOTE_ID, p.T_32BIT, 456);
Helmut Tschemernjak 5:2560e615ccd5 35 dprintf("LORA_REMOTE_ID: %d", p.GetProperty(p.LORA_REMOTE_ID, 0));
Helmut Tschemernjak 5:2560e615ccd5 36 dprintf("Host: %s", p.GetProperty(p.HOSTNAME, "MyHost"));
Helmut Tschemernjak 4:eb6850e3bc21 37 }
Helmut Tschemernjak 4:eb6850e3bc21 38 #endif
Helmut Tschemernjak 4:eb6850e3bc21 39
Helmut Tschemernjak 4:eb6850e3bc21 40
Helmut Tschemernjak 4:eb6850e3bc21 41
Helmut Tschemernjak 4:eb6850e3bc21 42 NVProperty_MBEDFlash::NVProperty_MBEDFlash(int propSizekB, bool erase)
Helmut Tschemernjak 4:eb6850e3bc21 43 {
Helmut Tschemernjak 4:eb6850e3bc21 44 _flashIAP = new FlashIAP();
Helmut Tschemernjak 4:eb6850e3bc21 45 _flashIAP->init();
Helmut Tschemernjak 4:eb6850e3bc21 46
Helmut Tschemernjak 5:2560e615ccd5 47 // a min page size > 8 looks strange
Helmut Tschemernjak 5:2560e615ccd5 48 MBED_ASSERT(_flashIAP->get_page_size() <= sizeof(int64_t));
Helmut Tschemernjak 5:2560e615ccd5 49
Helmut Tschemernjak 5:2560e615ccd5 50
Helmut Tschemernjak 4:eb6850e3bc21 51 _debug = false;
Helmut Tschemernjak 4:eb6850e3bc21 52 _propSizekB = propSizekB;
Helmut Tschemernjak 4:eb6850e3bc21 53 _pageSize = _flashIAP->get_page_size();
Helmut Tschemernjak 4:eb6850e3bc21 54 _numPages = _flashIAP->get_flash_size() / _pageSize;
Helmut Tschemernjak 14:96400e56a1ad 55 _rowSize = _flashIAP->get_sector_size(_flashIAP->get_flash_start());
Helmut Tschemernjak 14:96400e56a1ad 56 MBED_ASSERT(((propSizekB *1024) % _rowSize) == 0);
Helmut Tschemernjak 4:eb6850e3bc21 57 _startAddress = (uint8_t*)_flashIAP->get_flash_start() + ((_numPages-(_propSizekB * 1024)/_pageSize) * _pageSize);
Helmut Tschemernjak 4:eb6850e3bc21 58 _endAddress = _startAddress + (_propSizekB * 1024);
Helmut Tschemernjak 13:2436a800c0fa 59 // _flashErasedValue = _flashIAP->get_erase_value();
Helmut Tschemernjak 13:2436a800c0fa 60 _flashErasedValue = 0xff; // until the new mbed flashIAP->get_erase_value() is available
Helmut Tschemernjak 13:2436a800c0fa 61 #ifdef TARGET_STM32L0
Helmut Tschemernjak 13:2436a800c0fa 62 _flashErasedValue = 0x00;
Helmut Tschemernjak 13:2436a800c0fa 63 #endif
Helmut Tschemernjak 4:eb6850e3bc21 64 _lastEntry = NULL;
Helmut Tschemernjak 4:eb6850e3bc21 65
Helmut Tschemernjak 4:eb6850e3bc21 66 if (_debug) {
Helmut Tschemernjak 4:eb6850e3bc21 67 dprintf("_propSizekB: %d kB", _propSizekB);
Helmut Tschemernjak 4:eb6850e3bc21 68 dprintf("_pageSize: %d", _pageSize);
Helmut Tschemernjak 4:eb6850e3bc21 69 dprintf("_numPages: %d", _numPages);
Helmut Tschemernjak 4:eb6850e3bc21 70 dprintf("_rowSize: %d", _rowSize);
Helmut Tschemernjak 4:eb6850e3bc21 71 dprintf("PageOffset: %d", _numPages-((_propSizekB * 1024)/_pageSize));
Helmut Tschemernjak 4:eb6850e3bc21 72 dprintf("total: %d", _pageSize * _numPages);
Helmut Tschemernjak 4:eb6850e3bc21 73 dprintf("_startAddress: %d", (int)_startAddress);
Helmut Tschemernjak 4:eb6850e3bc21 74 }
Helmut Tschemernjak 4:eb6850e3bc21 75
Helmut Tschemernjak 4:eb6850e3bc21 76 _FlashInititalize(erase);
Helmut Tschemernjak 8:b42bb4130002 77 _GetFlashEntry(0); // inits the _lastEntry record
Helmut Tschemernjak 4:eb6850e3bc21 78 }
Helmut Tschemernjak 4:eb6850e3bc21 79
Helmut Tschemernjak 4:eb6850e3bc21 80
Helmut Tschemernjak 4:eb6850e3bc21 81 NVProperty_MBEDFlash::~NVProperty_MBEDFlash()
Helmut Tschemernjak 4:eb6850e3bc21 82 {
Helmut Tschemernjak 4:eb6850e3bc21 83 _flashIAP->deinit();
Helmut Tschemernjak 4:eb6850e3bc21 84 delete _flashIAP;
Helmut Tschemernjak 5:2560e615ccd5 85 #if 0
Helmut Tschemernjak 4:eb6850e3bc21 86 _debug = true;
Helmut Tschemernjak 4:eb6850e3bc21 87 wait_ms(100);
Helmut Tschemernjak 4:eb6850e3bc21 88 _DumpAllEntires();
Helmut Tschemernjak 4:eb6850e3bc21 89 wait_ms(100);
Helmut Tschemernjak 5:2560e615ccd5 90 dump("buffer: ", _startAddress, 100);
Helmut Tschemernjak 5:2560e615ccd5 91 wait_ms(100);
Helmut Tschemernjak 5:2560e615ccd5 92 #endif
Helmut Tschemernjak 4:eb6850e3bc21 93 }
Helmut Tschemernjak 4:eb6850e3bc21 94
Helmut Tschemernjak 4:eb6850e3bc21 95
Helmut Tschemernjak 4:eb6850e3bc21 96 void
Helmut Tschemernjak 4:eb6850e3bc21 97 NVProperty_MBEDFlash::_FlashInititalize(bool force)
Helmut Tschemernjak 4:eb6850e3bc21 98 {
Helmut Tschemernjak 4:eb6850e3bc21 99 _flash_header *fh = (_flash_header *)_startAddress;
Helmut Tschemernjak 4:eb6850e3bc21 100 if (fh->magic == FLASH_PROP_MAGIC && fh->version == FLASH_PROP_VERSION && fh->sizeKB == _propSizekB) {
Helmut Tschemernjak 4:eb6850e3bc21 101 if (_debug)
Helmut Tschemernjak 4:eb6850e3bc21 102 dprintf("Flash OK");
Helmut Tschemernjak 4:eb6850e3bc21 103 if (!force)
Helmut Tschemernjak 4:eb6850e3bc21 104 return;
Helmut Tschemernjak 4:eb6850e3bc21 105 }
Helmut Tschemernjak 4:eb6850e3bc21 106
Helmut Tschemernjak 4:eb6850e3bc21 107 if (_debug)
Helmut Tschemernjak 4:eb6850e3bc21 108 dprintf("Formatting Flash");
Helmut Tschemernjak 4:eb6850e3bc21 109
Helmut Tschemernjak 4:eb6850e3bc21 110 _flash_header f;
Helmut Tschemernjak 4:eb6850e3bc21 111 memset(&f, 0, sizeof(f));
Helmut Tschemernjak 4:eb6850e3bc21 112 f.magic = FLASH_PROP_MAGIC;
Helmut Tschemernjak 4:eb6850e3bc21 113 f.version = FLASH_PROP_VERSION;
Helmut Tschemernjak 4:eb6850e3bc21 114 f.sizeKB = _propSizekB;
Helmut Tschemernjak 4:eb6850e3bc21 115
Helmut Tschemernjak 4:eb6850e3bc21 116 int count = (_propSizekB * 1024) / _rowSize;
Helmut Tschemernjak 4:eb6850e3bc21 117 int startRow = (int)_startAddress / _rowSize;
Helmut Tschemernjak 4:eb6850e3bc21 118 _FlashEraseRow(startRow, count);
Helmut Tschemernjak 4:eb6850e3bc21 119 _FlashWrite(_startAddress, &f, sizeof(f));
Helmut Tschemernjak 4:eb6850e3bc21 120 }
Helmut Tschemernjak 4:eb6850e3bc21 121
Helmut Tschemernjak 4:eb6850e3bc21 122
Helmut Tschemernjak 4:eb6850e3bc21 123 void
Helmut Tschemernjak 4:eb6850e3bc21 124 NVProperty_MBEDFlash::_FlashEraseRow(int startRow, int count)
Helmut Tschemernjak 4:eb6850e3bc21 125 {
Helmut Tschemernjak 4:eb6850e3bc21 126 // dprintf("_FlashEraseRow: startRow=%d, count=%d", startRow, count);
Helmut Tschemernjak 4:eb6850e3bc21 127
Helmut Tschemernjak 4:eb6850e3bc21 128 for(int i = 0; i < count; i++) {
Helmut Tschemernjak 4:eb6850e3bc21 129 uint32_t *startAddr = (uint32_t *)((startRow + i) * _rowSize);
Helmut Tschemernjak 4:eb6850e3bc21 130 uint32_t *addr = startAddr;
Helmut Tschemernjak 4:eb6850e3bc21 131 bool foundData = false;
Helmut Tschemernjak 12:5539cdc8be4b 132 uint32_t emtpyValue = _flashErasedValue << 24 | _flashErasedValue << 16 | _flashErasedValue << 8 | _flashErasedValue;
Helmut Tschemernjak 4:eb6850e3bc21 133 for (int offset = 0; offset < _rowSize; offset += sizeof(uint32_t)) {
Helmut Tschemernjak 12:5539cdc8be4b 134 if (*addr++ != emtpyValue) {
Helmut Tschemernjak 4:eb6850e3bc21 135 foundData = true;
Helmut Tschemernjak 4:eb6850e3bc21 136 break;
Helmut Tschemernjak 4:eb6850e3bc21 137 }
Helmut Tschemernjak 4:eb6850e3bc21 138 }
Helmut Tschemernjak 4:eb6850e3bc21 139 if (_debug)
Helmut Tschemernjak 4:eb6850e3bc21 140 dprintf("_FlashEraseRow: addr=0x%x, count=%d (%s)", (unsigned int)startAddr, i,
Helmut Tschemernjak 4:eb6850e3bc21 141 foundData ? "erased" : "skipped");
Helmut Tschemernjak 4:eb6850e3bc21 142 if (!foundData)
Helmut Tschemernjak 4:eb6850e3bc21 143 continue;
Helmut Tschemernjak 4:eb6850e3bc21 144
Helmut Tschemernjak 4:eb6850e3bc21 145 _flashIAP->erase((startRow + i) * _rowSize, _rowSize);
Helmut Tschemernjak 4:eb6850e3bc21 146 }
Helmut Tschemernjak 4:eb6850e3bc21 147 }
Helmut Tschemernjak 4:eb6850e3bc21 148
Helmut Tschemernjak 4:eb6850e3bc21 149
Helmut Tschemernjak 4:eb6850e3bc21 150 /*
Helmut Tschemernjak 4:eb6850e3bc21 151 * Find out start page, number of pages
Helmut Tschemernjak 4:eb6850e3bc21 152 * Check if the page contins FF's than write, otherwise erase first
Helmut Tschemernjak 4:eb6850e3bc21 153 */
Helmut Tschemernjak 4:eb6850e3bc21 154 void
Helmut Tschemernjak 4:eb6850e3bc21 155 NVProperty_MBEDFlash::_FlashWrite(uint8_t *address, const void *d, size_t length)
Helmut Tschemernjak 4:eb6850e3bc21 156 {
Helmut Tschemernjak 4:eb6850e3bc21 157 uint8_t *data = (uint8_t *)d;
Helmut Tschemernjak 4:eb6850e3bc21 158
Helmut Tschemernjak 4:eb6850e3bc21 159 if (address < _startAddress || address > _startAddress + (_pageSize * _numPages))
Helmut Tschemernjak 4:eb6850e3bc21 160 return;
Helmut Tschemernjak 4:eb6850e3bc21 161
Helmut Tschemernjak 4:eb6850e3bc21 162 int done = 0;
Helmut Tschemernjak 4:eb6850e3bc21 163
Helmut Tschemernjak 4:eb6850e3bc21 164 do {
Helmut Tschemernjak 4:eb6850e3bc21 165 uint32_t startPage = (uint32_t)(address + done) / _pageSize;
Helmut Tschemernjak 4:eb6850e3bc21 166 int pageOffset = (uint32_t)(address + done) % _pageSize;
Helmut Tschemernjak 4:eb6850e3bc21 167 int pageWriteSize = _pageSize - pageOffset;
Helmut Tschemernjak 4:eb6850e3bc21 168
Helmut Tschemernjak 4:eb6850e3bc21 169 if (_FlashIsCleared((uint8_t *)(startPage * _pageSize) + pageOffset, pageWriteSize)) {
Helmut Tschemernjak 4:eb6850e3bc21 170 // single page write
Helmut Tschemernjak 4:eb6850e3bc21 171 int writeLength = std::min(pageWriteSize, (int)length);
Helmut Tschemernjak 4:eb6850e3bc21 172 _FlashWritePage(startPage, pageOffset, data, writeLength);
Helmut Tschemernjak 4:eb6850e3bc21 173 length -= writeLength;
Helmut Tschemernjak 4:eb6850e3bc21 174 done += writeLength;
Helmut Tschemernjak 4:eb6850e3bc21 175 data += writeLength;
Helmut Tschemernjak 4:eb6850e3bc21 176 } else {
Helmut Tschemernjak 4:eb6850e3bc21 177 // row write
Helmut Tschemernjak 4:eb6850e3bc21 178 // load row copy
Helmut Tschemernjak 4:eb6850e3bc21 179 // erase row
Helmut Tschemernjak 4:eb6850e3bc21 180 // merge in new data
Helmut Tschemernjak 4:eb6850e3bc21 181 // write row in page copies
Helmut Tschemernjak 4:eb6850e3bc21 182 uint32_t startRow = (uint32_t)(address + done) / _rowSize;
Helmut Tschemernjak 4:eb6850e3bc21 183 int rowOffset = (uint32_t)(address + done) - (startRow * _rowSize);
Helmut Tschemernjak 4:eb6850e3bc21 184 int cplen = std::min((int)length, _rowSize - rowOffset);
Helmut Tschemernjak 4:eb6850e3bc21 185 uint8_t *saveddata = new uint8_t[_rowSize];
Helmut Tschemernjak 4:eb6850e3bc21 186 if (!saveddata)
Helmut Tschemernjak 4:eb6850e3bc21 187 return;
Helmut Tschemernjak 4:eb6850e3bc21 188
Helmut Tschemernjak 4:eb6850e3bc21 189 memcpy(saveddata, (uint8_t *)(startRow * _rowSize), _rowSize);
Helmut Tschemernjak 4:eb6850e3bc21 190 // dprintf("startRow=%d rowOffset=%d, cplen=%d", startRow, rowOffset, cplen);
Helmut Tschemernjak 4:eb6850e3bc21 191
Helmut Tschemernjak 4:eb6850e3bc21 192 memcpy(saveddata + rowOffset, data, cplen);
Helmut Tschemernjak 4:eb6850e3bc21 193
Helmut Tschemernjak 4:eb6850e3bc21 194 _FlashEraseRow(startRow);
Helmut Tschemernjak 4:eb6850e3bc21 195 for (int i = 0; i < _rowSize/_pageSize; i++) {
Helmut Tschemernjak 4:eb6850e3bc21 196 _FlashWritePage(((startRow * _rowSize) / _pageSize) + i, 0, saveddata + (i * _pageSize), _pageSize);
Helmut Tschemernjak 4:eb6850e3bc21 197 }
Helmut Tschemernjak 4:eb6850e3bc21 198 length -= cplen;
Helmut Tschemernjak 4:eb6850e3bc21 199 done += cplen;
Helmut Tschemernjak 4:eb6850e3bc21 200 data += cplen;
Helmut Tschemernjak 4:eb6850e3bc21 201
Helmut Tschemernjak 4:eb6850e3bc21 202 delete[] saveddata;
Helmut Tschemernjak 4:eb6850e3bc21 203 }
Helmut Tschemernjak 4:eb6850e3bc21 204 } while(length > 0);
Helmut Tschemernjak 4:eb6850e3bc21 205 }
Helmut Tschemernjak 4:eb6850e3bc21 206
Helmut Tschemernjak 4:eb6850e3bc21 207
Helmut Tschemernjak 4:eb6850e3bc21 208 bool
Helmut Tschemernjak 4:eb6850e3bc21 209 NVProperty_MBEDFlash::_FlashIsCleared(uint8_t *address, int len)
Helmut Tschemernjak 4:eb6850e3bc21 210 {
Helmut Tschemernjak 5:2560e615ccd5 211 while (len-- > 0) {
Helmut Tschemernjak 12:5539cdc8be4b 212 if (*address++ != _flashErasedValue) {
Helmut Tschemernjak 4:eb6850e3bc21 213 return false;
Helmut Tschemernjak 4:eb6850e3bc21 214 }
Helmut Tschemernjak 4:eb6850e3bc21 215 }
Helmut Tschemernjak 4:eb6850e3bc21 216 return true;
Helmut Tschemernjak 4:eb6850e3bc21 217 }
Helmut Tschemernjak 4:eb6850e3bc21 218
Helmut Tschemernjak 4:eb6850e3bc21 219
Helmut Tschemernjak 4:eb6850e3bc21 220 void
Helmut Tschemernjak 4:eb6850e3bc21 221 NVProperty_MBEDFlash::_FlashWritePage(int page, int offset, uint8_t *data, int length)
Helmut Tschemernjak 4:eb6850e3bc21 222 {
Helmut Tschemernjak 4:eb6850e3bc21 223 uint8_t *addr = (uint8_t *)(page * _pageSize) + offset;
Helmut Tschemernjak 4:eb6850e3bc21 224 if (length < 1)
Helmut Tschemernjak 4:eb6850e3bc21 225 return;
Helmut Tschemernjak 4:eb6850e3bc21 226
Helmut Tschemernjak 4:eb6850e3bc21 227 _flashIAP->program(data, (uint32_t)addr, length);
Helmut Tschemernjak 4:eb6850e3bc21 228 }
Helmut Tschemernjak 4:eb6850e3bc21 229
Helmut Tschemernjak 4:eb6850e3bc21 230
Helmut Tschemernjak 4:eb6850e3bc21 231
Helmut Tschemernjak 4:eb6850e3bc21 232 int
Helmut Tschemernjak 4:eb6850e3bc21 233 NVProperty_MBEDFlash::GetProperty(int key)
Helmut Tschemernjak 4:eb6850e3bc21 234 {
Helmut Tschemernjak 4:eb6850e3bc21 235 return GetProperty64(key);
Helmut Tschemernjak 4:eb6850e3bc21 236 }
Helmut Tschemernjak 4:eb6850e3bc21 237
Helmut Tschemernjak 4:eb6850e3bc21 238
Helmut Tschemernjak 4:eb6850e3bc21 239 int64_t
Helmut Tschemernjak 4:eb6850e3bc21 240 NVProperty_MBEDFlash::GetProperty64(int key)
Helmut Tschemernjak 4:eb6850e3bc21 241 {
Helmut Tschemernjak 4:eb6850e3bc21 242 _flashEntry *p = _GetFlashEntry(key);
Helmut Tschemernjak 4:eb6850e3bc21 243 if (!p)
Helmut Tschemernjak 4:eb6850e3bc21 244 return NVProperty::NVP_ENOENT;
Helmut Tschemernjak 4:eb6850e3bc21 245
Helmut Tschemernjak 4:eb6850e3bc21 246 int64_t value = 0;
Helmut Tschemernjak 4:eb6850e3bc21 247
Helmut Tschemernjak 4:eb6850e3bc21 248 switch(p->t.type) {
Helmut Tschemernjak 4:eb6850e3bc21 249 case NVProperty::T_BIT:
Helmut Tschemernjak 4:eb6850e3bc21 250 if (p->t.t_bit)
Helmut Tschemernjak 4:eb6850e3bc21 251 value = 1;
Helmut Tschemernjak 4:eb6850e3bc21 252 else
Helmut Tschemernjak 4:eb6850e3bc21 253 value = 0;
Helmut Tschemernjak 4:eb6850e3bc21 254 break;
Helmut Tschemernjak 4:eb6850e3bc21 255 case NVProperty::T_8BIT:
Helmut Tschemernjak 4:eb6850e3bc21 256 value = p->u.v_8bit;
Helmut Tschemernjak 4:eb6850e3bc21 257 break;
Helmut Tschemernjak 4:eb6850e3bc21 258 case NVProperty::T_16BIT:
Helmut Tschemernjak 4:eb6850e3bc21 259 {
Helmut Tschemernjak 4:eb6850e3bc21 260 int16_t v;
Helmut Tschemernjak 4:eb6850e3bc21 261 memcpy(&v, &p->u.v_16bit, sizeof(p->u.v_16bit));
Helmut Tschemernjak 4:eb6850e3bc21 262 value = v;
Helmut Tschemernjak 4:eb6850e3bc21 263 }
Helmut Tschemernjak 4:eb6850e3bc21 264 break;
Helmut Tschemernjak 4:eb6850e3bc21 265 case NVProperty::T_32BIT:
Helmut Tschemernjak 4:eb6850e3bc21 266 {
Helmut Tschemernjak 4:eb6850e3bc21 267 int32_t v;
Helmut Tschemernjak 4:eb6850e3bc21 268 memcpy(&v, &p->data.v_32bit, sizeof(p->data.v_32bit));
Helmut Tschemernjak 4:eb6850e3bc21 269 value = v;
Helmut Tschemernjak 4:eb6850e3bc21 270 }
Helmut Tschemernjak 4:eb6850e3bc21 271 break;
Helmut Tschemernjak 4:eb6850e3bc21 272 case NVProperty::T_64BIT:
Helmut Tschemernjak 4:eb6850e3bc21 273 memcpy(&value, p->data.v_64bit, sizeof(p->data.v_64bit));
Helmut Tschemernjak 4:eb6850e3bc21 274 break;
Helmut Tschemernjak 4:eb6850e3bc21 275 case NVProperty::T_STR:
Helmut Tschemernjak 4:eb6850e3bc21 276 case NVProperty::T_BLOB:
Helmut Tschemernjak 4:eb6850e3bc21 277 value = p->u.option.d_len;
Helmut Tschemernjak 4:eb6850e3bc21 278 break;
Helmut Tschemernjak 4:eb6850e3bc21 279 }
Helmut Tschemernjak 4:eb6850e3bc21 280 return value;
Helmut Tschemernjak 4:eb6850e3bc21 281 }
Helmut Tschemernjak 4:eb6850e3bc21 282
Helmut Tschemernjak 4:eb6850e3bc21 283 const char *
Helmut Tschemernjak 4:eb6850e3bc21 284 NVProperty_MBEDFlash::GetPropertyStr(int key)
Helmut Tschemernjak 4:eb6850e3bc21 285 {
Helmut Tschemernjak 4:eb6850e3bc21 286 _flashEntry *p = _GetFlashEntry(key);
Helmut Tschemernjak 4:eb6850e3bc21 287 if (!p || p->t.type != NVProperty::T_STR)
Helmut Tschemernjak 4:eb6850e3bc21 288 return NULL;
Helmut Tschemernjak 4:eb6850e3bc21 289 return strdup(p->data.v_str);
Helmut Tschemernjak 4:eb6850e3bc21 290 }
Helmut Tschemernjak 4:eb6850e3bc21 291
Helmut Tschemernjak 4:eb6850e3bc21 292 int
Helmut Tschemernjak 4:eb6850e3bc21 293 NVProperty_MBEDFlash::GetPropertyBlob(int key, const void *blob, int *size)
Helmut Tschemernjak 4:eb6850e3bc21 294 {
Helmut Tschemernjak 4:eb6850e3bc21 295 _flashEntry *p = _GetFlashEntry(key);
Helmut Tschemernjak 4:eb6850e3bc21 296 if (!p || p->t.type != NVProperty::T_BLOB)
Helmut Tschemernjak 4:eb6850e3bc21 297 return NVProperty::NVP_ENOENT;
Helmut Tschemernjak 4:eb6850e3bc21 298
Helmut Tschemernjak 4:eb6850e3bc21 299 int cplen = std::min(*size, (int)p->u.option.d_len);
Helmut Tschemernjak 4:eb6850e3bc21 300 if (blob)
Helmut Tschemernjak 4:eb6850e3bc21 301 memcpy((void *)blob, p->data.v_blob, cplen);
Helmut Tschemernjak 4:eb6850e3bc21 302 *size = cplen;
Helmut Tschemernjak 4:eb6850e3bc21 303
Helmut Tschemernjak 4:eb6850e3bc21 304 return NVProperty::NVP_OK;
Helmut Tschemernjak 4:eb6850e3bc21 305 }
Helmut Tschemernjak 4:eb6850e3bc21 306
Helmut Tschemernjak 4:eb6850e3bc21 307
Helmut Tschemernjak 4:eb6850e3bc21 308 int
Helmut Tschemernjak 4:eb6850e3bc21 309 NVProperty_MBEDFlash::SetProperty(int key, int64_t value, int type)
Helmut Tschemernjak 4:eb6850e3bc21 310 {
Helmut Tschemernjak 4:eb6850e3bc21 311 UNUSED(type);
Helmut Tschemernjak 5:2560e615ccd5 312 uint8_t valbuf[16];
Helmut Tschemernjak 4:eb6850e3bc21 313 _flashEntry *p = (_flashEntry *) valbuf;
Helmut Tschemernjak 4:eb6850e3bc21 314 int storeType;
Helmut Tschemernjak 4:eb6850e3bc21 315
Helmut Tschemernjak 4:eb6850e3bc21 316 if (GetProperty64(key) == value) // no need to save it again.
Helmut Tschemernjak 4:eb6850e3bc21 317 return NVProperty::NVP_OK;
Helmut Tschemernjak 4:eb6850e3bc21 318
Helmut Tschemernjak 4:eb6850e3bc21 319 memset(valbuf, 0, sizeof(valbuf));
Helmut Tschemernjak 4:eb6850e3bc21 320
Helmut Tschemernjak 4:eb6850e3bc21 321 if (value == 0 || value == 1)
Helmut Tschemernjak 4:eb6850e3bc21 322 storeType = NVProperty::T_BIT;
Helmut Tschemernjak 4:eb6850e3bc21 323 else if (value >= -128 && value < 128)
Helmut Tschemernjak 4:eb6850e3bc21 324 storeType = NVProperty::T_8BIT;
Helmut Tschemernjak 4:eb6850e3bc21 325 else if (value >= -32768 && value < 32768)
Helmut Tschemernjak 4:eb6850e3bc21 326 storeType = NVProperty::T_16BIT;
Helmut Tschemernjak 4:eb6850e3bc21 327 else if (value > -2147483647LL && value < 2147483648LL)
Helmut Tschemernjak 4:eb6850e3bc21 328 storeType = NVProperty::T_32BIT;
Helmut Tschemernjak 4:eb6850e3bc21 329 else
Helmut Tschemernjak 4:eb6850e3bc21 330 storeType = NVProperty::T_64BIT;
Helmut Tschemernjak 4:eb6850e3bc21 331
Helmut Tschemernjak 4:eb6850e3bc21 332 p->key = key;
Helmut Tschemernjak 4:eb6850e3bc21 333 p->t.type = storeType;
Helmut Tschemernjak 4:eb6850e3bc21 334
Helmut Tschemernjak 4:eb6850e3bc21 335
Helmut Tschemernjak 4:eb6850e3bc21 336 switch(storeType) {
Helmut Tschemernjak 4:eb6850e3bc21 337 case NVProperty::T_BIT:
Helmut Tschemernjak 4:eb6850e3bc21 338 p->t.t_bit = value;
Helmut Tschemernjak 4:eb6850e3bc21 339 break;
Helmut Tschemernjak 4:eb6850e3bc21 340 case NVProperty::T_8BIT:
Helmut Tschemernjak 4:eb6850e3bc21 341 p->u.v_8bit = value;
Helmut Tschemernjak 4:eb6850e3bc21 342 break;
Helmut Tschemernjak 4:eb6850e3bc21 343 case NVProperty::T_16BIT:
Helmut Tschemernjak 4:eb6850e3bc21 344 p->u.v_16bit = value;
Helmut Tschemernjak 4:eb6850e3bc21 345 break;
Helmut Tschemernjak 4:eb6850e3bc21 346 case NVProperty::T_32BIT:
Helmut Tschemernjak 4:eb6850e3bc21 347 p->u.option.d_len = sizeof(p->data.v_32bit);
Helmut Tschemernjak 4:eb6850e3bc21 348 {
Helmut Tschemernjak 4:eb6850e3bc21 349 int32_t v = value;
Helmut Tschemernjak 4:eb6850e3bc21 350 memcpy(&p->data.v_32bit, &v, sizeof(p->data.v_32bit));
Helmut Tschemernjak 4:eb6850e3bc21 351 }
Helmut Tschemernjak 4:eb6850e3bc21 352 break;
Helmut Tschemernjak 4:eb6850e3bc21 353 case NVProperty::T_64BIT:
Helmut Tschemernjak 4:eb6850e3bc21 354 p->u.option.d_len = sizeof(p->data.v_64bit);
Helmut Tschemernjak 4:eb6850e3bc21 355 memcpy(p->data.v_64bit, &value, sizeof(p->data.v_64bit));
Helmut Tschemernjak 4:eb6850e3bc21 356 break;
Helmut Tschemernjak 4:eb6850e3bc21 357 }
Helmut Tschemernjak 4:eb6850e3bc21 358 int len;
Helmut Tschemernjak 5:2560e615ccd5 359 if (storeType == NVProperty::T_BIT)
Helmut Tschemernjak 5:2560e615ccd5 360 len = FLASH_ENTRY_HEADER_SHORT;
Helmut Tschemernjak 5:2560e615ccd5 361 else if (storeType == NVProperty::T_8BIT || storeType == NVProperty::T_16BIT)
Helmut Tschemernjak 5:2560e615ccd5 362 len = FLASH_ENTRY_HEADER;
Helmut Tschemernjak 5:2560e615ccd5 363 else // 32/64/STR/BLOB
Helmut Tschemernjak 5:2560e615ccd5 364 len = FLASH_ENTRY_HEADER + p->u.option.d_len;
Helmut Tschemernjak 5:2560e615ccd5 365 len += _GetFlashPaddingSize(len);
Helmut Tschemernjak 4:eb6850e3bc21 366 if ((uint8_t *)_lastEntry + len >= _endAddress) {
Helmut Tschemernjak 4:eb6850e3bc21 367 if (!_FlashReorgEntries(len))
Helmut Tschemernjak 4:eb6850e3bc21 368 return NVProperty::NVP_ERR_NOSPACE;
Helmut Tschemernjak 4:eb6850e3bc21 369 }
Helmut Tschemernjak 4:eb6850e3bc21 370
Helmut Tschemernjak 4:eb6850e3bc21 371 _FlashWrite((uint8_t *)_lastEntry, p, len);
Helmut Tschemernjak 4:eb6850e3bc21 372 _lastEntry = (_flashEntry *)((uint8_t *)_lastEntry + len);
Helmut Tschemernjak 4:eb6850e3bc21 373
Helmut Tschemernjak 4:eb6850e3bc21 374 // _DumpAllEntires();
Helmut Tschemernjak 4:eb6850e3bc21 375 return NVProperty::NVP_OK;
Helmut Tschemernjak 4:eb6850e3bc21 376 }
Helmut Tschemernjak 4:eb6850e3bc21 377
Helmut Tschemernjak 4:eb6850e3bc21 378
Helmut Tschemernjak 4:eb6850e3bc21 379 int
Helmut Tschemernjak 4:eb6850e3bc21 380 NVProperty_MBEDFlash::SetPropertyStr(int key, const char *value, int type)
Helmut Tschemernjak 4:eb6850e3bc21 381 {
Helmut Tschemernjak 4:eb6850e3bc21 382 if (type != NVProperty::T_STR)
Helmut Tschemernjak 4:eb6850e3bc21 383 return NVProperty::NVP_INVALD_PARM;
Helmut Tschemernjak 4:eb6850e3bc21 384
Helmut Tschemernjak 4:eb6850e3bc21 385 _flashEntry *p = _GetFlashEntry(key);
Helmut Tschemernjak 4:eb6850e3bc21 386 if (p && p->t.type == NVProperty::T_STR && strcmp(p->data.v_str, value) == 0) {
Helmut Tschemernjak 4:eb6850e3bc21 387 return NVProperty::NVP_OK;
Helmut Tschemernjak 4:eb6850e3bc21 388 }
Helmut Tschemernjak 4:eb6850e3bc21 389
Helmut Tschemernjak 4:eb6850e3bc21 390 int err = NVProperty::NVP_OK;
Helmut Tschemernjak 4:eb6850e3bc21 391
Helmut Tschemernjak 4:eb6850e3bc21 392 p = new _flashEntry();
Helmut Tschemernjak 4:eb6850e3bc21 393 if (!p)
Helmut Tschemernjak 4:eb6850e3bc21 394 return NVProperty::NVP_ERR_NOSPACE;
Helmut Tschemernjak 4:eb6850e3bc21 395
Helmut Tschemernjak 4:eb6850e3bc21 396 p->key = key;
Helmut Tschemernjak 4:eb6850e3bc21 397 p->t.type = NVProperty::T_STR;
Helmut Tschemernjak 4:eb6850e3bc21 398 int cplen = std::min(strlen(value), sizeof(p->data.v_str)-1);
Helmut Tschemernjak 4:eb6850e3bc21 399 memcpy(p->data.v_str, value, cplen);
Helmut Tschemernjak 4:eb6850e3bc21 400 p->u.option.d_len = cplen + 1; // zero term
Helmut Tschemernjak 4:eb6850e3bc21 401
Helmut Tschemernjak 5:2560e615ccd5 402 int len = FLASH_ENTRY_HEADER + p->u.option.d_len;
Helmut Tschemernjak 4:eb6850e3bc21 403 len += _GetFlashPaddingSize(len);
Helmut Tschemernjak 4:eb6850e3bc21 404
Helmut Tschemernjak 4:eb6850e3bc21 405 if ((uint8_t *)_lastEntry + len >= _endAddress) {
Helmut Tschemernjak 4:eb6850e3bc21 406 if (!_FlashReorgEntries(len)) {
Helmut Tschemernjak 4:eb6850e3bc21 407 err = NVProperty::NVP_ERR_NOSPACE;
Helmut Tschemernjak 4:eb6850e3bc21 408 goto done;
Helmut Tschemernjak 4:eb6850e3bc21 409 }
Helmut Tschemernjak 4:eb6850e3bc21 410 }
Helmut Tschemernjak 4:eb6850e3bc21 411
Helmut Tschemernjak 4:eb6850e3bc21 412 _FlashWrite((uint8_t *)_lastEntry, p, len);
Helmut Tschemernjak 4:eb6850e3bc21 413 _lastEntry = (_flashEntry *)((uint8_t *)_lastEntry + len);
Helmut Tschemernjak 4:eb6850e3bc21 414
Helmut Tschemernjak 4:eb6850e3bc21 415 done:
Helmut Tschemernjak 4:eb6850e3bc21 416 delete[] p;
Helmut Tschemernjak 4:eb6850e3bc21 417 // _DumpAllEntires();
Helmut Tschemernjak 4:eb6850e3bc21 418 return err;
Helmut Tschemernjak 4:eb6850e3bc21 419 }
Helmut Tschemernjak 4:eb6850e3bc21 420
Helmut Tschemernjak 4:eb6850e3bc21 421 int
Helmut Tschemernjak 4:eb6850e3bc21 422 NVProperty_MBEDFlash::SetPropertyBlob(int key, const void *blob, int size, int type)
Helmut Tschemernjak 4:eb6850e3bc21 423 {
Helmut Tschemernjak 4:eb6850e3bc21 424 if (type != NVProperty::T_BLOB)
Helmut Tschemernjak 4:eb6850e3bc21 425 return NVProperty::NVP_INVALD_PARM;
Helmut Tschemernjak 4:eb6850e3bc21 426
Helmut Tschemernjak 4:eb6850e3bc21 427 _flashEntry *p = _GetFlashEntry(key);
Helmut Tschemernjak 4:eb6850e3bc21 428 if (p && p->t.type == NVProperty::T_BLOB && size == p->u.option.d_len) { // check for duplicate
Helmut Tschemernjak 4:eb6850e3bc21 429 if (memcmp(blob, p->data.v_blob, size) == 0)
Helmut Tschemernjak 4:eb6850e3bc21 430 return NVProperty::NVP_OK;
Helmut Tschemernjak 4:eb6850e3bc21 431 }
Helmut Tschemernjak 4:eb6850e3bc21 432 int err = NVProperty::NVP_OK;
Helmut Tschemernjak 4:eb6850e3bc21 433
Helmut Tschemernjak 4:eb6850e3bc21 434 p = new _flashEntry();
Helmut Tschemernjak 4:eb6850e3bc21 435 if (!p)
Helmut Tschemernjak 4:eb6850e3bc21 436 return NVProperty::NVP_ERR_NOSPACE;
Helmut Tschemernjak 4:eb6850e3bc21 437
Helmut Tschemernjak 4:eb6850e3bc21 438 p->key = key;
Helmut Tschemernjak 4:eb6850e3bc21 439 p->t.type = NVProperty::T_BLOB;
Helmut Tschemernjak 4:eb6850e3bc21 440 int cplen = std::min(size, (int)sizeof(p->data.v_blob));
Helmut Tschemernjak 4:eb6850e3bc21 441 p->u.option.d_len = cplen;
Helmut Tschemernjak 4:eb6850e3bc21 442 memcpy(p->data.v_blob, blob, cplen);
Helmut Tschemernjak 4:eb6850e3bc21 443
Helmut Tschemernjak 5:2560e615ccd5 444 int len = FLASH_ENTRY_HEADER + p->u.option.d_len;
Helmut Tschemernjak 4:eb6850e3bc21 445 len += _GetFlashPaddingSize(len);
Helmut Tschemernjak 4:eb6850e3bc21 446
Helmut Tschemernjak 4:eb6850e3bc21 447 if ((uint8_t *)_lastEntry + len >= _endAddress) {
Helmut Tschemernjak 4:eb6850e3bc21 448 if (!_FlashReorgEntries(len)) {
Helmut Tschemernjak 4:eb6850e3bc21 449 err = NVProperty::NVP_ERR_NOSPACE;
Helmut Tschemernjak 4:eb6850e3bc21 450 goto done;
Helmut Tschemernjak 4:eb6850e3bc21 451 }
Helmut Tschemernjak 4:eb6850e3bc21 452 }
Helmut Tschemernjak 4:eb6850e3bc21 453
Helmut Tschemernjak 4:eb6850e3bc21 454 _FlashWrite((uint8_t *)_lastEntry, p, len);
Helmut Tschemernjak 4:eb6850e3bc21 455 _lastEntry = (_flashEntry *)((uint8_t *)_lastEntry + len);
Helmut Tschemernjak 4:eb6850e3bc21 456
Helmut Tschemernjak 4:eb6850e3bc21 457 done:
Helmut Tschemernjak 4:eb6850e3bc21 458 delete[] p;
Helmut Tschemernjak 4:eb6850e3bc21 459 // _DumpAllEntires();
Helmut Tschemernjak 4:eb6850e3bc21 460 return err;
Helmut Tschemernjak 4:eb6850e3bc21 461 }
Helmut Tschemernjak 4:eb6850e3bc21 462
Helmut Tschemernjak 4:eb6850e3bc21 463 int
Helmut Tschemernjak 4:eb6850e3bc21 464 NVProperty_MBEDFlash::EraseProperty(int key)
Helmut Tschemernjak 4:eb6850e3bc21 465 {
Helmut Tschemernjak 5:2560e615ccd5 466 uint8_t valbuf[16];
Helmut Tschemernjak 4:eb6850e3bc21 467 _flashEntry *p = (_flashEntry *) valbuf;
Helmut Tschemernjak 4:eb6850e3bc21 468
Helmut Tschemernjak 4:eb6850e3bc21 469 _flashEntry *op = _GetFlashEntry(key);
Helmut Tschemernjak 4:eb6850e3bc21 470 if (!op)
Helmut Tschemernjak 4:eb6850e3bc21 471 return NVProperty::NVP_ENOENT;
Helmut Tschemernjak 4:eb6850e3bc21 472 if (op->t.deleted)
Helmut Tschemernjak 4:eb6850e3bc21 473 return NVProperty::NVP_OK;
Helmut Tschemernjak 4:eb6850e3bc21 474
Helmut Tschemernjak 4:eb6850e3bc21 475 memset(valbuf, 0, sizeof(valbuf));
Helmut Tschemernjak 4:eb6850e3bc21 476 p->key = key;
Helmut Tschemernjak 4:eb6850e3bc21 477 p->t.type = op->t.type;
Helmut Tschemernjak 4:eb6850e3bc21 478 p->t.deleted = true;
Helmut Tschemernjak 4:eb6850e3bc21 479
Helmut Tschemernjak 5:2560e615ccd5 480 int len = FLASH_ENTRY_HEADER_SHORT;
Helmut Tschemernjak 5:2560e615ccd5 481 len += _GetFlashPaddingSize(len);
Helmut Tschemernjak 5:2560e615ccd5 482
Helmut Tschemernjak 5:2560e615ccd5 483 if ((uint8_t *)_lastEntry + len > _endAddress) {
Helmut Tschemernjak 5:2560e615ccd5 484 if (!_FlashReorgEntries(len))
Helmut Tschemernjak 5:2560e615ccd5 485 return NVProperty::NVP_ERR_NOSPACE;
Helmut Tschemernjak 4:eb6850e3bc21 486 }
Helmut Tschemernjak 4:eb6850e3bc21 487
Helmut Tschemernjak 5:2560e615ccd5 488 _FlashWrite((uint8_t *)_lastEntry, p, len);
Helmut Tschemernjak 5:2560e615ccd5 489 _lastEntry = (_flashEntry *)((uint8_t *)_lastEntry + len);
Helmut Tschemernjak 4:eb6850e3bc21 490
Helmut Tschemernjak 4:eb6850e3bc21 491 // _DumpAllEntires();
Helmut Tschemernjak 4:eb6850e3bc21 492 return NVProperty::NVP_OK;
Helmut Tschemernjak 4:eb6850e3bc21 493 }
Helmut Tschemernjak 4:eb6850e3bc21 494
Helmut Tschemernjak 4:eb6850e3bc21 495 int
Helmut Tschemernjak 4:eb6850e3bc21 496 NVProperty_MBEDFlash::ReorgProperties(void)
Helmut Tschemernjak 4:eb6850e3bc21 497 {
Helmut Tschemernjak 5:2560e615ccd5 498 if (_FlashReorgEntries(FLASH_ENTRY_HEADER))
Helmut Tschemernjak 4:eb6850e3bc21 499 return NVProperty::NVP_OK;
Helmut Tschemernjak 4:eb6850e3bc21 500 return NVProperty::NVP_ERR_NOSPACE;
Helmut Tschemernjak 4:eb6850e3bc21 501 }
Helmut Tschemernjak 4:eb6850e3bc21 502
Helmut Tschemernjak 4:eb6850e3bc21 503
Helmut Tschemernjak 4:eb6850e3bc21 504 int
Helmut Tschemernjak 4:eb6850e3bc21 505 NVProperty_MBEDFlash::OpenPropertyStore(bool forWrite)
Helmut Tschemernjak 4:eb6850e3bc21 506 {
Helmut Tschemernjak 4:eb6850e3bc21 507 UNUSED(forWrite);
Helmut Tschemernjak 4:eb6850e3bc21 508 return NVProperty::NVP_OK;
Helmut Tschemernjak 4:eb6850e3bc21 509 }
Helmut Tschemernjak 4:eb6850e3bc21 510
Helmut Tschemernjak 4:eb6850e3bc21 511 int
Helmut Tschemernjak 4:eb6850e3bc21 512 NVProperty_MBEDFlash::ClosePropertyStore(bool flush)
Helmut Tschemernjak 4:eb6850e3bc21 513 {
Helmut Tschemernjak 4:eb6850e3bc21 514 return NVProperty::NVP_OK;
Helmut Tschemernjak 4:eb6850e3bc21 515 }
Helmut Tschemernjak 4:eb6850e3bc21 516
Helmut Tschemernjak 4:eb6850e3bc21 517 #if 1
Helmut Tschemernjak 4:eb6850e3bc21 518 void
Helmut Tschemernjak 4:eb6850e3bc21 519 NVProperty_MBEDFlash::_DumpAllEntires(void)
Helmut Tschemernjak 4:eb6850e3bc21 520 {
Helmut Tschemernjak 4:eb6850e3bc21 521 if (!_debug)
Helmut Tschemernjak 4:eb6850e3bc21 522 return;
Helmut Tschemernjak 4:eb6850e3bc21 523
Helmut Tschemernjak 4:eb6850e3bc21 524 dprintf("------------- DumpAllEntires -------- ");
Helmut Tschemernjak 4:eb6850e3bc21 525
Helmut Tschemernjak 4:eb6850e3bc21 526 int index = 0;
Helmut Tschemernjak 4:eb6850e3bc21 527 _flashEntry *p = (_flashEntry *)(_startAddress + sizeof(_flash_header));
Helmut Tschemernjak 12:5539cdc8be4b 528 while((uint8_t *)p < _endAddress && p->key != _flashErasedValue) {
Helmut Tschemernjak 4:eb6850e3bc21 529
Helmut Tschemernjak 4:eb6850e3bc21 530 int64_t value = 0;
Helmut Tschemernjak 4:eb6850e3bc21 531 switch(p->t.type) {
Helmut Tschemernjak 4:eb6850e3bc21 532 case NVProperty::T_BIT:
Helmut Tschemernjak 4:eb6850e3bc21 533 if (p->t.t_bit)
Helmut Tschemernjak 4:eb6850e3bc21 534 value = 1;
Helmut Tschemernjak 4:eb6850e3bc21 535 else
Helmut Tschemernjak 4:eb6850e3bc21 536 value = 0;
Helmut Tschemernjak 4:eb6850e3bc21 537 break;
Helmut Tschemernjak 4:eb6850e3bc21 538 case NVProperty::T_8BIT:
Helmut Tschemernjak 4:eb6850e3bc21 539 value = p->u.v_8bit;
Helmut Tschemernjak 4:eb6850e3bc21 540 break;
Helmut Tschemernjak 4:eb6850e3bc21 541 case NVProperty::T_16BIT:
Helmut Tschemernjak 4:eb6850e3bc21 542 {
Helmut Tschemernjak 4:eb6850e3bc21 543 int16_t v;
Helmut Tschemernjak 4:eb6850e3bc21 544 memcpy(&v, &p->u.v_16bit, sizeof(p->u.v_16bit));
Helmut Tschemernjak 4:eb6850e3bc21 545 value = v;
Helmut Tschemernjak 4:eb6850e3bc21 546 }
Helmut Tschemernjak 4:eb6850e3bc21 547 break;
Helmut Tschemernjak 4:eb6850e3bc21 548 case NVProperty::T_32BIT:
Helmut Tschemernjak 4:eb6850e3bc21 549 {
Helmut Tschemernjak 4:eb6850e3bc21 550 int32_t v;
Helmut Tschemernjak 4:eb6850e3bc21 551 memcpy(&v, &p->data.v_32bit, sizeof(p->data.v_32bit));
Helmut Tschemernjak 4:eb6850e3bc21 552 value = v;
Helmut Tschemernjak 4:eb6850e3bc21 553 }
Helmut Tschemernjak 4:eb6850e3bc21 554 break;
Helmut Tschemernjak 4:eb6850e3bc21 555 case NVProperty::T_64BIT:
Helmut Tschemernjak 4:eb6850e3bc21 556 memcpy(&value, p->data.v_64bit, sizeof(p->data.v_64bit));
Helmut Tschemernjak 4:eb6850e3bc21 557 break;
Helmut Tschemernjak 4:eb6850e3bc21 558 case NVProperty::T_STR:
Helmut Tschemernjak 4:eb6850e3bc21 559 case NVProperty::T_BLOB:
Helmut Tschemernjak 4:eb6850e3bc21 560 value = p->u.option.d_len;
Helmut Tschemernjak 4:eb6850e3bc21 561 break;
Helmut Tschemernjak 4:eb6850e3bc21 562 }
Helmut Tschemernjak 4:eb6850e3bc21 563 index++;
Helmut Tschemernjak 4:eb6850e3bc21 564 if (p->t.deleted) {
Helmut Tschemernjak 4:eb6850e3bc21 565 dprintf("Dump[%.2d] Key: %d Type: %d deleted(%d)", index, p->key, p->t.type, p->t.deleted);
Helmut Tschemernjak 4:eb6850e3bc21 566
Helmut Tschemernjak 4:eb6850e3bc21 567 } else if (p->t.type == NVProperty::T_STR) {
Helmut Tschemernjak 4:eb6850e3bc21 568 dprintf("Dump[%.2d] Key: %d Type: %d value: %s", index, p->key, p->t.type, p->data.v_str);
Helmut Tschemernjak 4:eb6850e3bc21 569 } else if (p->t.type == NVProperty::T_BLOB) {
Helmut Tschemernjak 4:eb6850e3bc21 570 dprintf("Dump[%.2d] Key: %d Type: %d len: %d", index, p->key, p->t.type, p->u.option.d_len);
Helmut Tschemernjak 4:eb6850e3bc21 571 dump("Blob", p->data.v_str, p->u.option.d_len);
Helmut Tschemernjak 4:eb6850e3bc21 572 } else {
Helmut Tschemernjak 4:eb6850e3bc21 573 if (p->t.type == NVProperty::T_64BIT) {
Helmut Tschemernjak 4:eb6850e3bc21 574 dprintf("Dump[%.2d] Key: %d Type: %d value: %lld (0x%llx)", index, p->key, p->t.type, value, value);
Helmut Tschemernjak 4:eb6850e3bc21 575 } else {
Helmut Tschemernjak 4:eb6850e3bc21 576 dprintf("Dump[%.2d] Key: %d Type: %d value: %ld (0x%x)", index, p->key, p->t.type, (int32_t)value, (unsigned int)value);
Helmut Tschemernjak 4:eb6850e3bc21 577 }
Helmut Tschemernjak 4:eb6850e3bc21 578 }
Helmut Tschemernjak 4:eb6850e3bc21 579
Helmut Tschemernjak 4:eb6850e3bc21 580 p = (_flashEntry *)((uint8_t *)p + _GetFlashEntryLen(p));
Helmut Tschemernjak 4:eb6850e3bc21 581 }
Helmut Tschemernjak 4:eb6850e3bc21 582 int freebytes = _endAddress -(uint8_t *)_lastEntry;
Helmut Tschemernjak 4:eb6850e3bc21 583 if (_lastEntry)
Helmut Tschemernjak 4:eb6850e3bc21 584 dprintf("------ %d bytes free -------", freebytes);
Helmut Tschemernjak 4:eb6850e3bc21 585 }
Helmut Tschemernjak 4:eb6850e3bc21 586 #endif
Helmut Tschemernjak 4:eb6850e3bc21 587
Helmut Tschemernjak 4:eb6850e3bc21 588 NVProperty_MBEDFlash::_flashEntry *
Helmut Tschemernjak 4:eb6850e3bc21 589 NVProperty_MBEDFlash::_GetFlashEntry(int key, uint8_t *start)
Helmut Tschemernjak 4:eb6850e3bc21 590 {
Helmut Tschemernjak 4:eb6850e3bc21 591 _flashEntry *p;
Helmut Tschemernjak 4:eb6850e3bc21 592
Helmut Tschemernjak 4:eb6850e3bc21 593 if (start)
Helmut Tschemernjak 4:eb6850e3bc21 594 p = (_flashEntry *)start;
Helmut Tschemernjak 4:eb6850e3bc21 595 else
Helmut Tschemernjak 4:eb6850e3bc21 596 p = (_flashEntry *)(_startAddress + sizeof(_flash_header));
Helmut Tschemernjak 4:eb6850e3bc21 597 _flashEntry *lastP = NULL;
Helmut Tschemernjak 4:eb6850e3bc21 598 while(true) {
Helmut Tschemernjak 12:5539cdc8be4b 599 if ((uint8_t*)p >= _endAddress || p->key == _flashErasedValue) {
Helmut Tschemernjak 4:eb6850e3bc21 600 if ((uint8_t*)p <= _endAddress)
Helmut Tschemernjak 4:eb6850e3bc21 601 _lastEntry = p;
Helmut Tschemernjak 4:eb6850e3bc21 602 if (!lastP || lastP->t.deleted)
Helmut Tschemernjak 4:eb6850e3bc21 603 return NULL;
Helmut Tschemernjak 4:eb6850e3bc21 604 break;
Helmut Tschemernjak 4:eb6850e3bc21 605 }
Helmut Tschemernjak 4:eb6850e3bc21 606 if (p->key == key)
Helmut Tschemernjak 4:eb6850e3bc21 607 lastP = p;
Helmut Tschemernjak 4:eb6850e3bc21 608
Helmut Tschemernjak 4:eb6850e3bc21 609 p = (_flashEntry *)((uint8_t *)p + _GetFlashEntryLen(p));
Helmut Tschemernjak 4:eb6850e3bc21 610 }
Helmut Tschemernjak 4:eb6850e3bc21 611 return lastP;
Helmut Tschemernjak 4:eb6850e3bc21 612 }
Helmut Tschemernjak 4:eb6850e3bc21 613
Helmut Tschemernjak 4:eb6850e3bc21 614
Helmut Tschemernjak 4:eb6850e3bc21 615 int
Helmut Tschemernjak 4:eb6850e3bc21 616 NVProperty_MBEDFlash::_GetFlashEntryLen(_flashEntry *p)
Helmut Tschemernjak 4:eb6850e3bc21 617 {
Helmut Tschemernjak 4:eb6850e3bc21 618 int len = 0;
Helmut Tschemernjak 4:eb6850e3bc21 619
Helmut Tschemernjak 5:2560e615ccd5 620 if (p->t.type == NVProperty::T_BIT || p->t.deleted)
Helmut Tschemernjak 5:2560e615ccd5 621 len = FLASH_ENTRY_HEADER_SHORT;
Helmut Tschemernjak 5:2560e615ccd5 622 else if (p->t.type == NVProperty::T_8BIT || p->t.type == NVProperty::T_16BIT)
Helmut Tschemernjak 5:2560e615ccd5 623 len = FLASH_ENTRY_HEADER;
Helmut Tschemernjak 5:2560e615ccd5 624 else
Helmut Tschemernjak 5:2560e615ccd5 625 len = FLASH_ENTRY_HEADER + p->u.option.d_len;
Helmut Tschemernjak 5:2560e615ccd5 626
Helmut Tschemernjak 5:2560e615ccd5 627 len += _GetFlashPaddingSize(len);
Helmut Tschemernjak 5:2560e615ccd5 628
Helmut Tschemernjak 4:eb6850e3bc21 629 return len;
Helmut Tschemernjak 4:eb6850e3bc21 630 }
Helmut Tschemernjak 4:eb6850e3bc21 631
Helmut Tschemernjak 4:eb6850e3bc21 632 int
Helmut Tschemernjak 4:eb6850e3bc21 633 NVProperty_MBEDFlash::_GetFlashPaddingSize(int len)
Helmut Tschemernjak 4:eb6850e3bc21 634 {
Helmut Tschemernjak 5:2560e615ccd5 635 int remain = len % _pageSize;
Helmut Tschemernjak 4:eb6850e3bc21 636
Helmut Tschemernjak 4:eb6850e3bc21 637 if (remain == 0)
Helmut Tschemernjak 4:eb6850e3bc21 638 return 0;
Helmut Tschemernjak 4:eb6850e3bc21 639
Helmut Tschemernjak 5:2560e615ccd5 640 return (len + _pageSize - remain) - len;
Helmut Tschemernjak 4:eb6850e3bc21 641 }
Helmut Tschemernjak 4:eb6850e3bc21 642
Helmut Tschemernjak 4:eb6850e3bc21 643
Helmut Tschemernjak 4:eb6850e3bc21 644 int
Helmut Tschemernjak 4:eb6850e3bc21 645 NVProperty_MBEDFlash::_FlashReorgEntries(int minRequiredSpace)
Helmut Tschemernjak 4:eb6850e3bc21 646 {
Helmut Tschemernjak 4:eb6850e3bc21 647 if (_debug) {
Helmut Tschemernjak 4:eb6850e3bc21 648 dprintf("_FlashReorgEntries: start");
Helmut Tschemernjak 4:eb6850e3bc21 649 // _DumpAllEntires();
Helmut Tschemernjak 4:eb6850e3bc21 650 }
Helmut Tschemernjak 4:eb6850e3bc21 651
Helmut Tschemernjak 4:eb6850e3bc21 652 int totalLen = 0;
Helmut Tschemernjak 4:eb6850e3bc21 653 int freeSpace = 0;
Helmut Tschemernjak 4:eb6850e3bc21 654
Helmut Tschemernjak 4:eb6850e3bc21 655 _flashEntry *p = (_flashEntry *)(_startAddress + sizeof(_flash_header));
Helmut Tschemernjak 12:5539cdc8be4b 656 while((uint8_t *)p < _endAddress && p->key != _flashErasedValue) {
Helmut Tschemernjak 4:eb6850e3bc21 657 _flashEntry *k = _GetFlashEntry(p->key);
Helmut Tschemernjak 4:eb6850e3bc21 658 if (k == p) { // current entry is the lastest one.
Helmut Tschemernjak 4:eb6850e3bc21 659 totalLen += _GetFlashEntryLen(k);
Helmut Tschemernjak 4:eb6850e3bc21 660 }
Helmut Tschemernjak 4:eb6850e3bc21 661 p = (_flashEntry *)((uint8_t *)p + _GetFlashEntryLen(p));
Helmut Tschemernjak 4:eb6850e3bc21 662 }
Helmut Tschemernjak 4:eb6850e3bc21 663
Helmut Tschemernjak 4:eb6850e3bc21 664 if (_startAddress + sizeof(_flash_header) + totalLen + minRequiredSpace >= _endAddress)
Helmut Tschemernjak 4:eb6850e3bc21 665 return 0;
Helmut Tschemernjak 4:eb6850e3bc21 666
Helmut Tschemernjak 4:eb6850e3bc21 667 freeSpace = _endAddress - (_startAddress + sizeof(_flash_header) + totalLen);
Helmut Tschemernjak 4:eb6850e3bc21 668 if (_debug)
Helmut Tschemernjak 4:eb6850e3bc21 669 dprintf("freeSpace: %d, totalLen: %d", freeSpace, totalLen);
Helmut Tschemernjak 4:eb6850e3bc21 670
Helmut Tschemernjak 4:eb6850e3bc21 671 /*
Helmut Tschemernjak 4:eb6850e3bc21 672 * Copy header
Helmut Tschemernjak 4:eb6850e3bc21 673 * while (content {
Helmut Tschemernjak 4:eb6850e3bc21 674 * - scan until tmp page is full
Helmut Tschemernjak 4:eb6850e3bc21 675 * - write page
Helmut Tschemernjak 4:eb6850e3bc21 676 * }
Helmut Tschemernjak 4:eb6850e3bc21 677 * Erase remaining pages.
Helmut Tschemernjak 4:eb6850e3bc21 678 *
Helmut Tschemernjak 4:eb6850e3bc21 679 */
Helmut Tschemernjak 4:eb6850e3bc21 680
Helmut Tschemernjak 4:eb6850e3bc21 681 p = (_flashEntry *)(_startAddress + sizeof(_flash_header));
Helmut Tschemernjak 4:eb6850e3bc21 682 uint8_t *saveddata = new uint8_t[_rowSize+sizeof(struct _flashEntry)];
Helmut Tschemernjak 4:eb6850e3bc21 683 if (!saveddata)
Helmut Tschemernjak 4:eb6850e3bc21 684 return 0;
Helmut Tschemernjak 4:eb6850e3bc21 685 uint8_t *t = saveddata;
Helmut Tschemernjak 4:eb6850e3bc21 686 int currentRow = (uint32_t)_startAddress / _rowSize;
Helmut Tschemernjak 4:eb6850e3bc21 687 int totalCopied = 0;
Helmut Tschemernjak 4:eb6850e3bc21 688
Helmut Tschemernjak 4:eb6850e3bc21 689 t = saveddata;
Helmut Tschemernjak 4:eb6850e3bc21 690 memcpy(t, _startAddress, sizeof(_flash_header));
Helmut Tschemernjak 4:eb6850e3bc21 691 t += sizeof(_flash_header);
Helmut Tschemernjak 4:eb6850e3bc21 692
Helmut Tschemernjak 12:5539cdc8be4b 693 while((uint8_t *)p < _endAddress && p->key != _flashErasedValue) {
Helmut Tschemernjak 4:eb6850e3bc21 694 _flashEntry *k = _GetFlashEntry(p->key, (uint8_t *)p);
Helmut Tschemernjak 4:eb6850e3bc21 695 if (k == p) { // current entry is the lastest one.
Helmut Tschemernjak 4:eb6850e3bc21 696 if (!p->t.deleted) {
Helmut Tschemernjak 4:eb6850e3bc21 697 int plen = _GetFlashEntryLen(p);
Helmut Tschemernjak 4:eb6850e3bc21 698 memcpy(t, p, plen);
Helmut Tschemernjak 4:eb6850e3bc21 699 t += plen;
Helmut Tschemernjak 4:eb6850e3bc21 700 totalCopied += plen;
Helmut Tschemernjak 4:eb6850e3bc21 701 if (t - saveddata >= _rowSize) { // copy page
Helmut Tschemernjak 4:eb6850e3bc21 702 _FlashEraseRow(currentRow);
Helmut Tschemernjak 4:eb6850e3bc21 703 _FlashWrite((uint8_t *)(currentRow++ * _rowSize), saveddata, _rowSize);
Helmut Tschemernjak 4:eb6850e3bc21 704 int remainLen = (t - saveddata) - _rowSize;
Helmut Tschemernjak 4:eb6850e3bc21 705 if (remainLen) {
Helmut Tschemernjak 4:eb6850e3bc21 706 memcpy(saveddata, t - remainLen, remainLen);
Helmut Tschemernjak 4:eb6850e3bc21 707 }
Helmut Tschemernjak 4:eb6850e3bc21 708 t = saveddata + remainLen;
Helmut Tschemernjak 4:eb6850e3bc21 709 }
Helmut Tschemernjak 4:eb6850e3bc21 710 }
Helmut Tschemernjak 4:eb6850e3bc21 711 }
Helmut Tschemernjak 4:eb6850e3bc21 712 p = (_flashEntry *)((uint8_t *)p + _GetFlashEntryLen(p));
Helmut Tschemernjak 4:eb6850e3bc21 713 }
Helmut Tschemernjak 4:eb6850e3bc21 714
Helmut Tschemernjak 4:eb6850e3bc21 715 if (t > saveddata) { // copy remaining
Helmut Tschemernjak 4:eb6850e3bc21 716 _FlashEraseRow(currentRow);
Helmut Tschemernjak 4:eb6850e3bc21 717 _FlashWrite((uint8_t *)(currentRow++ * _rowSize), saveddata, t - saveddata);
Helmut Tschemernjak 4:eb6850e3bc21 718 }
Helmut Tschemernjak 4:eb6850e3bc21 719
Helmut Tschemernjak 4:eb6850e3bc21 720 while((uint32_t)0 + currentRow * _rowSize < (uint32_t)_endAddress) {
Helmut Tschemernjak 4:eb6850e3bc21 721 _FlashEraseRow(currentRow++);
Helmut Tschemernjak 4:eb6850e3bc21 722 }
Helmut Tschemernjak 4:eb6850e3bc21 723 delete[] saveddata;
Helmut Tschemernjak 4:eb6850e3bc21 724 _GetFlashEntry(0); // inits the _lastEntry record
Helmut Tschemernjak 4:eb6850e3bc21 725
Helmut Tschemernjak 4:eb6850e3bc21 726 if (_debug) {
Helmut Tschemernjak 4:eb6850e3bc21 727 dprintf("_FlashReorgEntries: end");
Helmut Tschemernjak 4:eb6850e3bc21 728 _DumpAllEntires();
Helmut Tschemernjak 4:eb6850e3bc21 729 }
Helmut Tschemernjak 4:eb6850e3bc21 730
Helmut Tschemernjak 4:eb6850e3bc21 731 return _endAddress - _startAddress - (sizeof(_flash_header) + totalCopied);
Helmut Tschemernjak 4:eb6850e3bc21 732 }
Helmut Tschemernjak 4:eb6850e3bc21 733
Helmut Tschemernjak 4:eb6850e3bc21 734
Helmut Tschemernjak 4:eb6850e3bc21 735 #endif // __MBED__