我在使用微控制器(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));
然后它确实有效。任何人都可以对此有所了解吗?我可以根据需要提供更多细节。
答案 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的模板。