2012-03-13 33 views
1

挥发性uint32_t的这是我的代码:上皮层立方米

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

当分析在我的调试器中的可变value,它拥有所有线路上的相同的值。我究竟做错了什么?

+0

也许你的调试器不能正确处理挥发物? – 2012-03-13 09:21:02

+0

为什么不只是使用一些跟踪和不依赖调试验证着想检查实际的程序的行为。 – 2012-03-13 09:22:15

+0

你在用什么处理器? – DipSwitch 2012-03-13 09:31:10

回答

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 uint32_t *pValue = (volatile uint32_t *) 0xA0000000; 
*pValue *= 2; 
*pValue |= 0x00000001; 

在这种情况下,存储位置将在每一个指令被改变,而不必明确写入值

+0

因为我正在开发嵌入式系统,所以目前我没有'printf'。 – Randomblue 2012-03-13 09:35:16

+0

那么你应该找到另一种方式,如http://stackoverflow.com/questions/5165654/cost-of-fprintf/5165813#5165813和最终做什么用的字符缓冲区('puts'或输出到串行端口等)。 – paxdiablo 2012-03-13 09:46:24

+0

http://github.com/dwelch67,寻找比特产,我用它无处不在,或使自己的,八是更加容易的,但我们大多数人还是认为工作在十六进制没有。如果你有一个示波器或逻辑分析仪将其并行或其他串行接口(以比uart速度快得多的速度)推出,则不需要除法,移位掩码和/或用于八进制,十六进制所需的条件。 – 2012-03-14 20:31:44

1
  1. 这可能是因为您的优化已经注意到value是一个自动变量,其地址是从来没有,所以实际上已经忽略了一个事实,即它的挥发性,因为它正好了解一下建筑在其上运行,并得出结论认为,即使标准认为这是可观察的,一致性程序也不能观察到什么序列的读写。显然这不是很好的调试器,但如果它发生的话,我不会感到惊讶。实际上,编译器会假设你不能“看到”堆栈,如果你使用调试器,检查核心转储,只读标记堆栈并处理结果信号等,这是错误的。检查反汇编,看看multipy/shift和bit-set是否真的出现。
  2. 可能是因为(1)或其他原因,调试器没有正确跟踪值。
+0

0xA0000000在我正在开发的主板的内存映射中是非常重要的。 – Randomblue 2012-03-13 09:34:28

+0

@Randomblue:编辑删除错误的指责:-) – 2012-03-13 09:35:57

+0

它实际上并不是未定义的,否则嵌入式系统永远不会声称符合内存映射I/O。该标准规定它是不确定的只有“无效值被分配到指针” - 无效值包括null,错误的定位和它的生命周期之后的对象,但是这一切都已经说了。 0xa0000000是否无效是实施的问题。 – paxdiablo 2012-03-13 09:37:32

0

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