如何将EEPROM.put和EEPROM.get封装在自己的函数中(Arduino/C/ESP8266)?
How to encapsulate EEPROM.put and EEPROM.get in own functions (Arduino / C / ESP8266)?
我想将 Arduino 函数 EEPROM.put 和 EEPROM.write 的用法封装在另一个函数中(它也开始和结束与 EEPROM 的通信),所以我创建了这两个函数:
void eeprom_save(uint addr, uint8_t *data, uint len) {
EEPROM.begin(len);
EEPROM.put(addr, *data);
EEPROM.commit();
EEPROM.end();
}
void eeprom_load(uint addr, uint8_t *data, uint len) {
EEPROM.begin(len);
EEPROM.get(addr, *data);
EEPROM.end();
}
我这样调用函数:
uint8_t scale_data[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
eeprom_save(0, scale_data, sizeof(scale_data));
// ... here is some code to clear the scale_data, to read back from EEPROM ...
eeprom_load(0, scale_data, sizeof(scale_data));
据我分析,它正确地将值保存到 EEPROM,但是用我的函数 eeprom_load 读取 EEPROM 不起作用(returns 只有 0、0 , 0, 0, 0, ...)
PS:我正在使用 ESP8266 内核 EEPROM implementation。
我想我在理解所使用的指针时遇到了一些困难?
如何解决?
恕我直言,class 无法处理数组(已经退化为指针)。所以你需要使用一个循环:
void eeprom_save(uint addr, uint8_t *data, uint len) {
EEPROM.begin(len);
for (uint i = 0; i < len; i++) {
EEPROM.put(addr + i, data[i]);
}
EEPROM.commit();
EEPROM.end();
}
void eeprom_load(uint addr, uint8_t *data, uint len) {
EEPROM.begin(len);
for (uint i = 0; i < len; i++) {
EEPROM.get(addr + i, data[i]);
}
EEPROM.end();
}
另一种选择是扩展 class 以处理数组。这是未经测试的,我以前从未使用过 class,但我认为它应该有效。
class MyEEPROMClass : public EEPROMClass {
public:
template<typename T>
T* get(int const address, T *t, size_t len) {
if (address < 0 || address + len > _size)
return t;
memcpy((uint8_t*)t, _data + address, len);
return t;
}
template<typename T>
const T* put(int const address, const T *t, size_t len) {
if (address < 0 || address + len > _size)
return t;
if (memcmp(_data + address, (const uint8_t*)t, len) != 0) {
_dirty = true;
memcpy(_data + address, (const uint8_t*)t, len);
}
return t;
}
};
我想将 Arduino 函数 EEPROM.put 和 EEPROM.write 的用法封装在另一个函数中(它也开始和结束与 EEPROM 的通信),所以我创建了这两个函数:
void eeprom_save(uint addr, uint8_t *data, uint len) {
EEPROM.begin(len);
EEPROM.put(addr, *data);
EEPROM.commit();
EEPROM.end();
}
void eeprom_load(uint addr, uint8_t *data, uint len) {
EEPROM.begin(len);
EEPROM.get(addr, *data);
EEPROM.end();
}
我这样调用函数:
uint8_t scale_data[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
eeprom_save(0, scale_data, sizeof(scale_data));
// ... here is some code to clear the scale_data, to read back from EEPROM ...
eeprom_load(0, scale_data, sizeof(scale_data));
据我分析,它正确地将值保存到 EEPROM,但是用我的函数 eeprom_load 读取 EEPROM 不起作用(returns 只有 0、0 , 0, 0, 0, ...)
PS:我正在使用 ESP8266 内核 EEPROM implementation。
我想我在理解所使用的指针时遇到了一些困难?
如何解决?
恕我直言,class 无法处理数组(已经退化为指针)。所以你需要使用一个循环:
void eeprom_save(uint addr, uint8_t *data, uint len) {
EEPROM.begin(len);
for (uint i = 0; i < len; i++) {
EEPROM.put(addr + i, data[i]);
}
EEPROM.commit();
EEPROM.end();
}
void eeprom_load(uint addr, uint8_t *data, uint len) {
EEPROM.begin(len);
for (uint i = 0; i < len; i++) {
EEPROM.get(addr + i, data[i]);
}
EEPROM.end();
}
另一种选择是扩展 class 以处理数组。这是未经测试的,我以前从未使用过 class,但我认为它应该有效。
class MyEEPROMClass : public EEPROMClass {
public:
template<typename T>
T* get(int const address, T *t, size_t len) {
if (address < 0 || address + len > _size)
return t;
memcpy((uint8_t*)t, _data + address, len);
return t;
}
template<typename T>
const T* put(int const address, const T *t, size_t len) {
if (address < 0 || address + len > _size)
return t;
if (memcmp(_data + address, (const uint8_t*)t, len) != 0) {
_dirty = true;
memcpy(_data + address, (const uint8_t*)t, len);
}
return t;
}
};