├── .gitattributes ├── .gitignore ├── LICENSE.txt ├── README.md ├── examples ├── simpleFlashNVS.ino └── uart-controlled.ino ├── keywords.txt ├── library.json ├── library.properties └── src ├── ArduinoNvs.cpp └── ArduinoNvs.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 Sinai RnD 2 | Copyright (c) 2016-2017 TridentTD 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Arduino NVS Library 2 | ========================== 3 | 4 | ## Summary 5 | Arduino NVS is a port for a non-volatile storage (NVS, flash) [library](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/storage/nvs_flash.html) for ESP32 to the Arduino Platform. It wraps main NVS functionality into the Arduino-styled C++ class. 6 | This lib is inspired and based on [TridentTD_ESP32NVS](https://github.com/TridentTD/TridentTD_ESP32NVS) work. This lib is a further development of it, contains a lot of improvements, bugfixes and translation (original text was published on [Thai](https://en.wikipedia.org/wiki/Thai_language)). 7 | 8 | 9 | 10 | ## Introduction 11 | 12 | NVS lib (commonly mentioned as *"flash lib"*) is a library used for storing data values in the flash memory in the ESP32. Data are stored in a non-volatile manner, so it is remaining in the memory after power-out or reboot of the ESP32. 13 | 14 | The ESP32 NVS stored data in the form of key-value. Keys are ASCII strings, up to 15 characters. Values can have one of the following types: 15 | 16 | - integer types: `uint8_t`, `int8_t`, `uint16_t`, `int16_t`, `uint32_t`, `int32_t`, `uint64_t`, `int64_t` 17 | - zero-terminated string 18 | - variable length binary data (blob) 19 | 20 | Refer to the NVS ESP32 lib [original documentation](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/storage/nvs_flash.html#internals) for a details about internal NVS lib organization. 21 | 22 | 23 | 24 | ## Usage 25 | 26 | Include the library header: ` #include ` 27 | 28 | Then init the NVS with the command: `NVS.begin();` 29 | 30 |    31 | 32 | ### Save data in NVS 33 | 34 | 35 | ```c++ 36 | bool ok; 37 | ok = NVS.setInt ("myInt", 23); // Stores the integer value 23 into the key named "myInt" on the NVS 38 | 39 | String data1 = "Hello String"; 40 | ok = NVS.setString ("myString", data); // Store the data value into the key named "myString" on the NVS 41 | ``` 42 | 43 | 44 | ### Load data from NVS 45 | 46 | ```c++ 47 | int i = NVS.getInt ("myInt"); // Read the value of the key "myInt" from the NVS 48 | 49 | String str = NVS.getString ("myString"); // Read the value of the "myString" key from the NVS 50 | ``` 51 | 52 | 53 | ### Binary-like Objects ### 54 | 55 | Storing variables other than the basic types are performed through serializing it to the blob/array form (std::vector is recommended). 56 | 57 | #### Store blob 58 | ```c++ 59 | uint8_t mac [6] = {0xDF, 0xEE, 0x10, 0x49, 0xA1, 0x42}; 60 | bool ok = NVS.setBlob("mac", f, sizeof(f)); // store mac [6] to key "MAC" on NVS 61 | ``` 62 | 63 | #### Load blob 64 | ```c++ 65 | size_t blobLength = NVS.getBlobSize("mac"); // retrievenig size of stored blob 66 | uint8_t mymac[blobLength]; 67 | bool ok = NVS.getBlob("mac", mymac, sizeof(mymac)); 68 | Serial.printf ("mac:% 02X:% 02X:% 02X:% 02X:% 02X:% 02X \ n", 69 |                mymac [1], mymac [2], mymac [3], mymac [4], mymac [5]);               70 | ``` 71 | 72 | 73 | 74 | ## Namespaces 75 | 76 | ArduinoNvs Library suports ESP32 [Namespaces](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/storage/nvs_flash.html#namespaces) 77 | 78 | The default namespace is `"storage"`. To store data in the separate namaspace, use its name in the `begin()` parameter: 79 | 80 | ```c++ 81 | ArduinoNvs mynvs; 82 | mynvs.begin("customNs"); 83 | ``` 84 | 85 | All subsequent store/load with `mynvs` object will be performed in `"customNs"` namespace: 86 | ```c++ 87 | String dataSt = "Namespace String"; 88 | mynvs.setString ("myString", dataSt); // this string is stored in "customNs" namespace 89 | ``` 90 | 91 | ## Authors 92 | 1. dRKr, Sinai RnD () 93 | 2. (original version) TridentTD (https://github.com/TridentTD/) -------------------------------------------------------------------------------- /examples/simpleFlashNVS.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ArduinoNvs.h" 3 | 4 | /** 5 | * Arduino NVS is a port for a non-volatile storage (NVS, flash) library for ESP32 to the Arduino Platform. 6 | * It wraps main NVS functionality into the Arduino-styled C++ class. 7 | */ 8 | 9 | bool res; 10 | 11 | void setup() { 12 | NVS.begin(); 13 | } 14 | 15 | 16 | void loop() { 17 | /*** Int ***/ 18 | // write to flash 19 | const uint64_t ui64_set = 0x1122334455667788; 20 | res = NVS.setInt("longInt", ui64_set); 21 | // read from flash 22 | uint64_t uui64 = NVS.getInt("longInt"); 23 | 24 | 25 | /*** String ***/ 26 | // write to flash 27 | const String st_set = "`simple plain string`"; 28 | res = NVS.setString("st", st_set); 29 | // read from flash 30 | String st = NVS.getString("st"); 31 | 32 | /*** BLOB ***/ 33 | //write to flash 34 | uint8_t blolb_set[] = {1,2,3,99,100, 0xEE, 0xFE, 0xEE}; 35 | res = NVS.setBlob("blob", blolb_set, sizeof(blolb_set)); 36 | // read from flash 37 | size_t blobLength = NVS.getBlobSize("blob"); 38 | uint8_t blob[blobLength]; 39 | res = NVS.getBlob("blob", blob, sizeof(blob)); 40 | 41 | delay(1000); 42 | } 43 | -------------------------------------------------------------------------------- /examples/uart-controlled.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ArduinoNvs.h" 3 | 4 | /** 5 | * Arduino NVS is a port for a non-volatile storage (NVS, flash) library for ESP32 to the Arduino Platform. 6 | * It wraps main NVS functionality into the Arduino-styled C++ class. 7 | */ 8 | 9 | using namespace std; 10 | 11 | #define PRINT(...) Serial.print(__VA_ARGS__) 12 | #define PRINTLN(...) Serial.println(__VA_ARGS__) 13 | #define PRINTF(...) Serial.printf(__VA_ARGS__) 14 | 15 | #define DEBUG(...) {Serial.print(__FUNCTION__);Serial.print("() ["); \ 16 | Serial.print(__FILE__); Serial.print(":");Serial.print(__LINE__); Serial.print("]:\t"); \ 17 | Serial.printf(__VA_ARGS__);Serial.println();} 18 | 19 | 20 | void printHex(uint8_t* data, size_t len, String startLine = "\n", String endLine = "\n"); 21 | void printHex(vector& data, String startLine = "\n", String endLine = "\n"); 22 | 23 | ArduinoNvs nvs; 24 | ArduinoNvs nvss; 25 | 26 | void setup() { 27 | Serial.begin(115200); 28 | 29 | NVS.begin(); 30 | nvs.begin("store"); 31 | nvss.begin("upstore"); 32 | } 33 | 34 | void loop() { 35 | if (Serial.available()) { 36 | char cmd = Serial.read(); 37 | bool ok; 38 | switch (cmd) { 39 | case '1': { 40 | size_t blobL = NVS.getBlobSize("blob"); 41 | DEBUG("1. Blob size: %d", blobL); 42 | uint8_t resp[blobL]; 43 | ok = NVS.getBlob("blob", resp, sizeof(resp)); 44 | DEBUG("1. NVS: res = %d, blob addr: %X, size %X", ok, (int32_t)&resp[0], sizeof(resp)); 45 | printHex(resp, blobL); 46 | } break; 47 | case '2': { 48 | vector respNvs; 49 | ok = nvs.getBlob("blob", respNvs); 50 | DEBUG("2. nvs: res = %d, blob addr: %X, size %X", ok, (int32_t)&respNvs[0], respNvs.size()); 51 | printHex(respNvs); 52 | } break; 53 | case '3': { 54 | vector respNvss; 55 | respNvss = nvss.getBlob("blob"); 56 | DEBUG("3. nvss: blob addr: %X, size %X", (int32_t)&respNvss[0], respNvss.size()); 57 | printHex(respNvss); 58 | } break; 59 | case '4': { 60 | float ff = nvss.getFloat("fl"); 61 | DEBUG("4. nvss: float: %f", ff); 62 | } break; 63 | case '5': { 64 | String stst = nvss.getString("st"); 65 | DEBUG("5. nvss: stst %s", stst.c_str()); 66 | } break; 67 | case '6': { 68 | uint64_t uui64 = nvss.getInt("ui64"); 69 | DEBUG("6. nvss: ui64 %llu", uui64); 70 | } break; 71 | case '7': { 72 | int64_t ii64 = nvss.getInt("i64"); 73 | DEBUG("7. nvss: i64 %lli", ii64); 74 | } break; 75 | case 'w': { 76 | bool res; 77 | NVS.setInt("u8", (uint8_t)0xDEADBEEF); 78 | NVS.setInt("u16", (uint16_t)0xDEADBEEF); 79 | NVS.setInt("u32", (uint32_t)0xDEADBEEF); 80 | NVS.setString("str", "worked!"); 81 | uint8_t f[] = {1,2,3,99,100, 0xEE, 0xFE, 0xEE}; 82 | res = NVS.setBlob("blob", f, sizeof(f)); 83 | DEBUG("1. res setObject = %s", ((res)?"true":"false") ); 84 | 85 | f[0] = 2; 86 | res = nvs.setBlob("blob", f, sizeof(f)); 87 | DEBUG("2. res setObject = %s", ((res)?"true":"false") ); 88 | 89 | f[sizeof(f)-1] = 0xAA; 90 | res = nvss.setBlob("blob", f, sizeof(f)); 91 | DEBUG("3. res setObject = %s", ((res)?"true":"false") ); 92 | 93 | float fl = 0.12345678e5; 94 | res = nvss.setFloat("fl", fl, false); 95 | DEBUG("4. fl res = %d", res); 96 | 97 | const char* st = "`ha\nha\nha\tha\tha`"; 98 | res = nvss.setString("st", st, false); 99 | DEBUG("5. st res = %d", res); 100 | 101 | uint64_t ui64 = 0xFFEEAABBCCDDEEFF; 102 | res = nvss.setInt("ui64", ui64, false); 103 | DEBUG("6. st res = %d", res); 104 | 105 | res = nvss.setInt("i64", (int64_t)ui64, false); 106 | DEBUG("7. st res = %d", res); 107 | 108 | 109 | res = nvss.commit(); 110 | DEBUG("0. commit = %d", res); 111 | } break; 112 | case 'e': { 113 | bool res = NVS.eraseAll(); 114 | DEBUG("NVS erase res = %d", res); 115 | } break; 116 | case 'r': { 117 | bool res = nvs.eraseAll(); 118 | DEBUG("nvs erase res = %d", res); 119 | } break; 120 | case 't': { 121 | bool res = nvss.eraseAll(); 122 | DEBUG("nvss erase res = %d", res); 123 | } break; 124 | 125 | case 'd': { 126 | bool res = nvss.erase("st"); 127 | DEBUG("nvss st erase res = %d", res); 128 | } break; 129 | 130 | case 'k': { 131 | bool res; 132 | float fl = 0.87654321e5; 133 | res = nvss.setFloat("fl", fl); 134 | DEBUG("4. fl res = %d", res); 135 | 136 | const char* st = "`simple plain string`"; 137 | res = nvss.setString("st", st); 138 | DEBUG("5. st res = %d", res); 139 | 140 | uint64_t ui64 = 0x1122334455667788; 141 | res = nvss.setInt("ui64", ui64); 142 | DEBUG("6. st res = %d", res); 143 | } break; 144 | 145 | } 146 | } 147 | } 148 | 149 | 150 | void printHex(uint8_t* data, size_t len, String startLine, String endLine) { 151 | PRINT(startLine); 152 | for (uint8_t i = 0; i < len; i++) { 153 | PRINTF("%02X,", data[i]); 154 | } 155 | PRINT(endLine); 156 | } 157 | 158 | void printHex(vector& data, String startLine, String endLine) { 159 | printHex(&data[0], data.size(), startLine, endLine); 160 | } -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For Ultrasound 3 | ####################################### 4 | ####################################### 5 | # Library (KEYWORD3) 6 | ####################################### 7 | 8 | TridentTD_ESP32NVS KEYWORD3 9 | 10 | ####################################### 11 | # Datatypes (KEY 12 | ####################################### 13 | 14 | NVS KEYWORD1 15 | 16 | ####################################### 17 | # Methods and Functions (KEYWORD2) 18 | ####################################### 19 | 20 | begin KEYWORD2 21 | close KEYWORD2 22 | 23 | eraseAll KEYWORD2 24 | erase KEYWORD2 25 | 26 | setInt KEYWORD2 27 | setFloat KEYWORD2 28 | setCharArray KEYWORD2 29 | setString KEYWORD2 30 | setObject KEYWORD2 31 | 32 | getInt KEYWORD2 33 | getFloat KEYWORD2 34 | getCharArray KEYWORD2 35 | getString KEYWORD2 36 | getObject KEYWORD2 37 | 38 | 39 | ####################################### 40 | # Constants (LITERAL1) 41 | ####################################### 42 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ArduinoNvs", 3 | "keywords": "NVS, ESP32, Non-volatile storage", 4 | "description": "Arduino wrapper for ESP32 NVS (Non-volatile storage)", 5 | "homepage": "https://github.com/rpolitex/ArduinoNvs", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/rpolitex/ArduinoNvs" 9 | }, 10 | "version": "2.10", 11 | "authors": [ 12 | { 13 | "name": "dRKr", 14 | "email": "info@sinai.io", 15 | "url": "https://www.sinai.io", 16 | "maintainer": true 17 | } 18 | ], 19 | "frameworks": "arduino", 20 | "platforms": ["esp32", "espressif32"] 21 | } 22 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=ArduinoNvs 2 | version=2.10 3 | author=dRKr 4 | maintainer=SinaiRnD 5 | sentence=Arduino wrapper for ESP32 NVS (Non-volatile storage) 6 | paragraph= 7 | category=Communication 8 | url=https://github.com/rpolitex/ArduinoNvs 9 | architectures=esp32 10 | -------------------------------------------------------------------------------- /src/ArduinoNvs.cpp: -------------------------------------------------------------------------------- 1 | // ArduinoNvs.cpp 2 | 3 | // Copyright (c) 2018 Sinai RnD 4 | // Copyright (c) 2016-2017 TridentTD 5 | 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #include "ArduinoNvs.h" 25 | 26 | ArduinoNvs::ArduinoNvs() 27 | { 28 | } 29 | 30 | esp_err_t ArduinoNvs::_init(nvs_sec_cfg_t *keys) 31 | { 32 | // If encryption is supported - make additional moves for retrieving keys: 33 | // - try to use user-provided keys if any, OR 34 | // - check is keypartition present, if no - as a last hope - try to open NVS in non-encrypted mode 35 | #ifdef CONFIG_NVS_ENCRYPTION 36 | bool noKeyPartition = ( NULL == esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS_KEYS, NULL) ); 37 | 38 | if (keys) 39 | { 40 | return nvs_flash_secure_init(keys); 41 | } 42 | else if (noKeyPartition) 43 | { 44 | DEBUG_PRINTLN("W: You are trying to open Non-encrypted NVS on Encryption-enabled system. Maybe something is miscofigured"); 45 | return nvs_flash_init_partition(NVS_DEFAULT_PART_NAME); 46 | } 47 | #endif 48 | 49 | // in all other cases use usual init process 50 | return nvs_flash_init(); 51 | } 52 | 53 | bool ArduinoNvs::begin(String namespaceNvs) 54 | { 55 | return begin(namespaceNvs, NULL); 56 | } 57 | 58 | bool ArduinoNvs::begin(String namespaceNvs, nvs_sec_cfg_t *keys) 59 | { 60 | esp_err_t err = _init(keys); 61 | if (err != ESP_OK) 62 | { 63 | DEBUG_PRINTLN("W: NVS. Cannot init flash mem"); 64 | if (err != ESP_ERR_NVS_NO_FREE_PAGES) 65 | return false; 66 | 67 | // erase and reinit 68 | DEBUG_PRINTLN("NVS. Try reinit the partition"); 69 | err = format(); 70 | if (err) 71 | return false; 72 | err = _init(keys); 73 | if (err) 74 | return false; 75 | DEBUG_PRINTLN("NVS. Partition re-formatted"); 76 | } 77 | 78 | err = nvs_open(namespaceNvs.c_str(), NVS_READWRITE, &_nvs_handle); 79 | if (err != ESP_OK) 80 | return false; 81 | 82 | return true; 83 | } 84 | 85 | bool ArduinoNvs::format() { 86 | const esp_partition_t *nvs_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL); 87 | if (nvs_partition == NULL) { 88 | DEBUG_PRINTLN("E: NVS. No NVS partition"); 89 | return false; 90 | } 91 | esp_err_t err = esp_partition_erase_range(nvs_partition, 0, nvs_partition->size); 92 | if (err != ESP_OK) 93 | DEBUG_PRINTF("E: NVS. Cannot format the partition [%d]\n", err); 94 | return err == ESP_OK; 95 | } 96 | 97 | bool ArduinoNvs::close(bool deinit_partition) 98 | { 99 | nvs_close(_nvs_handle); 100 | if (deinit_partition == false) 101 | return true; 102 | 103 | // deinit parttion if needed 104 | esp_err_t err = nvs_flash_deinit(); 105 | if (err != ESP_OK) 106 | DEBUG_PRINTF("W: NVS. Cannot deinit the partition [%d]\n", err); 107 | 108 | return err == ESP_OK; 109 | } 110 | 111 | bool ArduinoNvs::eraseAll(bool forceCommit) 112 | { 113 | esp_err_t err = nvs_erase_all(_nvs_handle); 114 | if (err != ESP_OK) 115 | return false; 116 | return forceCommit ? commit() : true; 117 | } 118 | 119 | bool ArduinoNvs::erase(String key, bool forceCommit) 120 | { 121 | esp_err_t err = nvs_erase_key(_nvs_handle, key.c_str()); 122 | if (err != ESP_OK) 123 | return false; 124 | return forceCommit ? commit() : true; 125 | } 126 | 127 | bool ArduinoNvs::commit() 128 | { 129 | esp_err_t err = nvs_commit(_nvs_handle); 130 | if (err != ESP_OK) 131 | return false; 132 | return true; 133 | } 134 | 135 | bool ArduinoNvs::setInt(String key, uint8_t value, bool forceCommit) 136 | { 137 | esp_err_t err = nvs_set_u8(_nvs_handle, (char *)key.c_str(), value); 138 | if (err != ESP_OK) 139 | return false; 140 | return forceCommit ? commit() : true; 141 | } 142 | 143 | bool ArduinoNvs::setInt(String key, int16_t value, bool forceCommit) 144 | { 145 | esp_err_t err = nvs_set_i16(_nvs_handle, (char *)key.c_str(), value); 146 | if (err != ESP_OK) 147 | return false; 148 | return forceCommit ? commit() : true; 149 | } 150 | 151 | bool ArduinoNvs::setInt(String key, uint16_t value, bool forceCommit) 152 | { 153 | esp_err_t err = nvs_set_u16(_nvs_handle, (char *)key.c_str(), value); 154 | if (err != ESP_OK) 155 | return false; 156 | return forceCommit ? commit() : true; 157 | } 158 | 159 | bool ArduinoNvs::setInt(String key, int32_t value, bool forceCommit) 160 | { 161 | esp_err_t err = nvs_set_i32(_nvs_handle, (char *)key.c_str(), value); 162 | if (err != ESP_OK) 163 | return false; 164 | return forceCommit ? commit() : true; 165 | } 166 | 167 | bool ArduinoNvs::setInt(String key, uint32_t value, bool forceCommit) 168 | { 169 | esp_err_t err = nvs_set_u32(_nvs_handle, (char *)key.c_str(), value); 170 | if (err != ESP_OK) 171 | return false; 172 | return forceCommit ? commit() : true; 173 | } 174 | bool ArduinoNvs::setInt(String key, int64_t value, bool forceCommit) 175 | { 176 | esp_err_t err = nvs_set_i64(_nvs_handle, (char *)key.c_str(), value); 177 | if (err != ESP_OK) 178 | return false; 179 | return forceCommit ? commit() : true; 180 | } 181 | 182 | bool ArduinoNvs::setInt(String key, uint64_t value, bool forceCommit) 183 | { 184 | esp_err_t err = nvs_set_u64(_nvs_handle, (char *)key.c_str(), value); 185 | if (err != ESP_OK) 186 | return false; 187 | return forceCommit ? commit() : true; 188 | } 189 | 190 | bool ArduinoNvs::setString(String key, String value, bool forceCommit) 191 | { 192 | esp_err_t err = nvs_set_str(_nvs_handle, (char *)key.c_str(), value.c_str()); 193 | if (err != ESP_OK) 194 | return false; 195 | return forceCommit ? commit() : true; 196 | } 197 | 198 | bool ArduinoNvs::setBlob(String key, uint8_t *blob, size_t length, bool forceCommit) 199 | { 200 | DEBUG_PRINTF("ArduinoNvs::setObjct(): set obj addr = [0x%X], length = [%d]\n", (int32_t)blob, length); 201 | if (length == 0) 202 | return false; 203 | esp_err_t err = nvs_set_blob(_nvs_handle, (char *)key.c_str(), blob, length); 204 | if (err) 205 | { 206 | DEBUG_PRINTF("ArduinoNvs::setObjct(): err = [0x%X]\n", err); 207 | return false; 208 | } 209 | return forceCommit ? commit() : true; 210 | } 211 | 212 | bool ArduinoNvs::setBlob(String key, std::vector &blob, bool forceCommit) 213 | { 214 | return setBlob(key, &blob[0], blob.size(), forceCommit); 215 | } 216 | 217 | int64_t ArduinoNvs::getInt(String key, int64_t default_value) 218 | { 219 | uint8_t v_u8; 220 | int16_t v_i16; 221 | uint16_t v_u16; 222 | int32_t v_i32; 223 | uint32_t v_u32; 224 | int64_t v_i64; 225 | uint64_t v_u64; 226 | 227 | esp_err_t err; 228 | err = nvs_get_u8(_nvs_handle, (char *)key.c_str(), &v_u8); 229 | if (err == ESP_OK) 230 | return (int64_t)v_u8; 231 | 232 | err = nvs_get_i16(_nvs_handle, (char *)key.c_str(), &v_i16); 233 | if (err == ESP_OK) 234 | return (int64_t)v_i16; 235 | 236 | err = nvs_get_u16(_nvs_handle, (char *)key.c_str(), &v_u16); 237 | if (err == ESP_OK) 238 | return (int64_t)v_u16; 239 | 240 | err = nvs_get_i32(_nvs_handle, (char *)key.c_str(), &v_i32); 241 | if (err == ESP_OK) 242 | return (int64_t)v_i32; 243 | 244 | err = nvs_get_u32(_nvs_handle, (char *)key.c_str(), &v_u32); 245 | if (err == ESP_OK) 246 | return (int64_t)v_u32; 247 | 248 | err = nvs_get_i64(_nvs_handle, (char *)key.c_str(), &v_i64); 249 | if (err == ESP_OK) 250 | return (int64_t)v_i64; 251 | 252 | err = nvs_get_u64(_nvs_handle, (char *)key.c_str(), &v_u64); 253 | if (err == ESP_OK) 254 | return (int64_t)v_u64; 255 | 256 | return default_value; 257 | } 258 | 259 | bool ArduinoNvs::getString(String key, String &res) 260 | { 261 | size_t required_size; 262 | esp_err_t err; 263 | 264 | err = nvs_get_str(_nvs_handle, key.c_str(), NULL, &required_size); 265 | if (err) 266 | return false; 267 | 268 | char value[required_size]; 269 | err = nvs_get_str(_nvs_handle, key.c_str(), value, &required_size); 270 | if (err) 271 | return false; 272 | res = value; 273 | return true; 274 | } 275 | 276 | String ArduinoNvs::getString(String key, const char* default_value) { 277 | String res; 278 | bool ok = getString(key, res); 279 | if (!ok) 280 | return String(default_value); 281 | return res; 282 | } 283 | 284 | size_t ArduinoNvs::getBlobSize(String key) 285 | { 286 | size_t required_size; 287 | esp_err_t err = nvs_get_blob(_nvs_handle, key.c_str(), NULL, &required_size); 288 | if (err) 289 | { 290 | if (err != ESP_ERR_NVS_NOT_FOUND) // key_not_found is not an error, just return size 0 291 | DEBUG_PRINTF("ArduinoNvs::getBlobSize(): err = [0x%X]\n", err); 292 | return 0; 293 | } 294 | return required_size; 295 | } 296 | 297 | bool ArduinoNvs::getBlob(String key, uint8_t *blob, size_t length) 298 | { 299 | if (length == 0) 300 | return false; 301 | 302 | size_t required_size = getBlobSize(key); 303 | if (required_size == 0) 304 | return false; 305 | if (length < required_size) 306 | return false; 307 | 308 | esp_err_t err = nvs_get_blob(_nvs_handle, key.c_str(), blob, &required_size); 309 | if (err) 310 | { 311 | DEBUG_PRINTF("ArduinoNvs::getBlob(): get object err = [0x%X]\n", err); 312 | return false; 313 | } 314 | return true; 315 | } 316 | 317 | bool ArduinoNvs::getBlob(String key, std::vector &blob) 318 | { 319 | size_t required_size = getBlobSize(key); 320 | if (required_size == 0) 321 | return false; 322 | 323 | blob.resize(required_size); 324 | esp_err_t err = nvs_get_blob(_nvs_handle, key.c_str(), &blob[0], &required_size); 325 | if (err) 326 | { 327 | DEBUG_PRINTF("ArduinoNvs::getBlob(): get object err = [0x%X]\n", err); 328 | return false; 329 | } 330 | return true; 331 | } 332 | 333 | std::vector ArduinoNvs::getBlob(String key) 334 | { 335 | std::vector res; 336 | bool ok = getBlob(key, res); 337 | if (!ok) 338 | res.clear(); 339 | return res; 340 | } 341 | 342 | bool ArduinoNvs::setFloat(String key, float value, bool forceCommit) 343 | { 344 | return setBlob(key, (uint8_t *)&value, sizeof(float), forceCommit); 345 | } 346 | 347 | float ArduinoNvs::getFloat(String key, float default_value) 348 | { 349 | std::vector res(sizeof(float)); 350 | if (!getBlob(key, res)) 351 | return default_value; 352 | return *(float *)(&res[0]); 353 | } 354 | 355 | ArduinoNvs NVS; 356 | -------------------------------------------------------------------------------- /src/ArduinoNvs.h: -------------------------------------------------------------------------------- 1 | // ArduinoNvs.h 2 | 3 | // Copyright (c) 2018 Sinai RnD 4 | // Copyright (c) 2016-2017 TridentTD 5 | 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #ifndef __ARDUINO_NVS_H__ 25 | #define __ARDUINO_NVS_H__ 26 | 27 | #include 28 | #include 29 | 30 | extern "C" { 31 | #include "esp_partition.h" 32 | #include "esp_err.h" 33 | #include "nvs_flash.h" 34 | #include "nvs.h" 35 | } 36 | 37 | #ifndef ARDUINONVS_SILENT 38 | #define ARDUINONVS_SILENT 0 39 | #endif 40 | 41 | #if ARDUINONVS_SILENT 42 | #define DEBUG_PRINT(...) { } 43 | #define DEBUG_PRINTLN(...) { } 44 | #define DEBUG_PRINTF(fmt, args...) { } 45 | #else 46 | #ifndef ANVS_DEBUG_PRINTER 47 | #define ANVS_DEBUG_PRINTER Serial 48 | #endif 49 | #define DEBUG_PRINT(...) { ANVS_DEBUG_PRINTER.print(__VA_ARGS__); } 50 | #define DEBUG_PRINTLN(...) { ANVS_DEBUG_PRINTER.println(__VA_ARGS__); } 51 | #define DEBUG_PRINTF(fmt, args...) { ANVS_DEBUG_PRINTER.printf(fmt,## args); } 52 | #endif 53 | 54 | class ArduinoNvs { 55 | public: 56 | ArduinoNvs(); 57 | 58 | bool begin(String namespaceNvs = "storage"); 59 | bool begin(String namespaceNvs, nvs_sec_cfg_t *keys); /// use only for that rare cases, when you do not have NVS Key Partition, and store keys in external secure storage (or hardcode). See https://docs.espressif.com/projects/esp-idf/en/release-v5.0/esp32/api-reference/storage/nvs_flash.html#encrypted-read-write 60 | 61 | bool close(bool deinit_partition = false); 62 | 63 | bool eraseAll(bool forceCommit = true); 64 | bool erase(String key, bool forceCommit = true); 65 | 66 | bool setInt(String key, uint8_t value, bool forceCommit = true); 67 | bool setInt(String key, int16_t value, bool forceCommit = true); 68 | bool setInt(String key, uint16_t value, bool forceCommit = true); 69 | bool setInt(String key, int32_t value, bool forceCommit = true); 70 | bool setInt(String key, uint32_t value, bool forceCommit = true); 71 | bool setInt(String key, int64_t value, bool forceCommit = true); 72 | bool setInt(String key, uint64_t value, bool forceCommit = true); 73 | bool setFloat(String key, float value, bool forceCommit = true); 74 | bool setString(String key, String value, bool forceCommit = true); 75 | bool setBlob(String key, uint8_t* blob, size_t length, bool forceCommit = true); 76 | bool setBlob(String key, std::vector& blob, bool forceCommit = true); 77 | 78 | int64_t getInt(String key, int64_t default_value = 0); // In case of error, default_value will be returned 79 | float getFloat(String key, float default_value = 0); 80 | 81 | bool getString(String key, String& res); 82 | String getString(String key, const char* default_value = ""); 83 | 84 | size_t getBlobSize(String key); /// Returns the size of the stored blob 85 | bool getBlob(String key, uint8_t* blob, size_t length); /// User should proivde enought memory to store the loaded blob. If length < than required size to store blob, function fails. 86 | bool getBlob(String key, std::vector& blob); 87 | std::vector getBlob(String key); /// Less eficient but more simple in usage implemetation of `getBlob()` 88 | 89 | bool commit(); 90 | static bool format(); /// Format NVS parttion. WARNING: DESTROYS ALL NVS DATA! 91 | 92 | protected: 93 | nvs_handle _nvs_handle; 94 | esp_err_t _init(nvs_sec_cfg_t *cfg); 95 | }; 96 | 97 | extern ArduinoNvs NVS; 98 | 99 | #endif 100 | --------------------------------------------------------------------------------