volatile uint32_t on cortex-m3

0kjbasz6  于 2023-08-03  发布在  其他
关注(0)|答案(3)|浏览(153)

下面是我的代码:

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

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

wvyml7n5

wvyml7n51#

也许你的调试器实际上并不那么好。当我的一个工具似乎不正常时,我总是用另一个工具来检查它。
尝试用老式的方法调试,使用:

  1. volatile uint32_t value = *((volatile uint32_t *) 0xA0000000);
  2. printf ("A:%d\n", value);
  3. value *= 2;
  4. printf ("B:%d\n", value);
  5. value |= 0x0000001;
  6. printf ("C:%d\n", value);

字符串
如果printf不可用,则使用其他输出方法(看起来您可能正在嵌入式空间中工作)。
看看你得到了什么-我更倾向于相信printf-调试比调试器。
如果您的问题不是与value有关,而是与0xA0000000位置的内存有关,那么它正在按预期工作。
您操作的是局部变量,而不是内存位置。你需要写回值,类似于:

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


然而,考虑到你使用的是volatile,你完全可能只是想要一个指向该位置的变量 * 指针 *,这样变化就会立即反映出来。
如果是这样的话,你需要的东西沿着:

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


在这种情况下,存储器位置将在每个指令 * 处改变,而 * 不必显式地写入值。

展开查看全部
sqyvllje

sqyvllje2#

1.可能你的优化器已经注意到value是一个自动变量,它的地址从来没有被取过,所以实际上忽略了它的volatile,因为它碰巧知道一些关于它运行的架构,并得出结论,一个符合标准的程序不能观察到它发生的读写顺序,即使标准说这是可观察的。显然,这对调试器不是很友好,但如果它发生了,我也不会感到惊讶。实际上,编译器会假设你不能“看到”堆栈,如果你使用调试器,检查核心转储,将堆栈标记为只读并处理结果信号等,这是假的。检查反汇编,看看multipy/shift和bit-set是否真的出现。
1.可能是调试器没有正确跟踪值,原因可能是(1)或其他原因。

ylamdve6

ylamdve63#

尝试将值写入另一个临时变量并检查该值。有时这会欺骗编译器/调试器做你想做的事情。volatile告诉编译器总是读取该值,如果它从未被读取,则不必保留它以供写入。

相关问题