基礎知識
arm體系架構的處理器中通常將低位址32位元組作為中斷向量表,當中斷產生時會執行以下操作:
儲存處理器當前狀態,設定中斷遮蔽位和各條件標誌位
設定當前程式狀態暫存器cpsr中相應位
將lr_mode暫存器設定成返回位址
跳轉到中斷向量位址執行,從而跳轉到相應的中斷程式中執行
執行中斷處理函式內容
恢復被遮蔽的中斷遮蔽位
返回到被中斷指令的下一條指令處繼續執行
zynq中低32位元組作為中斷向量表,每個中斷佔據4位元組,這4位元組通常儲存乙個跳轉指令,從而跳轉到中斷解析程式中。這低32位元組中斷向量表如:
位址中斷型別
異常中斷模式
優先順序說明
0x00
復位中斷
特權模式(svc)
1系統上電和系統復位或軟復位時產生
0x04
未定義指令中斷
未定義指令中止模式(undef)
6當執行的指令不是arm處理器或協處理器的指令時產生
0x08
軟體中斷(swi)
特權模式(svc)
6使用者定義中斷指令,可用於使用者模式下呼叫特權操作指令
0x0c
指令預取中止
中止模式
5當預取指令位址不存在或位址不允許當前指令訪問時產生
0x10
資料訪問中止
中止模式
2當資料訪問指令的目的位址不存在或位址不允許當前指令訪問時產生
0x14保留無
無無0x18
外部中斷請求(irq)
外部中斷模式
4處理器外部中斷請求引腳有效而且cpsr的i位被清除時產生
0x1c
快速中斷請求(fiq)
快速中斷模式
3處理器外部快速中斷請求引腳有效而且cpsr的f位被清除時產生
本內容部分修改自《xilinx zynq soc與嵌入式linux設計實戰指南——相容arm cortex-a9的設計方法》
vivado中ps部分配置如下圖:
選中fabric interrupts和irq_f2p[15:0]
連線如下圖:
其中concat模組只是簡單的將多個訊號合併為乙個匯流排連線到zynq;而utility vector logic則是執行一些邏輯計算,這裡選擇not邏輯計算。
#include #include "platform.h"
#include "xscugic.h"
#include "xil_exception.h"
#define int_cfg0_offset 0x00000c00
// parameter definitions
#define sw1_int_id 61
#define sw2_int_id 62
#define sw3_int_id 63
#define intc_device_id xpar_ps7_scugic_0_device_id
#define int_type_rising_edge 0x03
#define int_type_highlevel 0x01
#define int_type_mask 0x03
static xscugic intcinst;
static void sw_intr_handler(void *param);
static int interruptsystemsetup(xscugic *xscugicinstanceptr);
static int intcinitfunction(u16 deviceid);
static void sw_intr_handler(void *param)
void intctypesetup(xscugic *instanceptr, int intid, int inttype)
int intcinitfunction(u16 deviceid)
int main(void)
檢視u585第231頁,可以看到從pl部分輸入的中斷號為對應irq_f2p[15:0],這裡使用irq_f2p[2:0],所以才有sw1_int_id到sw3_int_id定義為61到63。
分析中斷執行要從中斷執行開始的中斷向量表開始,查詢.org 0
,可以在bsp目錄下\ps7_cortexa9_0\libsrc\standalone_v5_2\src下asm_vectors.s檔案中的第64行可以找到,其下便是中斷向量表。
從bsp目錄下\ps7_cortexa9_0\libsrc\standalone_v5_2\src下vectors.c檔案中可以找到irqinterrupt函式,其中呼叫xexc_vectortable[xil_exception_id_irq_int].handler(xexc_vectortable[xil_exception_id_irq_int].data);
即irq中斷最終呼叫了xexc_vectortable陣列中第xil_exception_id_irq_int(即5)個成員的handler函式,並傳入data作為引數。
回到以上例程中有xil_exceptionregisterhandler(xil_exception_id_int,(xil_exceptionhandler)xscugic_interrupthandler,&intcinst);
從bsp目錄下\ps7_cortexa9_0\libsrc\standalone_v5_2\src下xil_exception.c中可找到此函式,其將(xil_exceptionhandler)xscugic_interrupthandler和&intcinst賦值給xexc_vectortable第xil_exception_id_int(即5)個成員的handler和data成員,結合上一段中說明,則irq中斷最終執行了:xscugic_interrupthandler(&intcinst)
。
再看以上例程有status = xscugic_connect(&intcinst,sw1_int_id,(xil_exceptionhandler)sw_intr_handler,(void *)1);
,可以從bsp目錄下\ps7_cortexa9_0\libsrc\standalone_v5_2\src下xscugic.c中可找到此函式,可以看到(其中instanceptr對應&intcinst;int_id對應sw1_int_id;handler對應sw_intr_handler;callbackref對應1,當然其它中斷分別為2,3):
instanceptr->config->handlertable[int_id].handler = handler; // 即引數sw_intr_handler
instanceptr->config->handlertable[int_id].callbackref = callbackref;// 即引數1
即將處理函式(sw_intr_handler)及其引數(1)放到&intcinst中, 再次回到irq中斷後會執行的xscugic_interrupthandler函式(在bsp目錄下\ps7_cortexa9_0\libsrc\standalone_v5_2\src下xscugic_intr.c)中有以下語句:
tableptr = &(instanceptr->config->handlertable[interruptid]);
if(tableptr != null)
即當tableptr不為空時就執行了instanceptr->config->handlertable[interruptid]->handler(instanceptr->config->handlertable[interruptid]->callbackref);
結合上一段說明即執行了sw_intr_handler(1)
或引數為2、3。
綜上,irq中斷產生後跳轉到0x18執行b irqhandler
執行,在irqhandler下執行bl irqinterrupt
;在函式irqinterrupt中xexc_vectortable[xil_exception_id_irq_int].handler(xexc_vectortable[xil_exception_id_irq_int].data);
經過xil_exceptionregisterhandler函式後即xscugic_interrupthandler(&intcinst)
再經過xscugic_connect函式這也即sw_intr_handler(1)
或引數為2、3。最終irq中斷執行了sw_intr_handler函式。
zynq新增GPIO中斷程式
核心原始碼為adi官方關於ad9361的核心,編譯工具為petalinux2015.2,開發板為zynqxc7z100 一 修改裝置樹 1.開啟petalinux專案下的.project spec meta user recipes dt device tree files system top.d...
zynq中乙個中斷程式分析
原文 本文通過分析乙個中斷例程來了解zynq中斷執行過程 儲存處理器當前狀態,設定中斷遮蔽位和各條件標誌位 設定當前程式狀態暫存器cpsr中相應位 將lr mode暫存器設定成返回位址 跳轉到中斷向量位址執行,從而跳轉到相應的中斷程式中執行 執行中斷處理函式內容 恢復被遮蔽的中斷遮蔽位 返回到被中斷...
zynq中乙個中斷程式分析
本文通過分析乙個中斷例程來了解zynq中斷執行過程 儲存處理器當前狀態,設定中斷遮蔽位和各條件標誌位 設定當前程式狀態暫存器cpsr中相應位 將lr mode暫存器設定成返回位址 跳轉到中斷向量位址執行,從而跳轉到相應的中斷程式中執行 執行中斷處理函式內容 恢復被遮蔽的中斷遮蔽位 返回到被中斷指令的...