<3> 設備驅動程序
其實,“總線仲裁器”也可看作一種硬件控制器,只不過它管的不是具體的硬件,而是負責數據的傳輸。那么它也有自己的設備驅動,封裝了總線操作的細節(jié)。既然總線是現成的,我們秉承“拿來主義”的原則,甭管它怎么實現的,會用就行。
例如,數碼管設備驅動要把數據“5”和“顯示”命令傳給數碼管控制器,設計兩個函數,由于數據和命令的傳遞必須經過總線,那么需調用總線驅動函數IOWR(基地址, 偏移量, 數據),另外,讀取寄存器用到IORD(基地址, 偏移量),這兩個函數在<io.h>里。
<io.h>的路徑是"..alterakits ios2_60componentsaltera_nios2HALinc"。
至此,“橋”搭完。
函數功能從字面上很好理解。剛才定義兩個寄存器時,data_reg在前面,所以偏移量是0,cmd_reg在后面,偏移量是1?!痢羅REG_MSK稱 為掩碼,avalon總線數據接口共32位,但我們設計的data_reg位寬是3,cmd_reg位寬為1,掩碼的作用在于告知寄存器寬度,知道就行, 實際上用不著?!痢羅REG_OFST是寄存器內的偏移量,這里同樣用不著,先寫上吧。
OK,我們的數碼管設備驅動文件正式出爐了,看看是不是簡潔明了很多?。?/p>
<4> 硬件抽象層(HAL)
設備驅動程序封裝的僅僅是對某個寄存器的一次讀寫操作,功能單一,需要在硬件抽象層再做一次封裝。
直接將這些函數列出來,一目了然,不作多余的解釋了。
[!--empirenews.page--]
至此,“橋”搭完。
接下來在把我們的“數碼管控制器”加入sopc builder系統(tǒng)中。
現在幾乎所有講nios的書都會提及自定義用戶外設,而且用的都是altera官方提供的例子PWM,本文的“數碼管控制器”就是照著它依葫蘆畫瓢改過來 的,呵呵,慚愧慚愧,之所以想改它,一是因為它用的是verilog而不是VHDL,而大多數人先接觸卻是VHDL;二來PWM的顯示效果似乎不太明顯, 改成數碼管顯示相對比較有成就感;第三,PWM的邏輯稍微有一點點復雜,我們的重點在于說明怎樣自定義外設,當然例子越簡單越好。
既然是照著PWM原樣改的,所以本文工程的結構與之保持高度一致,將其加入sopc builder的步驟也差不多,這里我就不再碼字了,各位照著書上做吧:
《SOPC嵌入式系統(tǒng)基礎教程(周立功等著)》第8章……
再接下來,建立一個包含“數碼管控制器”的nios系統(tǒng),并編寫應用程序,實現從0到9計數。
貼張官方的nios設計流程圖,看起來很漂亮是吧,不愧是altera的東西,大而全而不亂。
先說最中間的"SOPC Builder",它的任務是建立一個“以Nios CPU為核心,以Avalon總線為紐帶,將各種硬件設備連接起來”的nios系統(tǒng);這個系統(tǒng)要在FPGA中運行,所以必須掛靠一個Quartus II工程,用左邊的Quartus II進行分配引腳等等工作,生成硬件系統(tǒng);接著,右邊的Nios II IDE就可以在這個硬件系統(tǒng)上設計應用程序了;最后將硬件系統(tǒng)和軟件程序分別下載到FPGA芯片上,大功告成。
下面step by step
<1> Quartus II 新建一個工程名,工程名"DE2_SEG7"。
<2> "Tool" → "SOPC Builder" 打開SOPC Builder。
<3> "System Name": nios2_system 選VHDL。
一個包含“數碼管控制器”的最小系統(tǒng)至少由3部分組成:CPU必不可少,RAM存儲代碼,還有剛才設計的"seg7_avalon"。
<4> 加入"Nios II Processor",選"Nios II/e",精簡型夠用了。
<5> 加入"On-Chip Memory",類型選"RAM",位寬默認"32 bits","Total Memory"選"48Kbytes",等會兒軟件要占用四十多K空間。
<6> 加入"seg7_avalon"。
<7> 將這三個組件的名稱改好看點,然后設定RAM的基地址為"0x00000000",再右鍵鎖定基地址,如圖:
為什么要鎖定RAM的基地址為0呢?點選第二個選項卡,可以看到"Reset Address"對應著RAM,系統(tǒng)的復位肯定要從地址0開始。
<8> 由于剛才人為改動了地址分配,弄亂了,讓系統(tǒng)自動再分配一次,當然被鎖定的RAM基地址是不會變的。"System" →"Auto-Assign Base Addresses"。最終系統(tǒng)組件列表如下:
注意,seg7的地址范圍是"0x00010800"→"0x00010807",占8個地址,nios系統(tǒng)的地址按字節(jié)分配,也就是說,每個字節(jié)占用一 個地址,數碼管控制器中定義了兩個寄存器,avalon總線規(guī)定每個寄存器占32位(實際上是不是32位它就不管了,反正按最大32位分配),這樣兩個寄 存器共占去8個字節(jié),自然需要8個地址。
<9> 點擊"Generate"生成nios系統(tǒng),回到Quartus II。
<10> 新建一個頂層文件"File"→"New"→"Block Diagram/Schematic File",引入nios II系統(tǒng),增加輸入輸出引腳。然后,"Assignment"→"Import Assignment",添加引腳分配文件(在DE2光盤目錄下的DE2_tutorialsdesign_files DE2_pin_assignments.csv),改動頂層文件的引腳名稱使其與.csv文件中保持一致。
<11> 編譯,查看編譯報告,可見,48K的RAM占用了芯片83%的memory bits,差不多耗光了。
<12> 硬件部分已經搞定,關掉Quartus II,打開Nios II IDE,切換到工作目錄下。
<13> "File"→"New"→"C/C++ Application","SOPC Builder System"選擇"nios2_system.ptf"(就是剛才Generate Nios II系統(tǒng)生成的東東),再選模板"Hello World"(純屬偷懶 ),頂上的"name"改成"seg_example","Finish"。
<14> 改動hello_world.c,代碼的功能為:先初始化數碼管,等待2秒鐘,再進行0-9的循環(huán),循環(huán)過程中穿插2秒鐘的清屏。SEG7_BASE的宏 定義在system.h中,實際上就是在SOPC Builder中的seg7_avalon的基地址0x00010800。
<15> "Project"→"Build Project",得到編譯報告,軟件占用了7K空間……
<16> 下載到DE2板上,運行,數碼管不停地閃啊閃。
OK,從硬件到軟件的一條龍講完了。