将结构写入闪存

时间:2015-01-02 08:31:02

标签: c++ c struct arduino microcontroller

我在使用微控制器(nrf58122 SoC内部的cortex-M0)向闪存写入结构时遇到问题。我不知道足够的c / c ++来确定它是一个内存管理问题还是对编程的基本缺乏理解。

我有一个带有struct成员的类:

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

在我的一个类方法中,我需要将此结构的内容写入微控制器中的闪存(没有可用的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));

然后它确实有效。任何人都可以对此有所了解吗?我可以根据需要提供更多细节。

2 个答案:

答案 0 :(得分:1)

文档可能没有说明,但实现显示源和目标必须是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;

答案 1 :(得分:0)

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