標籤:style http color 使用 os strong io 資料
1 概述
Nios II 的boot過程要經曆兩個過程。
- FPGA器件本身的配置過程。FPGA器件在外部配置控制器或自身攜帶的配置控制器的控制下配置FPGA的內部邏輯。如果內部邏輯中使用了Nios II,則配置完成的FPGA中包含有Nios II軟核CPU。
- Nios II本身的引導過程。一旦FPGA配置成功後,Nios II 就被邏輯中的複位電路複位,從reset地址開始執行代碼。Nios II 的reset地址可以在SOPC builder的“Nios II More‘CPU’setting”頁表中設定。
2 幾種常見的boot方式
2.1 從EPCS串列存貯器中boot
這種boot方式,FPGA的配置資料和Nios II的程式都存放在EPCS器件中。FPGA配置資料放在最前面,程式放在後面,程式可能有多個段,每個段前面都插有一個“程式記錄”。一個“程式記錄”由2個32位的資料構成,一個是32位的整數,另一個是32位的地址,分別用於表示程式段本身的長度和程式段的運行時地址。這個“程式記錄”用於協助bootloader把各個程式段搬到程式執行時真正的位置。EPCS是串列存貯器,Nios II 不能直接從EPCS中執行程式,它實際上是執行EPCS控制器的片內ROM的代碼(即bootloader),把EPCS中程式的搬到RAM中執行。
2.2 從外部CFI 並行flash中boot
這種boot方式還可以分為2種情況。
- 程式直接在flash中運行。這種情況程式不需要另外的bootloader,Nios II 複位時reset地址(指向flash內部)開始執行程式,程式必須有啟動代碼用於搬移.rwdata段(因為.rwdata段是可讀寫的不能存放在flash中),同時如果.RODATA段和.EXCEPTIONS段串連時沒有指定在flash中話(比如在RAM中),也會被搬到RAM中,並對.bss段清零,設定棧的指標。這些工作都在Crt0.s中完成。
- 程式在RAM(包括On-chip Ram,SDRAM,SSRAM…泛指一般的RAM)中運行。這種情況需要有一個專門的bootloader,它把存放在flash中的各個程式段搬到程式執行時各個段真正的位置。
3 從EPCS中boot
要支援Nios II從EPCS中boot首先要求FPGA器件要支援主動串列配置。Altera的Cyclone,Cyclone II和Stratix II系列的FPGA支援主動串列配置。直到Nios II 5.1版本,Nios II 從EPCS中boot在Stratix II系列的FPGA上實現上仍有問題。所以這種方式主要用於Cyclone和Cyclone II系列的器件。
為了實現這種boot方式,使用者必須在SOPC builder中添加一個EPCS控制器,無須給它分配管腿,Quartus II 會自動給它分配到專用管腿上。添完EPCS控制器後,SOPC builder會給它分配一個base address,這個地址是EPCS控制器本身攜帶的片上ROM在Nios II系統中的基地址,這個ROM存有一小段bootloader代碼,用於引導整個過程。所以,必須在SOPC builder的“Nios II More‘CPU’setting”頁表中把reset地址設定為這個基地址,使得Nios II 複位後從這個地址開始執行以完成整個引導過程。
3.1 EPCS控制器的bootloader分析
EPCS控制器帶有一塊片內ROM,內有Bootloader代碼,Nios II 就靠這段程式碼完成boot過程。它把EPCS裡的Nios II程式映象複製到RAM中,然後跳轉到RAM中運行。由於程式映象是由elf2flash輸出的,bootloader對被搬運的程式映象的位置和結構的解讀必須和elf2flash工具一致。FPGA的配置資料從EPCS位移為0的地址開始存放,緊挨著配置資料後面是一個32位的整數,指示程式段的長度,接著是一個32位的地址,指示程式執行時該程式段的地址,我們把這個長度和地址一起稱為“程式記錄”,“程式記錄”隨後就是程式段映象。一個程式可能有多個程式段,所以也就有多個“程式記錄”和程式段映象。Bootloader必須知道FPGA配置資料的長度以讀取配置資料後面的內容,不同型號的FPGA的配置資料長度是不同的,所以必須讀取配置資料的頭部資訊擷取配置資料的長度,進而逐個讀取程式段映象的長度和運行時地址,然後把程式段映象搬到目的運行時地址。為了存取EPCS,bootloader構造了一些位置無關彙編代碼。EPCS的存貯布局如下所示:
當bootloader讀取到L時,L=0,表示前面所有的程式記錄已經處理完畢,這個是最後的程式記錄就直接跳到地址A的地方執行。顯然A必須是程式的入口地址。如果L=0xffffffff(即-1),那麼就忽略A並停機,這樣,即使是一個只有FPGA配置資料而沒有程式的EPCS也是安全的。當一個EPCS只有配置資料而沒有程式的時候,sof2flash會在配置資料的末尾增加4個位元組的0xff使bootloader不會有誤動作。Bootloader的工作流程如下:
3.2 EPCS控制器
EPCS控制器手冊沒有對EPCS進行詳細的說明只是建議使用者使用Altera的HAL函數來存取。其實EPCS控制器由兩個獨立的組件構成:
- Rom。大小是512個位元組,也就是128 words。儘管EPCS控制器手冊表述了Rom的大小是1K位元組,實際上直到Nios II 5.1 EPCS控制器的Rom仍然是512個位元組,因此手冊中給出的寄存器位移地址都需要修正。
- SPI Master控制器。EPCS串列存貯器的介面符合SPI標準。Nios II 可以通過SPI Master來存取EPCS串列存貯器。這兩個組件的地址(從Nios II 的角度看,以位元組為單位)安排如下:
| 位移地址 |
寄存器 |
R/W |
位描述 |
| 31..0 |
| 0x000 |
Boot Rom Memory |
R |
Boot Loader Code epcs_controller_boot_rom.hex or epcs_controller_boot_rom.dat |
| 0x004 |
| … |
| 0x1FC |
| 0x200 |
Rx Data |
R |
31..8 (Not Implemented) |
Rx Data(7..0) |
| 0x204 |
Tx Data |
W |
31..8 (Not Implemented) |
Tx Data(7..0) |
| 0x208 |
Status |
R/W |
31..11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
| |
|
EOP |
E |
RRDY |
TRDY |
TMT |
TOE |
ROE |
|
|
|
| 0x20C |
Cotrol |
R/W |
31..11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
| |
|
IEOP |
IE |
IRRDY |
ITRDY |
|
ITOE |
IROE |
|
|
|
| 0x210 |
Reserved |
- |
|
| 0x214 |
Slaver Enable |
R/W |
31..16 |
15 |
14 |
13 |
… |
3 |
2 |
1 |
0 |
| |
SS_15 |
SS_14 |
SS_13 |
… |
SS_3 |
SS_2 |
SS_1 |
SS_0 |
| 0x218 |
End of Packet |
R/W |
31..8 (Not Implemented) |
End of character(7..0) |
- Rx Data寄存器
Nios II從Rx Data寄存器中讀出從EPCS中接收到的資料。當接收移位寄存器收到滿8位的資料,status寄存器的RRDY位被置1,同時資料被傳入Rx Data寄存器。讀取Rx Data寄存器會把RRDY位清掉,而往Rx Data寫則沒有影響。
- Tx Data寄存器
Nios II把要發送的資料寫到Tx Data寄存器。status寄存器中的TRDY位置1表示Tx Data寄存器準備好接收來自Nios II的新資料。Tx Data被寫了之後,TRDY位就被置0,直到資料從Tx Data轉移到發送移位寄存器又會被重新置為1。
- Status寄存器
status寄存器包含有指示目前狀態的位。幾乎每一位都和control寄存器的一個中斷允許位相關。Nios II任何時候都可以讀取status寄存器,不會影響該寄存器的值。往status寄存器寫將清除ROE,TOE和E這些位。下表描述了各個位的含義:
| 位 |
名稱 |
含義 |
| 3 |
ROE |
接收溢出錯誤。當Rx Data寄存器資料滿的時候(RRDY為1),接收移位寄存器又往Rx Data寄存器寫,那ROE位將被置1。而新的資料會覆蓋老的資料。往status寄存器寫可以把ROE位清0。 |
| 4 |
TOE |
發送溢出錯誤。如果Tx Data寄存器資料還沒有被轉移到發送移位寄存器(TRDY為0),又往Tx Data寄存器寫,那TOE就會被置為1。新的數被忽略。往status寄存器寫可以清TOE為0。 |
| 5 |
TMT |
發送移位寄存器空。如果一個發送過程進行中中,那TMT為0;如果發送移位寄存器為空白,則TMT為1。 |
| 6 |
TRDY |
發送器準備好接收新的發送資料。當Tx Data寄存器空的時候,TRDY為1。 |
| 7 |
RRDY |
接收器準備好送出接收到的數。當Rx Data寄存器滿的時候,RRDY為1。 |
| 8 |
E |
有錯誤產生。它是TOE和ROE的邏輯或。只要TOE或ROE中有一個為1,那它也為1。它給程式提供了一個判斷有錯誤發生的方便的途徑。往status寄存器寫可以把E位清0。 |
| 9 |
EOP |
包結束標誌。該標誌在下列情況下被置1: 1. 一個EOP位元組被寫入Tx Data寄存器2. 一個EOP位元組從Rx Data寄存器中讀出 EOP位元組就是End of Packet寄存器中的End of Character位元組。往status寄存器寫可以把EOP位清0。 |
- Control寄存器
control寄存器控制SPI Master的操作。Nios II可以在任何時候讀取control寄存器而不改變它的值。大部分control寄存器的位(IROE,ITOE,ITRDY,IRRDY和IE)控制status寄存器相應位的中斷。比如當IROE設為1,就允許當status中的ROE為1時產生中斷。只有當control寄存器和stauts寄存器中的相應位都為1的情況下,SPI Master才會產生中斷。
| 位 |
名稱 |
含義 |
| 3 |
IROE |
允許ROE條件滿足時產生中斷。 |
| 4 |
ITOE |
允許TOE條件滿足時產生中斷。 |
| 6 |
ITRDY |
允許TRDY條件滿足時產生中斷。 |
| 7 |
IRRDY |
允許RRDY條件滿足時產生中斷。 |
| 8 |
IE |
允許E條件滿足時產生中斷。 |
| 9 |
IEOP |
允許EOP條件滿足時產生中斷。 |
| 10 |
SSO |
強制slave enable寄存器器中為1的位對應的ss_n有效,即輸出電平0。 |
- Slave enable寄存器
slave enable寄存器中的某一位置1表示相應的ss_n訊號可以被驅動有效(即在control寄存器中寫SSO位為1,或者有資料寫入Tx Data寄存器準備開始傳送資料)。Slave enable寄存器可以多位為1,但是需要有其它邏輯來處理多個SPI slave的衝突問題。
- End of Packet寄存器
End of Packet寄存器包含End of Character,當某一Avalon master讀出的Rx Data寄存器位元組和End of Character一樣,或者寫入Tx Data的位元組和End of Character一樣時,SPI Master產生EOP標誌。如果該Avalon master支援endofpacket訊號,則會中斷傳輸。
EPCS控制器在例化SPI Master時使用下列參數:資料位元8位;SPI時鐘SCLK頻率20MHz;MOSI(ASDO)在SCLK的下降沿處輸出;MISO(DATA0)在SCLK上升沿處採樣;SCLK的初始相位為0;MSB先輸出,LSB後輸出;目標延遲100us(即ss_n輸出為低到SCLK開始驅動輸出時鐘脈衝的延遲為100us)。
3.3 EPCS串列存貯器件
Altera的器件手冊對EPCS器件有完整清楚的表述。在read byte,read status和read silicon ID操作時,發出命令後,所要的資料會馬上從EPCS的DATA管腿移出。所以EPCS控制在發出命令後繼續發送虛擬資料(比如0或隨便什麼值),在發送虛擬資料的同時接收EPCS送出的資料,就可以擷取所要的資料。SPI介面的發送和接收是同時的,為了接收資料,你必鬚髮送點什麼,儘管這些資料是對方不需要的,同樣在你發送命令或資料的同時也會收到點什麼,儘管這些也不一定是你需要的。