zynq中乙個中斷程式分析

2021-08-15 09:23:33 字數 4536 閱讀 5061

原文:

本文通過分析乙個中斷例程來了解zynq中斷執行過程

儲存處理器當前狀態,設定中斷遮蔽位和各條件標誌位

設定當前程式狀態暫存器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)

例程修改自z-turn例程

檢視u585第231頁,可以看到從pl部分輸入的中斷號為對應irq_f2p[15:0],這裡使用irq_f2p[2:0],所以才有sw1_int_id到sw3_int_id定義為61到63。

分析中斷執行要從中斷執行開始的中斷向量表開始,查詢.org 0,跳轉到irqhandler標籤,其後第99行再次跳轉到irqinterrupt,從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中乙個中斷程式分析

本文通過分析乙個中斷例程來了解zynq中斷執行過程 儲存處理器當前狀態,設定中斷遮蔽位和各條件標誌位 設定當前程式狀態暫存器cpsr中相應位 將lr mode暫存器設定成返回位址 跳轉到中斷向量位址執行,從而跳轉到相應的中斷程式中執行 執行中斷處理函式內容 恢復被遮蔽的中斷遮蔽位 返回到被中斷指令的...

Zynq 中斷程式例項分析

基礎知識 arm體系架構的處理器中通常將低位址32位元組作為中斷向量表,當中斷產生時會執行以下操作 儲存處理器當前狀態,設定中斷遮蔽位和各條件標誌位 設定當前程式狀態暫存器cpsr中相應位 將lr mode暫存器設定成返回位址 跳轉到中斷向量位址執行,從而跳轉到相應的中斷程式中執行 執行中斷處理函式...

用request irq註冊乙個中斷

request irq函式做的工作 1 分配乙個irqaciton結構體 2 把自己的中斷程式賦值給aciton 3 把這個結構體放入irq desc irq 的aciton煉表裡 把aciton放入鍊錶之前,還需要判斷這個中斷的標誌,如果是irqf shared,表示可以多個action共享中斷線...