完成自訂外設的硬體設計後,就需要編寫軟體來測試外設的設計是否正確了。
在這之前首先要弄清楚Nios II中的地址對齊,對Avalon slave來說,有兩種地址對齊:動態地址對齊和靜態地址對齊。
動態地址對齊:動態地址對齊可以自動適應和Avalon master連接埠寬度不同的器件,而同時保持地址增長的方式是以位元組為單位增長的方式。匹配不同連接埠寬度的master和slave時使用動態地址對齊可以得到一個連續的存貯器空間。但動態地址對齊在讀操作的時候有附作用。當一個32位Nios II core讀一個8位寬的slave時,物理會產生4次8位的讀操作,而讀一個16位寬的slave時,則要產生2次的讀操作。大部分寄存器類型的外設不能容忍這種附作用,所以動態地址對齊一般不適合用於寄存器外設,主要用於存貯器。如果外部存貯器的寬度大於8位時,比如16位或32位,則必然有位元組使能訊號,以便進行位元組粒度的寫操作。所以在為這些存貯器做介面的時候,如果採用動態地址對齊的方式,則一定要串連位元組使能訊號。
靜態地址對齊:靜態地址對齊的地址增長單位是Avalon master的連接埠寬度,每次讀寫都只對應一次操作沒有什麼附作用。但在匹配不同連接埠寬度的master和slave時,地址不能自動調整,某些地址沒有相應的物理實體和它對應。當一個32位的Nios II core讀一個8位寬的slave時,其獲得的32位元據低8位從slave擷取,而高24位則沒有定義。同樣,當它讀16寬的slave時,其獲得的32位元據低16位從slave擷取,而高16位則沒有定義。當Nios II core想繼續讀下一個8位(或16位)時,則需要增長位元組地址4。除非你一定需要一個連續的地址空間,否則使用靜態地址對齊是比較保險的方式。
在剛調試期間遇到這樣一個問題:用IOWR(KEYBOARD_BASE,2,0);清楚irq中斷訊號,在用SignalTap II邏輯分析儀始終抓不到write訊號,一直保持低電平,後來用IOWR(KEYBOARD_BASE,0,0)就能抓到write訊號了。我想一定是地址對齊的問題,然後開啟SOPC Builder,準備地址對齊對齊,可是始終沒有看到那一項,以前6.0版本是有這個選項的。折騰了我一天,後來只好硬著頭皮看Altera官方文檔,終於找到答案了。
於是決定找到源檔案,改代碼,在產生的key_hw.tcl中
#set_interface_property avalon_slave addressAlignment DYNAMIC
set_interface_property avalon_slave addressAlignment NATIVE
注釋掉DYNAMIC,改成NATIVE。
重新編譯,問題就不服存在了,用SignalTap II成功到捕捉write訊號
測試來源程式如下:
1 #include "system.h"
2 #include <stdio.h>
3 #include <io.h>
4 #include "alt_types.h"
5 #include "sys/alt_irq.h"
6 static void key_isr(void* context, alt_u32 id);
7 volatile int irq_capture;
8 int main (void) __attribute__ ((weak, alias ("alt_main")));
9 int alt_main (void)
10 {
11 alt_irq_init(ALT_IRQ_BASE); //使能中斷
12 alt_irq_register(KEYBOARD_IRQ,NULL , key_isr);//註冊中斷服務程式
13 while (1);
14 return 0;
15 }
16 static void key_isr(void* context, alt_u32 id)
17 {
18 irq_capture = IORD(KEYBOARD_BASE,1);
19 IOWR(KEYBOARD_BASE,2,0);
20 printf("key_value:%d\n",irq_capture);
21 }
22
為了能弄清楚中斷的工作流程,決定進行單步調試。但必須Crowdsourced Security Testing道中斷時如何控制和執行的。
中斷由三個寄存器控制:state,ienable,ipending。
state:最後一位PIE,中斷開關,1:中斷使能。0:禁止外部中斷
ipending:32位,第n位為1則表示正在處理第n個中斷。
ienable:32位,每1位對應1個外部中斷源的使能位,若第n位為1,則使能對應的中斷,為0則禁止對應的中斷。
注意,ienable變成了0x4,聯想到上一篇(原創)SOPC系統自訂外設之:硬體設計,中斷號為2,表示鍵盤中斷已經使能。
還有一個就是終端向量表alt_irq,一共有32個,每一個對應一個中斷優先順序,如果中斷註冊成功,就會向中斷向量表裡面寫入ISR和context
如,alt_irq[2]的handler指向key_isr()中斷服務程式,中斷註冊成功!
Context為全0,因為程式在註冊中斷服務程式時設定的context參數為NULL。
alt_irq_active是一個32位的全域變數,當某個中斷被使能後,對應位就為1。
開始硬體上運行程式,讓程式執行key_isr()中斷服務程式。在按鍵時,輸出如下:
中斷服務程式成功執行!!
經過這次自訂外設軟硬體的調試,實在是讓人感歎SOPC的靈活性!