如何保存值从指针数组到结构体在EEPROM
How to save values from array of pointers to structs in EEPROM
我试图使用标准Arduino EEPROM- library Routine EEPROM.put()将4个结构体的所有值保存到我的ATMega328P EEPROM,并通过EEPROM.get()检索它们。我怎么能传递所有的值从我的value_table到这些函数?以下是我的数据。
typedef struct EXAMPLE {
uint8_t part1[7][2];
uint8_t part2[3];
} *ptr[5];
EXAMPLE VALUE_1 = {{
{1, 8},
{2, 9},
{3, 10},
{4, 11},
{5, 12},
{6, 13},
{7, 14}
},
{15, 16, 17}
};
在指针数组中有VALUE_1到VALUE_4四个版本。
struct EXAMPLE *value_table[] = {&VALUE_1, &VALUE_2, &VALUE_3, &VALUE_4};
这是我所提出的,但产生错误的结果。
EEPROM.put(0, &value_table); // 0 is first byte of EEPROM
EEPROM.get(0, value_table);
我想存储的是位于VALUE_1 - VALUE_4中的值,以使它们持久。
我非常感谢每一个提示!
只是猜测:
// writing (starting at some "eeprom_address" address)
int eeprom_address = 0;
EEPROM.put(eeprom_address + 0*sizeof(EXAMPLE), VALUE_1);
EEPROM.put(eeprom_address + 1*sizeof(EXAMPLE), VALUE_2);
EEPROM.put(eeprom_address + 2*sizeof(EXAMPLE), VALUE_3);
EEPROM.put(eeprom_address + 3*sizeof(EXAMPLE), VALUE_4);
// reading
EEPROM.get(eeprom_address + 0*sizeof(EXAMPLE), VALUE_1);
EEPROM.get(eeprom_address + 1*sizeof(EXAMPLE), VALUE_2);
EEPROM.get(eeprom_address + 2*sizeof(EXAMPLE), VALUE_3);
EEPROM.get(eeprom_address + 3*sizeof(EXAMPLE), VALUE_4);
// plus set the value_table in the same way as before
struct EXAMPLE *value_table[] = {&VALUE_1, &VALUE_2, &VALUE_3, &VALUE_4};
没有必要将指针存储到EEPROM中,你应该只存储数据值(但是以结构化的方式,这样你就知道哪个字节属于哪个数据项,并且可以将它们正确地读入目标变量)。
如果您想使用单个结构体,请执行struct EXAMPLE value_table[] = {VALUE_1, VALUE_2, VALUE_3, VALUE_4};
。但是这将把VALUE_1复制到value_table中,所以它将消耗两倍于只存在一个VALUE_1的内存。
顺便说一句,文档只是说"EEPROM。获取(地址,数据)"没有类型…这还是C/c++吗?:/*皱眉*
文档链接:get, put,还有struct
的例子
BTW: int
的地址只用作官方文档的副本,我个人永远不会使用int
的地址,当然,突然我的计划在某个遥远的未来点检查Arduino变得更加遥远。
使用for
变体书写:
constexpr size_t VALUES_N = 4;
struct EXAMPLE *value_table[] = {&VALUE_1, &VALUE_2, &VALUE_3, &VALUE_4};
// writing (starting at some "eeprom_address" address)
int eeprom_address = 0;
for (size_t i = 0; i < VALUES_N; ++i) {
EEPROM.put(eeprom_address + i*sizeof(EXAMPLE), *(value_table[i]));
}
// reading
for (size_t i = 0; i < VALUES_N; ++i) {
EEPROM.get(eeprom_address + i*sizeof(EXAMPLE), *(value_table[i]));
}
下载Arduino并查看get
和put
。正如预期的那样,它们被模板化了
template< typename T > T &get( int idx, T &t )
template< typename T > const T &put( int idx, const T &t )
因为它们有对模板定义类型的参数的引用,所以它们知道在EEPROM上执行读写操作所需的大小和几乎所有其他内容。
希望put
在写失败时抛出异常,因为我没有看到任何throw
或其他错误通知方法,但这不是这里的问题。
所以…
struct EXAMPLE *value_table[] = {&VALUE_1, &VALUE_2, &VALUE_3, &VALUE_4};
是一个包含4个指向结构体的指针的数组,而不是结构体本身。这意味着
sizeof(value_table);
将是指针大小的四倍,在Arduino上可能是16字节。但
EEPROM.put(0, &value_table);
甚至不会写这个。因为它传递了一个指向value_table
的指针,所有写入的都是一个指针,根据数组的工作方式,它将是指向第一个条目的指针,即指向要存储的数据的指针。
get
和put
通过引用获取数据,因此不需要显式地获取指针。不幸的是,因为模板将接受任何东西,所以编译器没有警告或错误来捕捉这个错误。
对于put
,您有两个选择:
EEPROM.put(0, VALUE_1 );
EEPROM.put(sizeof(VALUE_1), VALUE_2);
EEPROM.put(sizeof(VALUE_1)*2, VALUE_3);
...
EEPROM.put(sizeof(VALUE_1)*(N-1), VALUE_N);
或执行相同操作的循环,或将指向EXAMPLE结构体的指针表替换为EXAMPLE结构体的表。
struct EXAMPLE value_table[] =
{
{
{
{1, 8},
{2, 9},
{3, 10},
{4, 11},
{5, 12},
{6, 13},
{7, 14}
},
{15, 16, 17}
},
{
// contents of VALUE_2
},
{
// contents of VALUE_3
},
...
{
// contents of VALUE_N
}
}
VALUE_1
等…被丢弃。
可以使用value_table[x]
,其中x
的值为-1,或者定义
enum VALUES
{
VALUE_1 = 0,
VALUE_2,
VALUE_3,
...
VALUE_N
}
,并作为value_table[VALUE_1]
访问表。这种方法有点冗长,但更容易阅读。
对put
的调用与当前使用的类似,只是丢失了操作符的地址。
EEPROM.put(0, value_table);
使用get
将非常相似
EEPROM.get(0, VALUE_1 );
EEPROM.get(sizeof(VALUE_1), VALUE_2);
EEPROM.get(sizeof(VALUE_1)*2, VALUE_3);
...
EEPROM.get(sizeof(VALUE_1)*(N-1), VALUE_N);
或
EEPROM.get(0, value_table);
取决于选择处理put
的方法
- 添加到数组指针
- C++语法差异:二维和一维数组(指针算术)
- 数组指针表示法C++(移动数组时)
- 复制后删除原始数组指针将前 3 个字节设置为 0
- C++访问指向结构的指针中的类数组指针
- C++编译时使用 constexpr 字符数组指针分配静态数组?
- std::flush可以用于将对象指针转换为其封闭数组指针吗
- 创建<int>对整数数组指针的矢量引用 (C++)
- 将 2D 数组指针传递给 C++ 中的函数
- 创建指针是否超过非数组指针的末尾,而不是从 C++17 中的一元运算符和未定义的行为派生?
- 队列数组指针 (C++)
- C++数组指针上的删除操作
- 对于循环不循环和检测字符数组 [指针和字符数组]
- 如何初始化数组指针对象
- 如何正确传递 2D 数组指针作为参数
- 从数组指针中获取怪异的数字
- 初始化std :: unique_ptr作为原始数组指针的初始化
- 将结构数组指针从C#传递到C
- STD :: Sort将数组指针设置为NULL
- C++数组指针错误无法将“int*”转换为“int**”