将结构写入闪存

Writing a struct to flash memory

我在使用微控制器(nrf58122 SoC 内的 cortex-M0)将结构写入闪存时遇到问题。我对 c/c++ 的了解还不够,无法确定这是内存管理问题还是对编程缺乏基本了解。

我有一个 class 结构成员:

struct settings_t
{   
  uint16_t n;
  uint8_t b;
  bool e;
} settings;

在我的 class 方法之一中,我需要将此结构的内容写入微控制器中的闪存(没有可用的 EEPROM)。为了做到这一点,我调用了预先编写的函数——我知道我需要在写入之前擦除页面。如果我尝试以下操作:

settings = {
  constants::n,
  constants::b,
  constants::e
};

其中值 n、b、e 的类型正确,我遵循此定义:

flashPageErase(PAGE_FROM_ADDRESS(constants::settingsPageAddr));
flashWriteBlock(s, &settings, sizeof(settings));

我在执行 flashWriteBlock 函数时遇到运行时错误(程序执行暂停,没有错误代码)。但是,如果我先复制结构:

settings_t cpy = settings;
flashPageErase(PAGE_FROM_ADDRESS(constants::settingsPageAddr));
flashWriteBlock(s, &cpy, sizeof(settings));

然后它确实起作用了。任何人都可以对此有所了解吗?我可以根据需要提供更多详细信息。

如果您谈论的是 Arduino Uno 和相关的基于 ATMega 的控制器,您可能需要查阅 Arduino 官方网站:Reading and Writing Data Structures to EEPROM。该页面包含 EEPROM_readAnything 和 EEPROM_writeAnything 的模板。

文档可能没有说,但是实现表明源和目标都必须是 32 位对齐的:

int flashWriteBlock( void *dst, const void *src, int cb )
{
    uint32_t *d = dst;
    const uint32_t *s = src;

    /* The rest of the function snipped*/
}

失败是由于 settings 变量是 16 位对齐的。它必须被强制为 32 位对齐。这是如何完成的取决于编译器。以下示例适用于 gcc:

struct settings_t
{   
  uint16_t n;
  uint8_t b;
  bool e;
} __attribute__ ((aligned (4))) settings;