皮质-m3上的挥发性uint32_t

时间:2012-03-13 09:19:30

标签: c cortex-m3

这是我的代码:

volatile uint32_t value = *((volatile uint32_t *) 0xA0000000); // here `value` is 12498
value *= 2; // here `value` is still 12498
value |= 0x0000001; // still 12498

在我的调试器中分析变量value时,它在所有行上保持相同的值。我做错了什么?

3 个答案:

答案 0 :(得分:5)

也许你的调试器实际上并不那么好。当我的某个工具似乎没有表现时,我总是会对另一个工具进行检查。

尝试使用以下方法调试老式方法:

volatile uint32_t value = *((volatile uint32_t *) 0xA0000000);
printf ("A:%d\n", value);

value *= 2;
printf ("B:%d\n", value);

value |= 0x0000001;
printf ("C:%d\n", value);

或其他一些输出方法如果printf不可用(看起来您可能在嵌入式空间中工作)。

看看你得到了什么 - 我更倾向于信任printf - 调试而不是调试器。


如果您的问题不在value,而在位置0xA0000000的内存中,那么它就会按预期运行。

您正在操纵局部变量,而不是内存位置。您需要将值写回来,例如:

*((volatile uint32_t *) 0xA0000000) = value;

但是,考虑到你使用volatile,你完全可能只需要一个变量指针到那个位置,以便更改立即反映出来。

如果是这种情况,你需要的是:

volatile uint32_t *pValue = (volatile uint32_t *) 0xA0000000;
*pValue *= 2;
*pValue |= 0x00000001;

在这种情况下,内存位置将在每条指令处更改,而不必显式写入值。

答案 1 :(得分:1)

  1. 可能是你的优化器注意到value是一个自动变量,其地址永远不会被占用,因此实际上忽略了它的易变性这一事实,因为它碰巧知道它运行的架构on,并得出结论,即使标准认为这是可观察的,一致性程序也无法观察到它的读写顺序。显然,这对调试器来说并不是很友好,但如果它发生的话,我也不会感到惊讶。实际上,编译器会假设你不能“看到”堆栈,如果你使用调试器,检查核心转储,将堆栈标记为只读并处理结果信号等,这是错误的。检查反汇编,看看是否实际出现了乘数/移位和位集。
  2. 由于(1)或其他原因,您的调试器可能无法正确跟踪该值。

答案 2 :(得分:0)

尝试将值写入另一个临时变量并检查该值。有时这会欺骗编译器/调试器做你想做的事情。 AFAIK,volatile告诉编译器始终读取该值,如果它永远不会读取,则不一定要保留它。