繁体   English   中英

cortex-m3上的易失性uint32_t

[英]volatile uint32_t on 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时,它在所有行上都具有相同的值。 我究竟做错了什么?

也许您的调试器实际上并不是那么好。 当我的一个工具似乎不起作用时,我总是将其与另一个工具进行对照。

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

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 -debugging。


如果您的问题不是value ,而是位置0xA0000000的内存,则说明它按预期工作。

您正在操作局部变量,而不是内存位置。 您需要使用以下方式写回值:

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

但是,鉴于使用了volatile,您完全可能只需要一个指向该位置的变量指针 ,以便更改可以立即反映出来。

如果是这样,您将需要遵循以下要求:

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

在那种情况下,将在每个指令中更改存储位置, 不必显式写入该值。

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

尝试将值写入另一个临时变量并检查该值。 有时,这会欺骗编译器/调试器执行所需的操作。 AFAIK,volatile告诉编译器始终读取该值,如果永不读取,则不必将其保留以进行写入。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM