from bbc microbit library

Dependencies:   BLE_API mbed-dev-bin nRF51822

Dependents:   microbit

Fork of microbit-dal by Lancaster University

Committer:
LancasterUniversity
Date:
Wed Jul 13 12:18:08 2016 +0100
Revision:
30:db87179335d5
Parent:
3:d86a4ddc1867
Child:
31:87789e55bac7
Synchronized with git rev 3b435c0d
Author: James Devine
microbit-dal: BUGFIX in MicroBitStorage

There was an off by one error when storing the key of the key value
pair, where the null terminator was dropped. This would mean that if
the returned key of the KeyValuePair were used, it would cause a number
of issues.

Another issue raised was the copying a random 48 bytes from memory
regardless of the position of memory in the stack. If the memory was
smaller than 48 bytes, and existed at the top of the stack, this could
have dire consequences. As a result, MicroBitStorage now accepts a size
parameter which informs the number of bytes to be copied into flash.

#130

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jonathan Austin 1:8aa5cdb4ab67 1 /*
Jonathan Austin 1:8aa5cdb4ab67 2 The MIT License (MIT)
Jonathan Austin 1:8aa5cdb4ab67 3
Jonathan Austin 1:8aa5cdb4ab67 4 Copyright (c) 2016 British Broadcasting Corporation.
Jonathan Austin 1:8aa5cdb4ab67 5 This software is provided by Lancaster University by arrangement with the BBC.
Jonathan Austin 1:8aa5cdb4ab67 6
Jonathan Austin 1:8aa5cdb4ab67 7 Permission is hereby granted, free of charge, to any person obtaining a
Jonathan Austin 1:8aa5cdb4ab67 8 copy of this software and associated documentation files (the "Software"),
Jonathan Austin 1:8aa5cdb4ab67 9 to deal in the Software without restriction, including without limitation
Jonathan Austin 1:8aa5cdb4ab67 10 the rights to use, copy, modify, merge, publish, distribute, sublicense,
Jonathan Austin 1:8aa5cdb4ab67 11 and/or sell copies of the Software, and to permit persons to whom the
Jonathan Austin 1:8aa5cdb4ab67 12 Software is furnished to do so, subject to the following conditions:
Jonathan Austin 1:8aa5cdb4ab67 13
Jonathan Austin 1:8aa5cdb4ab67 14 The above copyright notice and this permission notice shall be included in
Jonathan Austin 1:8aa5cdb4ab67 15 all copies or substantial portions of the Software.
Jonathan Austin 1:8aa5cdb4ab67 16
Jonathan Austin 1:8aa5cdb4ab67 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Jonathan Austin 1:8aa5cdb4ab67 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Jonathan Austin 1:8aa5cdb4ab67 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Jonathan Austin 1:8aa5cdb4ab67 20 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
Jonathan Austin 1:8aa5cdb4ab67 22 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 23 DEALINGS IN THE SOFTWARE.
Jonathan Austin 1:8aa5cdb4ab67 24 */
Jonathan Austin 1:8aa5cdb4ab67 25
Jonathan Austin 1:8aa5cdb4ab67 26 #ifndef MICROBIT_STORAGE_H
Jonathan Austin 1:8aa5cdb4ab67 27 #define MICROBIT_STORAGE_H
Jonathan Austin 1:8aa5cdb4ab67 28
Jonathan Austin 1:8aa5cdb4ab67 29 #include "mbed.h"
Jonathan Austin 1:8aa5cdb4ab67 30 #include "MicroBitConfig.h"
Jonathan Austin 1:8aa5cdb4ab67 31 #include "ManagedString.h"
Jonathan Austin 1:8aa5cdb4ab67 32 #include "ErrorNo.h"
Jonathan Austin 1:8aa5cdb4ab67 33
Jonathan Austin 1:8aa5cdb4ab67 34 #define MICROBIT_STORAGE_MAGIC 0xCAFE
Jonathan Austin 1:8aa5cdb4ab67 35
Jonathan Austin 1:8aa5cdb4ab67 36 #define MICROBIT_STORAGE_BLOCK_SIZE 48
Jonathan Austin 1:8aa5cdb4ab67 37 #define MICROBIT_STORAGE_KEY_SIZE 16
Jonathan Austin 1:8aa5cdb4ab67 38 #define MICROBIT_STORAGE_VALUE_SIZE MICROBIT_STORAGE_BLOCK_SIZE - MICROBIT_STORAGE_KEY_SIZE
Jonathan Austin 1:8aa5cdb4ab67 39
Jonathan Austin 1:8aa5cdb4ab67 40 #define MICROBIT_STORAGE_STORE_PAGE_OFFSET 17 //Use the page just above the BLE Bond Data.
Jonathan Austin 1:8aa5cdb4ab67 41 #define MICROBIT_STORAGE_SCRATCH_PAGE_OFFSET 19 //Use the page just below the BLE Bond Data.
Jonathan Austin 1:8aa5cdb4ab67 42
Jonathan Austin 1:8aa5cdb4ab67 43 struct KeyValuePair
Jonathan Austin 1:8aa5cdb4ab67 44 {
LancasterUniversity 3:d86a4ddc1867 45 uint8_t key[MICROBIT_STORAGE_KEY_SIZE];
LancasterUniversity 3:d86a4ddc1867 46 uint8_t value[MICROBIT_STORAGE_VALUE_SIZE];
Jonathan Austin 1:8aa5cdb4ab67 47 };
Jonathan Austin 1:8aa5cdb4ab67 48
Jonathan Austin 1:8aa5cdb4ab67 49 struct KeyValueStore
Jonathan Austin 1:8aa5cdb4ab67 50 {
Jonathan Austin 1:8aa5cdb4ab67 51 uint32_t magic;
Jonathan Austin 1:8aa5cdb4ab67 52 uint32_t size;
Jonathan Austin 1:8aa5cdb4ab67 53
Jonathan Austin 1:8aa5cdb4ab67 54 KeyValueStore(uint32_t magic, uint32_t size)
Jonathan Austin 1:8aa5cdb4ab67 55 {
Jonathan Austin 1:8aa5cdb4ab67 56 this->magic = magic;
Jonathan Austin 1:8aa5cdb4ab67 57 this->size = size;
Jonathan Austin 1:8aa5cdb4ab67 58 }
Jonathan Austin 1:8aa5cdb4ab67 59
Jonathan Austin 1:8aa5cdb4ab67 60 KeyValueStore()
Jonathan Austin 1:8aa5cdb4ab67 61 {
Jonathan Austin 1:8aa5cdb4ab67 62 this->magic = 0;
Jonathan Austin 1:8aa5cdb4ab67 63 this->size = 0;
Jonathan Austin 1:8aa5cdb4ab67 64 }
Jonathan Austin 1:8aa5cdb4ab67 65 };
Jonathan Austin 1:8aa5cdb4ab67 66
Jonathan Austin 1:8aa5cdb4ab67 67
Jonathan Austin 1:8aa5cdb4ab67 68 /**
Jonathan Austin 1:8aa5cdb4ab67 69 * Class definition for the MicroBitStorage class.
Jonathan Austin 1:8aa5cdb4ab67 70 * This allows reading and writing of small blocks of data to FLASH memory.
Jonathan Austin 1:8aa5cdb4ab67 71 *
Jonathan Austin 1:8aa5cdb4ab67 72 * This class operates as a key value store, it allows the retrieval, addition
Jonathan Austin 1:8aa5cdb4ab67 73 * and deletion of KeyValuePairs.
Jonathan Austin 1:8aa5cdb4ab67 74 *
Jonathan Austin 1:8aa5cdb4ab67 75 * The first 8 bytes are reserved for the KeyValueStore struct which gives core
Jonathan Austin 1:8aa5cdb4ab67 76 * information such as the number of KeyValuePairs in the store, and whether the
Jonathan Austin 1:8aa5cdb4ab67 77 * store has been initialised.
Jonathan Austin 1:8aa5cdb4ab67 78 *
Jonathan Austin 1:8aa5cdb4ab67 79 * After the KeyValueStore struct, KeyValuePairs are arranged contiguously until
Jonathan Austin 1:8aa5cdb4ab67 80 * the end of the block used as persistent storage.
Jonathan Austin 1:8aa5cdb4ab67 81 *
Jonathan Austin 1:8aa5cdb4ab67 82 * |-------8-------|--------48-------|-----|---------48--------|
Jonathan Austin 1:8aa5cdb4ab67 83 * | KeyValueStore | KeyValuePair[0] | ... | KeyValuePair[N-1] |
Jonathan Austin 1:8aa5cdb4ab67 84 * |---------------|-----------------|-----|-------------------|
Jonathan Austin 1:8aa5cdb4ab67 85 */
Jonathan Austin 1:8aa5cdb4ab67 86 class MicroBitStorage
Jonathan Austin 1:8aa5cdb4ab67 87 {
Jonathan Austin 1:8aa5cdb4ab67 88 /**
Jonathan Austin 1:8aa5cdb4ab67 89 * Function for copying words from one location to another.
Jonathan Austin 1:8aa5cdb4ab67 90 *
Jonathan Austin 1:8aa5cdb4ab67 91 * @param from the address to copy data from.
Jonathan Austin 1:8aa5cdb4ab67 92 *
Jonathan Austin 1:8aa5cdb4ab67 93 * @param to the address to copy the data to.
Jonathan Austin 1:8aa5cdb4ab67 94 *
Jonathan Austin 1:8aa5cdb4ab67 95 * @param sizeInWords the number of words to copy
Jonathan Austin 1:8aa5cdb4ab67 96 */
Jonathan Austin 1:8aa5cdb4ab67 97 void flashCopy(uint32_t* from, uint32_t* to, int sizeInWords);
Jonathan Austin 1:8aa5cdb4ab67 98
Jonathan Austin 1:8aa5cdb4ab67 99 /**
Jonathan Austin 1:8aa5cdb4ab67 100 * Function for populating the scratch page with a KeyValueStore.
Jonathan Austin 1:8aa5cdb4ab67 101 *
Jonathan Austin 1:8aa5cdb4ab67 102 * @param store the KeyValueStore struct to write to the scratch page.
Jonathan Austin 1:8aa5cdb4ab67 103 */
Jonathan Austin 1:8aa5cdb4ab67 104 void scratchKeyValueStore(KeyValueStore store);
Jonathan Austin 1:8aa5cdb4ab67 105
Jonathan Austin 1:8aa5cdb4ab67 106 /**
Jonathan Austin 1:8aa5cdb4ab67 107 * Function for populating the scratch page with a KeyValuePair.
Jonathan Austin 1:8aa5cdb4ab67 108 *
Jonathan Austin 1:8aa5cdb4ab67 109 * @param pair the KeyValuePair struct to write to the scratch page.
Jonathan Austin 1:8aa5cdb4ab67 110 *
Jonathan Austin 1:8aa5cdb4ab67 111 * @param flashPointer the pointer in flash where this KeyValuePair resides. This pointer
Jonathan Austin 1:8aa5cdb4ab67 112 * is used to determine the offset into the scratch page, where the KeyValuePair should
Jonathan Austin 1:8aa5cdb4ab67 113 * be written.
Jonathan Austin 1:8aa5cdb4ab67 114 */
Jonathan Austin 1:8aa5cdb4ab67 115 void scratchKeyValuePair(KeyValuePair pair, uint32_t* flashPointer);
Jonathan Austin 1:8aa5cdb4ab67 116
Jonathan Austin 1:8aa5cdb4ab67 117 public:
Jonathan Austin 1:8aa5cdb4ab67 118
Jonathan Austin 1:8aa5cdb4ab67 119 /**
Jonathan Austin 1:8aa5cdb4ab67 120 * Default constructor.
Jonathan Austin 1:8aa5cdb4ab67 121 *
Jonathan Austin 1:8aa5cdb4ab67 122 * Creates an instance of MicroBitStorage which acts like a KeyValueStore
Jonathan Austin 1:8aa5cdb4ab67 123 * that allows the retrieval, addition and deletion of KeyValuePairs.
Jonathan Austin 1:8aa5cdb4ab67 124 */
Jonathan Austin 1:8aa5cdb4ab67 125 MicroBitStorage();
Jonathan Austin 1:8aa5cdb4ab67 126
Jonathan Austin 1:8aa5cdb4ab67 127 /**
Jonathan Austin 1:8aa5cdb4ab67 128 * Writes the given number of bytes to the address specified.
Jonathan Austin 1:8aa5cdb4ab67 129 *
Jonathan Austin 1:8aa5cdb4ab67 130 * @param buffer the data to write.
Jonathan Austin 1:8aa5cdb4ab67 131 *
Jonathan Austin 1:8aa5cdb4ab67 132 * @param address the location in memory to write to.
Jonathan Austin 1:8aa5cdb4ab67 133 *
Jonathan Austin 1:8aa5cdb4ab67 134 * @param length the number of bytes to write.
Jonathan Austin 1:8aa5cdb4ab67 135 *
Jonathan Austin 1:8aa5cdb4ab67 136 * @note currently not implemented.
Jonathan Austin 1:8aa5cdb4ab67 137 */
Jonathan Austin 1:8aa5cdb4ab67 138 int writeBytes(uint8_t *buffer, uint32_t address, int length);
Jonathan Austin 1:8aa5cdb4ab67 139
Jonathan Austin 1:8aa5cdb4ab67 140 /**
Jonathan Austin 1:8aa5cdb4ab67 141 * Method for erasing a page in flash.
Jonathan Austin 1:8aa5cdb4ab67 142 *
Jonathan Austin 1:8aa5cdb4ab67 143 * @param page_address Address of the first word in the page to be erased.
Jonathan Austin 1:8aa5cdb4ab67 144 */
Jonathan Austin 1:8aa5cdb4ab67 145 void flashPageErase(uint32_t * page_address);
Jonathan Austin 1:8aa5cdb4ab67 146
Jonathan Austin 1:8aa5cdb4ab67 147 /**
Jonathan Austin 1:8aa5cdb4ab67 148 * Method for writing a word of data in flash with a value.
Jonathan Austin 1:8aa5cdb4ab67 149 *
Jonathan Austin 1:8aa5cdb4ab67 150 * @param address Address of the word to change.
Jonathan Austin 1:8aa5cdb4ab67 151 *
Jonathan Austin 1:8aa5cdb4ab67 152 * @param value Value to be written to flash.
Jonathan Austin 1:8aa5cdb4ab67 153 */
Jonathan Austin 1:8aa5cdb4ab67 154 void flashWordWrite(uint32_t * address, uint32_t value);
Jonathan Austin 1:8aa5cdb4ab67 155
Jonathan Austin 1:8aa5cdb4ab67 156 /**
Jonathan Austin 1:8aa5cdb4ab67 157 * Places a given key, and it's corresponding value into flash at the earliest
Jonathan Austin 1:8aa5cdb4ab67 158 * available point.
Jonathan Austin 1:8aa5cdb4ab67 159 *
Jonathan Austin 1:8aa5cdb4ab67 160 * @param key the unique name that should be used as an identifier for the given data.
Jonathan Austin 1:8aa5cdb4ab67 161 * The key is presumed to be null terminated.
Jonathan Austin 1:8aa5cdb4ab67 162 *
Jonathan Austin 1:8aa5cdb4ab67 163 * @param data a pointer to the beginning of the data to be persisted.
Jonathan Austin 1:8aa5cdb4ab67 164 *
LancasterUniversity 30:db87179335d5 165 * @param dataSize the size of the data to be persisted
LancasterUniversity 30:db87179335d5 166 *
LancasterUniversity 30:db87179335d5 167 * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if the key or size is too large,
LancasterUniversity 30:db87179335d5 168 * MICROBIT_NO_RESOURCES if the storage page is full
Jonathan Austin 1:8aa5cdb4ab67 169 */
LancasterUniversity 30:db87179335d5 170 int put(const char* key, uint8_t* data, int dataSize);
LancasterUniversity 30:db87179335d5 171
Jonathan Austin 1:8aa5cdb4ab67 172
Jonathan Austin 1:8aa5cdb4ab67 173 /**
Jonathan Austin 1:8aa5cdb4ab67 174 * Places a given key, and it's corresponding value into flash at the earliest
Jonathan Austin 1:8aa5cdb4ab67 175 * available point.
Jonathan Austin 1:8aa5cdb4ab67 176 *
Jonathan Austin 1:8aa5cdb4ab67 177 * @param key the unique name that should be used as an identifier for the given data.
Jonathan Austin 1:8aa5cdb4ab67 178 *
Jonathan Austin 1:8aa5cdb4ab67 179 * @param data a pointer to the beginning of the data to be persisted.
Jonathan Austin 1:8aa5cdb4ab67 180 *
LancasterUniversity 30:db87179335d5 181 * @param dataSize the size of the data to be persisted
LancasterUniversity 30:db87179335d5 182 *
LancasterUniversity 30:db87179335d5 183 * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if the key or size is too large,
LancasterUniversity 30:db87179335d5 184 * MICROBIT_NO_RESOURCES if the storage page is full
Jonathan Austin 1:8aa5cdb4ab67 185 */
LancasterUniversity 30:db87179335d5 186 int put(ManagedString key, uint8_t* data, int dataSize);
Jonathan Austin 1:8aa5cdb4ab67 187
Jonathan Austin 1:8aa5cdb4ab67 188 /**
Jonathan Austin 1:8aa5cdb4ab67 189 * Retreives a KeyValuePair identified by a given key.
Jonathan Austin 1:8aa5cdb4ab67 190 *
Jonathan Austin 1:8aa5cdb4ab67 191 * @param key the unique name used to identify a KeyValuePair in flash.
Jonathan Austin 1:8aa5cdb4ab67 192 *
Jonathan Austin 1:8aa5cdb4ab67 193 * @return a pointer to a heap allocated KeyValuePair struct, this pointer will be
Jonathan Austin 1:8aa5cdb4ab67 194 * NULL if the key was not found in storage.
Jonathan Austin 1:8aa5cdb4ab67 195 *
Jonathan Austin 1:8aa5cdb4ab67 196 * @note it is up to the user to free memory after use.
Jonathan Austin 1:8aa5cdb4ab67 197 */
Jonathan Austin 1:8aa5cdb4ab67 198 KeyValuePair* get(const char* key);
Jonathan Austin 1:8aa5cdb4ab67 199
Jonathan Austin 1:8aa5cdb4ab67 200 /**
Jonathan Austin 1:8aa5cdb4ab67 201 * Retreives a KeyValuePair identified by a given key.
Jonathan Austin 1:8aa5cdb4ab67 202 *
Jonathan Austin 1:8aa5cdb4ab67 203 * @param key the unique name used to identify a KeyValuePair in flash.
Jonathan Austin 1:8aa5cdb4ab67 204 *
Jonathan Austin 1:8aa5cdb4ab67 205 * @return a pointer to a heap allocated KeyValuePair struct, this pointer will be
Jonathan Austin 1:8aa5cdb4ab67 206 * NULL if the key was not found in storage.
Jonathan Austin 1:8aa5cdb4ab67 207 *
Jonathan Austin 1:8aa5cdb4ab67 208 * @note it is up to the user to free memory after use.
Jonathan Austin 1:8aa5cdb4ab67 209 */
Jonathan Austin 1:8aa5cdb4ab67 210 KeyValuePair* get(ManagedString key);
Jonathan Austin 1:8aa5cdb4ab67 211
Jonathan Austin 1:8aa5cdb4ab67 212 /**
Jonathan Austin 1:8aa5cdb4ab67 213 * Removes a KeyValuePair identified by a given key.
Jonathan Austin 1:8aa5cdb4ab67 214 *
Jonathan Austin 1:8aa5cdb4ab67 215 * @param key the unique name used to identify a KeyValuePair in flash.
Jonathan Austin 1:8aa5cdb4ab67 216 *
Jonathan Austin 1:8aa5cdb4ab67 217 * @return MICROBIT_OK on success, or MICROBIT_NO_DATA if the given key
Jonathan Austin 1:8aa5cdb4ab67 218 * was not found in flash.
Jonathan Austin 1:8aa5cdb4ab67 219 */
Jonathan Austin 1:8aa5cdb4ab67 220 int remove(const char* key);
Jonathan Austin 1:8aa5cdb4ab67 221
Jonathan Austin 1:8aa5cdb4ab67 222 /**
Jonathan Austin 1:8aa5cdb4ab67 223 * Removes a KeyValuePair identified by a given key.
Jonathan Austin 1:8aa5cdb4ab67 224 *
Jonathan Austin 1:8aa5cdb4ab67 225 * @param key the unique name used to identify a KeyValuePair in flash.
Jonathan Austin 1:8aa5cdb4ab67 226 *
Jonathan Austin 1:8aa5cdb4ab67 227 * @return MICROBIT_OK on success, or MICROBIT_NO_DATA if the given key
Jonathan Austin 1:8aa5cdb4ab67 228 * was not found in flash.
Jonathan Austin 1:8aa5cdb4ab67 229 */
Jonathan Austin 1:8aa5cdb4ab67 230 int remove(ManagedString key);
Jonathan Austin 1:8aa5cdb4ab67 231
Jonathan Austin 1:8aa5cdb4ab67 232 /**
Jonathan Austin 1:8aa5cdb4ab67 233 * The size of the flash based KeyValueStore.
Jonathan Austin 1:8aa5cdb4ab67 234 *
Jonathan Austin 1:8aa5cdb4ab67 235 * @return the number of entries in the key value store
Jonathan Austin 1:8aa5cdb4ab67 236 */
Jonathan Austin 1:8aa5cdb4ab67 237 int size();
Jonathan Austin 1:8aa5cdb4ab67 238 };
Jonathan Austin 1:8aa5cdb4ab67 239
LancasterUniversity 3:d86a4ddc1867 240 #endif