2012-03-13 36 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告訴編譯器總是讀取值,如果它永遠不會讀取,不一定要保持寫入值。