我遇到了一个非常混杂的情况、非常感谢您提供任何建议。 我将 EMIF CS2配置为32位接口、并将所有时序设置为尽可能低的选项。 正常模式在启用延长等待时间的情况下使用。 当单步执行调试器时、从该 EMIF 复制值的函数偶尔会复制不正确的值、但实际上在 JTAG 中检查该 EMIF 地址的值会显示正确的值。
typedef union Field {
float32_t f32;
int32_t i32;
uint32_t u32;
} Field;
typedef union {
struct {
uint8_t id:8;
State state:8; // Enum defined elsewhere
uint8_t _16:4;
bool message_refuse:1;
uint8_t _21:3;
MessageType message_type:8; // Enum defined elsewhere
};
uint32_t all;
struct {
uint16_t lower;
uint16_t upper;
};
} Header;
typedef union {
struct {
uint8_t bcc:8;
uint8_t _8:8;
uint8_t speed:8;
uint8_t acceleration:8;
};
uint32_t all;
struct {
uint16_t lower;
uint16_t upper;
};
} Footer;
typedef struct Message {
Header header;
Field sections[6];
Footer footer;
} Message;
Message volatile const* const RECEIVE_MESSAGE = SOME_EMIF_ADDRESS;
void readMessage(Message* message_out) {
Message volatile const* in = RECEIVE_MESSAGE;
message_out->footer.all = in->footer.all;
DELAY_US(0.2);
message_out->header.all = in->header.all;
DELAY_US(0.2);
// Read sections
for (int16_t i = 0; i < 6; ++i) {
message_out->sections[i].u32 = in->sections[i].u32;
DELAY_US(0.2);
}
}
上面显示了 EMIF 地址的结构化读取的示例定义。 `re` adMessage `m函数、` essage_out `始终生成正确的标头/段、但似乎在页脚的` Bcc 代码中偶尔会失败(也总是具有相同的值、其中它应该是0x3、但应该是0x10)。 最有趣的是`m断点并观察调试器中的值时、页脚在实际的 EMIF 地址中是正确的、但仅在` essage_out `中` Bcc 代码是错误的。 这在某种程度上也是随机的/不频繁的。
为了解决这个问题、我已经尝试将 EMIF 时序配置降低到可用的最慢选项、在读取函数内增加不同数量的延迟、在延迟函数内重新排序副本、以及在读取函数内多次从 EMIF 地址复制页脚。 所有这些操作都不会在结果中产生任何变化(间歇性页脚`BCC`错误为0x10而不是0x3、仅在复制的`message_out`中出现)。
是否有人经历过类似的行为? 此时、我没有怀疑 EMIF 本身、因为它在直接读取时会生成正确的值、但我不明白从一个存储器区域到另一个存储器区域的简单副本如何会随机间隔产生具有相同值的完全相同的错误。

