-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Converted EEPROM library to use nvs instead of partition. #2678
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
20f9f83
6a4b337
d3b9524
e262520
1c13541
ea34660
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
## EEPROM | ||
|
||
EEPROM is deprecated. For new applications on ESP32, use Preferences. EEPROM is provided for backwards compatibility with existing Arduino applications. | ||
EEPROM is implemented using a single blob within NVS, so it is a container within a container. As such, it is not going to be a high performance storage method. Preferences will directly use nvs, and store each entry as a single object therein. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,9 @@ | ||
/* | ||
EEPROM.h -ported by Paolo Becchi to Esp32 from esp8266 EEPROM | ||
-Modified by Elochukwu Ifediora <[email protected]> | ||
-Converted to nvs [email protected] | ||
|
||
Uses a one sector flash partition defined in partition table | ||
OR | ||
Multiple sector flash partitions defined by the name column in the partition table | ||
Uses a nvs byte array to emulate EEPROM | ||
|
||
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. | ||
This file is part of the esp8266 core for Arduino environment. | ||
|
@@ -28,36 +27,34 @@ | |
|
||
#include <esp_log.h> | ||
|
||
EEPROMClass::EEPROMClass(uint32_t sector) | ||
: _sector(sector) | ||
, _data(0) | ||
EEPROMClass::EEPROMClass(void) | ||
: _data(0) | ||
, _size(0) | ||
, _dirty(false) | ||
, _mypart(NULL) | ||
, _handle(NULL) | ||
, _name("eeprom") | ||
, _user_defined_size(0) | ||
{ | ||
} | ||
|
||
EEPROMClass::EEPROMClass(const char* name, uint32_t user_defined_size) | ||
: _sector(0) | ||
, _data(0) | ||
EEPROMClass::EEPROMClass(uint32_t sector) | ||
// Only for compatiility, no sectors in nvs! | ||
: _data(0) | ||
, _size(0) | ||
, _dirty(false) | ||
, _mypart(NULL) | ||
, _name(name) | ||
, _user_defined_size(user_defined_size) | ||
, _handle(NULL) | ||
, _name("eeprom") | ||
, _user_defined_size(0) | ||
{ | ||
} | ||
|
||
EEPROMClass::EEPROMClass(void) | ||
: _sector(0)// (((uint32_t)&_SPIFFS_end - 0x40200000) / SPI_FLASH_SEC_SIZE)) | ||
, _data(0) | ||
EEPROMClass::EEPROMClass(const char* name, uint32_t user_defined_size) | ||
: _data(0) | ||
, _size(0) | ||
, _dirty(false) | ||
, _mypart(NULL) | ||
, _name("eeprom") | ||
, _user_defined_size(0) | ||
, _handle(NULL) | ||
, _name(name) | ||
, _user_defined_size(user_defined_size) | ||
{ | ||
} | ||
|
||
|
@@ -66,31 +63,59 @@ EEPROMClass::~EEPROMClass() { | |
} | ||
|
||
bool EEPROMClass::begin(size_t size) { | ||
if (size <= 0) { | ||
return false; | ||
if (size <= 0) return false; | ||
|
||
esp_err_t res = nvs_open(_name, NVS_READWRITE, &_handle); | ||
if (res != ESP_OK) { | ||
log_e("Unable to open NVS namespace: %d", res); | ||
return false; | ||
} | ||
|
||
size_t key_size = 0; | ||
res = nvs_get_blob(_handle, _name, NULL, &key_size); | ||
if(res != ESP_OK && res != ESP_ERR_NVS_NOT_FOUND) { | ||
log_e("Unable to read NVS key: %d", res); | ||
return false; | ||
} | ||
if (size > SPI_FLASH_SEC_SIZE) { | ||
size = SPI_FLASH_SEC_SIZE; | ||
if (size < key_size) { // truncate | ||
log_w("truncating EEPROM from %d to %d", key_size, size); | ||
uint8_t* trunc_key = (uint8_t*) malloc(size); | ||
me-no-dev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
nvs_get_blob(_handle, _name, trunc_key, &size); | ||
nvs_set_blob(_handle, _name, trunc_key, size); | ||
nvs_commit(_handle); | ||
free(trunc_key); | ||
} | ||
// _mypart = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,ESP_PARTITION_SUBTYPE_ANY, EEPROM_FLASH_PARTITION_NAME); | ||
_mypart = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, _name); | ||
if (_mypart == NULL) { | ||
return false; | ||
if (size > key_size) { // expand or new | ||
me-no-dev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
size_t expand_size = size - key_size; | ||
uint8_t* expand_key = (uint8_t*) malloc(expand_size); | ||
me-no-dev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if(nvs_set_blob(_handle, "expand", expand_key, expand_size)) { | ||
log_e("Not enough space to expand EEPROM from %d to %d", key_size, size); | ||
free(expand_key); | ||
return false; | ||
} | ||
free(expand_key); | ||
nvs_erase_key(_handle, "expand"); | ||
uint8_t* hold_data = (uint8_t*) malloc(size); | ||
me-no-dev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
memset(hold_data, 0, size); | ||
if(key_size) { | ||
log_i("Expanding EEPROM from %d to %d", key_size, size); | ||
nvs_get_blob(_handle, _name, hold_data, &key_size); | ||
nvs_erase_key(_handle, _name); | ||
} | ||
nvs_commit(_handle); | ||
nvs_set_blob(_handle, _name, hold_data, size); | ||
free(hold_data); | ||
nvs_commit(_handle); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this whole block of code needs some comments to explain exactly what is going on :) I got lost with all those reads, writes and erases. What data is where... you need 2 blobs to hold the default 4K EEPROM, but reading through your code I got lost. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no way to expand a key, so in order to do so, it tests for free space, then holds the data while it deletes the key. If it is a new key, it just fills with zeros. I think changing the variable name to key_data will make it clearer. |
||
} | ||
size = (size + 3) & (~3); | ||
|
||
if (_data) { | ||
delete[] _data; | ||
} | ||
|
||
_data = new uint8_t[size]; | ||
_size = size; | ||
bool ret = false; | ||
if (esp_partition_read (_mypart, 0, (void *) _data, _size) == ESP_OK) { | ||
ret = true; | ||
} | ||
|
||
return ret; | ||
nvs_get_blob(_handle, _name, _data, &_size); | ||
return true; | ||
} | ||
|
||
void EEPROMClass::end() { | ||
|
@@ -134,29 +159,15 @@ void EEPROMClass::write(int address, uint8_t value) { | |
|
||
bool EEPROMClass::commit() { | ||
bool ret = false; | ||
if (!_size) | ||
return false; | ||
if (!_dirty) | ||
return true; | ||
if (!_data) | ||
return false; | ||
|
||
if (!_size) return false; | ||
if (!_data) return false; | ||
if (!_dirty) return true; | ||
|
||
if (esp_partition_erase_range(_mypart, 0, SPI_FLASH_SEC_SIZE) != ESP_OK) | ||
{ | ||
log_e( "partition erase err."); | ||
} | ||
else | ||
{ | ||
if (esp_partition_write(_mypart, 0, (void *)_data, _size) == ESP_ERR_INVALID_SIZE) | ||
{ | ||
log_e( "error in Write"); | ||
} | ||
else | ||
{ | ||
if (ESP_OK != nvs_set_blob(_handle, _name, _data, _size)) { | ||
log_e( "error in write"); | ||
} else { | ||
_dirty = false; | ||
ret = true; | ||
} | ||
} | ||
|
||
return ret; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,9 @@ | ||
/* | ||
EEPROM.h -ported by Paolo Becchi to Esp32 from esp8266 EEPROM | ||
-Modified by Elochukwu Ifediora <[email protected]> | ||
-Converted to nvs [email protected] | ||
|
||
Uses a one sector flash partition defined in partition table | ||
OR | ||
Multiple sector flash partitions defined by the name column in the partition table | ||
Uses a nvs byte array to emulate EEPROM | ||
|
||
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. | ||
This file is part of the esp8266 core for Arduino environment. | ||
|
@@ -30,19 +29,8 @@ | |
#define EEPROM_FLASH_PARTITION_NAME "eeprom" | ||
#endif | ||
#include <Arduino.h> | ||
extern "C" { | ||
|
||
#include <stddef.h> | ||
#include <stdint.h> | ||
#include <string.h> | ||
#include <esp_partition.h> | ||
} | ||
|
||
// | ||
// need to define AT LEAST a flash partition for EEPROM with above name | ||
// | ||
// eeprom , data , 0x99, start address, 0x1000 | ||
// | ||
#include <nvs.h> | ||
|
||
class EEPROMClass { | ||
public: | ||
EEPROMClass(uint32_t sector); | ||
|
@@ -117,11 +105,10 @@ class EEPROMClass { | |
template <class T> T writeAll (int address, const T &); | ||
|
||
protected: | ||
uint32_t _sector; | ||
nvs_handle _handle; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could you maybe forward declare the |
||
uint8_t* _data; | ||
size_t _size; | ||
bool _dirty; | ||
const esp_partition_t * _mypart; | ||
const char* _name; | ||
uint32_t _user_defined_size; | ||
}; | ||
|
Uh oh!
There was an error while loading. Please reload this page.