2010-06-10 18 views
0

我正在做一個軟核處理器的編程,來自Altera的Nios II,下面是一個教程中的代碼,我設法得到代碼通過在硬件(DE2板卡)上測試來工作,但是我無法理解代碼。需要關於此語法的幫助:「#define LEDs(char *)0x0003010」

#define Switches (volatile char *) 0x0003000 
#define LEDs (char *) 0x0003010 
void main() 
{ while (1) 
*LEDs = *Switches; 
} 

我知道#define的是,它無論是用於定義不變,或,但

  1. 爲什麼在上面的代碼中,有鑄像, (char *) 0x0003010,在#define
  2. 爲什麼2個常數SwitchesLEDs的行爲像一個變量而不是一個常量?

回答

4

1)爲什麼在上面的代碼中,在#define中存在像(char *)0x0003010這樣的轉換?

預處理器宏是文本替換。因此,代碼出來作爲

while (1) { 
    *(char *) 0x0003010 = *(volatile char *) 0x0003000 
} 

其中重複分配輸入(開關)的內容在0x3000處映射到輸出(LED)在0x3010映射。

2)爲什麼2個常數,開關和LED的行爲像一個變量,而不是一個常數?

請注意,這些是指針。所以它們總是指向相同的地方(恰好是一對存儲器映射的IO引腳或類似的東西),但是不能保證那些恆定位置的地址是恆定的,並且在每個預處理器符號之前出現的地址是是指針去參考運算符。

4

似乎SwitchesLEDs表示內存映射到實際的輸入(在Switches的情況下)和輸出(在LEDs的情況下)。

所以你的答案包括:

  1. 爲輸入字節轉換爲內存映射到地址0x0003000。爲了以字節的形式訪問它,你需要告訴編譯器,無論地址是0x0003000還是char(事實上,你告訴它該值的地址是volatile char,這樣編譯器不會優化掉該地址處的值可能隨時發生變化)。

  2. 他們常數,但它們是常數指針。也就是說,地址是恆定的,但包含在這些地址中的值不是恆定的。

會發生什麼情況是,每個時鐘週期(大約),不管從內存地址0x0003000讀取,然後寫入地址0x0003010。這給出了開關立即切換LED的錯覺。

3

在C中,宏是簡單的替換。

每當編譯器在您的代碼中看到LEDs時,它將用(char *) 0x0003010代替它。

所以,你的代碼實際上是一樣的:

void main() 
{ 
    while (1) 
     *(char *) 0x0003010 = *(volatile char *) 0x0003000; 
} 
+3

預處理器,不是編譯器。 – DiGMi 2010-06-10 01:57:14

+0

@dig:在C中,預處理階段是編譯過程的一部分,並且說編譯器執行這些任務是正確的,即使某些實現可能使用單獨的程序來執行預處理階段。 – 2010-06-10 02:01:33

+0

@詹姆斯:但在這種情況下,更清楚地說出「預處理器」,你的意思是「預處理器」。 – dmckee 2010-06-10 02:05:42

0

沒有在#定義類型轉換,他們不會爲char *和揮發性的char *對待。 *開關處的內容被複制到* LED中。