将结构写入闪存
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;
我在使用微控制器(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;