将struct成员写入内存的通用接口模式?

时间:2016-10-12 12:37:14

标签: c memory struct embedded

我正在使用具有一些外部非易失性存储器的嵌入式设备(无操作系统)。

我在NV内存中存储单个结构数据的多个副本。我读取并写入内存中的数据作为整个结构作为单个成员。

目前我有一个有效的实施方案。当处理内存操作的模块被初始化时,它被赋予RAM中的结构的位置,它作为其上下文的一部分存储。这意味着当涉及读取和写入单个成员时,它可以通过从成员的位置减去前面提到的位置来计算成员的偏移量。然后它使用此偏移量来知道在NV存储器中找到副本的位置。

e.g。在伪代码中:

init:
    wm_ram = pointer to working memory struct start in RAM;

write to a member from the member in RAM:
    offset = working memory member location in RAM - wm_ram;
    sector address = address of selected copy of struct in NV to write to;
    write data from working memory member location to NV sector @ start + 
        offset + sector address;

(结构类型有几个嵌套结构,所以我认为offsetof()就在这里)

这为常见操作带来了非常简单和熟悉的感觉功能签名:

int write_or_read(*handle, copyNumber, *data, size);

这很好,直到我还想从RAM存储第二个结构。这意味着RAM中现在有两个地址,内存模块需要跟踪以正确计算偏移量,还有一些额外的决策工作来决定使用哪个

因此,我推断结构RAM起始位置应该在内存操作时传入,而不是作为内存模块上下文的一部分保存。

虽然开始有点笨拙:

int write_or_read(*handle, copyNumber, *data, *data_struct_start, size);

所以我的问题是:是否存在经常或常用于类似或类似情况的任何约定或模式,希望这样也会导致简单熟悉的操作函数签名?

编辑:进一步说明 NV存储器是一个简单的外部器件,类似于EEPROM,具有2KB的存储器。我的结构包含多种数据类型,包括其他结构,每种结构大小约为600B。该设备没有缓冲;它实际上是FRAM,所以它相当快,但是我的开销很小,所以我不想只为一个成员编写整个结构。

图片显示我目前在RAM中有一个结构,在NV内存中有多个副本。如果我想读取或写入特定副本的特定成员,那么我只需要获取成员的地址(&myStruct->member_2)就可以在RAM中获得该成员的地址,但我应该在NV中使用哪个地址? RAM地址不与NV中的地址对齐(例如,RAM中的地址0x300!NV中的0x300),因此我需要一些其他方法来确定。

enter image description here

如果读取或写入函数被告知在NV中将member_2 myStruct的{​​{1}}副本写入struct_1,那么它需要写入哪个字节地址?

也许我试图保持界面这么简单是不正确的?

1 个答案:

答案 0 :(得分:1)

不要使用结构进行序列化。

而是在明文数据文件(CSV,JSON,XML,...)中定义设置变量:

ID,  TYPE,   DEFAULT
Foo, int32,      120
Bar, float,     40.0 

然后使用您选择的脚本语言将该数据文件转换为源文件。您可以从类型中确定所需的大小,并自动计算NV内存偏移到表格。

您的脚本吐出的其中一个文件是ID列表:

typedef enum {
    ID_Foo,
    ID_Bar,
    ID_COUNT
} ID_T;

您提供的API很简单:

int32_t ReadInt32(ID_T id);
float ReadFloat(ID_T id);
void WriteInt32(ID_T id, int32_t value);
void WriteFloat(ID_T id, float value);

这有几个好处:

  • 偏移和地址的所有脏信息都隐藏在其他代码中。
  • 现在您可以轻松扩展它,添加例如最小/最大/描述字段。
  • 您可以通过更改脚本轻松更改数据表格式,同时保持API不变。
  • 如果您以后需要其他功能,例如通过串口读取/写入设置的功能,则会在一个位置列出设置。
  • 如果为数据指针添加附加字段,则可以在调用写入函数时自动更新实际RAM值。
  • 您可以创建其他脚本来生成设置文档(pdf / doc / etc.)