0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

ARM體系架構(gòu)處理器的中斷程序分析

454398 ? 來(lái)源:CSDN博主 ? 作者:husipeng86 ? 2020-11-21 11:10 ? 次閱讀

基礎(chǔ)知識(shí)

ARM體系架構(gòu)的處理器中通常將低地址32字節(jié)作為中斷向量表,當(dāng)中斷產(chǎn)生時(shí)會(huì)執(zhí)行以下操作:

① 保存處理器當(dāng)前狀態(tài),設(shè)置中斷屏蔽位和各條件標(biāo)志位
② 設(shè)置當(dāng)前程序狀態(tài)寄存器CPSR中相應(yīng)位
③ 將lr_mode寄存器設(shè)置成返回地址
④ 跳轉(zhuǎn)到中斷向量地址執(zhí)行,從而跳轉(zhuǎn)到相應(yīng)的中斷程序中執(zhí)行
⑤ 執(zhí)行中斷處理函數(shù)內(nèi)容
⑥ 恢復(fù)被屏蔽的中斷屏蔽位
⑦ 返回到被中斷指令的下一條指令處繼續(xù)執(zhí)行

zynq中低32字節(jié)作為中斷向量表,每個(gè)中斷占據(jù)4字節(jié),這4字節(jié)通常存儲(chǔ)一個(gè)跳轉(zhuǎn)指令,從而跳轉(zhuǎn)到中斷解析程序中。這低32字節(jié)中斷向量表如:


本內(nèi)容部分修改自《Xilinx Zynq SoC與嵌入式Linux設(shè)計(jì)實(shí)戰(zhàn)指南——兼容ARM Cortex-A9的設(shè)計(jì)方法》

例程

vivado中ps部分配置如下圖:


選中Fabric Interrupts和IRQ_F2P[15:0]

連接如下圖:


其中Concat模塊只是簡(jiǎn)單的將多個(gè)信號(hào)合并為一個(gè)總線連接到zynq;而Utility Vector Logic則是執(zhí)行一些邏輯計(jì)算,這里選擇not邏輯計(jì)算。

#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)
{
    int sw_id = (int)param;
    printf("SW%d int/n/r", sw_id);
}

void IntcTypeSetup(XScuGic *InstancePtr, int intId, int intType)
{
    int mask;

    intType &= INT_TYPE_MASK;
    mask = XScuGic_DistReadReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4);
    mask &= ~(INT_TYPE_MASK << (intId%16)*2);
    mask |= intType << ((intId%16)*2);
    XScuGic_DistWriteReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4, mask);
}

int IntcInitFunction(u16 DeviceId)
{
    XScuGic_Config *IntcConfig;
    int status;

    // Interrupt controller initialisation
    IntcConfig = XScuGic_LookupConfig(DeviceId);
    status = XScuGic_CfgInitialize(&INTCInst, IntcConfig, IntcConfig->CpuBaseAddress);
    if(status != XST_SUCCESS) return XST_FAILURE;

    // Call to interrupt setup
    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
                                 (Xil_ExceptionHandler)XScuGic_InterruptHandler,
                                 &INTCInst);
    Xil_ExceptionEnable();

    // Connect SW1~SW3 interrupt to handler
    status = XScuGic_Connect(&INTCInst,
                             SW1_INT_ID,
                             (Xil_ExceptionHandler)SW_intr_Handler,
                             (void *)1);
    if(status != XST_SUCCESS) return XST_FAILURE;

    status = XScuGic_Connect(&INTCInst,
                             SW2_INT_ID,
                             (Xil_ExceptionHandler)SW_intr_Handler,
                             (void *)2);
    if(status != XST_SUCCESS) return XST_FAILURE;

    status = XScuGic_Connect(&INTCInst,
                             SW3_INT_ID,
                             (Xil_ExceptionHandler)SW_intr_Handler,
                             (void *)3);
    if(status != XST_SUCCESS) return XST_FAILURE;

    // Set interrupt type of SW1~SW3 to rising edge
    IntcTypeSetup(&INTCInst, SW1_INT_ID, INT_TYPE_RISING_EDGE);
    IntcTypeSetup(&INTCInst, SW2_INT_ID, INT_TYPE_RISING_EDGE);
    IntcTypeSetup(&INTCInst, SW3_INT_ID, INT_TYPE_RISING_EDGE);

    // Enable SW1~SW3 interrupts in the controller
    XScuGic_Enable(&INTCInst, SW1_INT_ID);
    XScuGic_Enable(&INTCInst, SW2_INT_ID);
    XScuGic_Enable(&INTCInst, SW3_INT_ID);

    return XST_SUCCESS;
}

int main(void)
{
    init_platform();

    print("PL int test/n/r");
    IntcInitFunction(INTC_DEVICE_ID);
    while(1);
    cleanup_platform();
    return 0;
}

例程修改自z-turn例程

過(guò)程分析

查看U585第231頁(yè),可以看到從PL部分輸入的中斷號(hào)為{[91:84],[68:61]}對(duì)應(yīng)IRQ_F2P[15:0],這里使用IRQ_F2P[2:0],所以才有SW1_INT_ID到SW3_INT_ID定義為61到63。

分析中斷執(zhí)行要從中斷執(zhí)行開(kāi)始的中斷向量表開(kāi)始,查找.org 0,可以在BSP目錄下/ps7_cortexa9_0/libsrc/standalone_v5_2/src下asm_vectors.s文件中的第64行可以找到,其下便是中斷向量表,作為IRQ中斷,在中斷向量表中為第5條(地址:0x18)指令,對(duì)應(yīng)第77行B IRQHandler,跳轉(zhuǎn)到IRQHandler標(biāo)簽,其后第99行再次跳轉(zhuǎn)到IRQInterrupt,從BSP目錄下/ps7_cortexa9_0/libsrc/standalone_v5_2/src下vectors.c文件中可以找到IRQInterrupt函數(shù),其中調(diào)用XExc_VectorTable[XIL_EXCEPTION_ID_IRQ_INT].Handler(XExc_VectorTable[XIL_EXCEPTION_ID_IRQ_INT].Data);即IRQ中斷最終調(diào)用了XExc_VectorTable數(shù)組中第XIL_EXCEPTION_ID_IRQ_INT(即5)個(gè)成員的Handler函數(shù),并傳入Data作為參數(shù)。

回到以上例程中有Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,&INTCInst);從BSP目錄下/ps7_cortexa9_0/libsrc/standalone_v5_2/src下xil_exception.c中可找到此函數(shù),其將(Xil_ExceptionHandler)XScuGic_InterruptHandler和&INTCInst賦值給XExc_VectorTable第XIL_EXCEPTION_ID_INT(即5)個(gè)成員的Handler和Data成員,結(jié)合上一段中說(shuō)明,則IRQ中斷最終執(zhí)行了: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中可找到此函數(shù),可以看到(其中InstancePtr對(duì)應(yīng)&INTCInst;Int_Id對(duì)應(yīng)SW1_INT_ID;Handler對(duì)應(yīng)SW_intr_Handler;CallBackRef對(duì)應(yīng)1,當(dāng)然其它中斷分別為2,3):

InstancePtr->Config->HandlerTable[Int_Id].Handler = Handler;        //  即參數(shù)SW_intr_Handler
InstancePtr->Config->HandlerTable[Int_Id].CallBackRef = CallBackRef;//  即參數(shù)1

即將處理函數(shù)(SW_intr_Handler)及其參數(shù)(1)放到&INTCInst中,
再次回到IRQ中斷后會(huì)執(zhí)行的XScuGic_InterruptHandler函數(shù)(在BSP目錄下/ps7_cortexa9_0/libsrc/standalone_v5_2/src下xscugic_intr.c)中有以下語(yǔ)句:

TablePtr = &(InstancePtr->Config->HandlerTable[InterruptID]);
if(TablePtr != NULL) {
    TablePtr->Handler(TablePtr->CallBackRef);
}

即當(dāng)TablePtr不為空時(shí)就執(zhí)行了InstancePtr->Config->HandlerTable[InterruptID]->Handler(InstancePtr->Config->HandlerTable[InterruptID]->CallBackRef);結(jié)合上一段說(shuō)明即執(zhí)行了SW_intr_Handler(1)或參數(shù)為2、3。

綜上,IRQ中斷產(chǎn)生后跳轉(zhuǎn)到0x18執(zhí)行B IRQHandler執(zhí)行,在IRQHandler下執(zhí)行bl IRQInterrupt;在函數(shù)IRQInterrupt中XExc_VectorTable[XIL_EXCEPTION_ID_IRQ_INT].Handler(XExc_VectorTable[XIL_EXCEPTION_ID_IRQ_INT].Data);經(jīng)過(guò)Xil_ExceptionRegisterHandler函數(shù)后即XScuGic_InterruptHandler(&INTCInst)再經(jīng)過(guò)XScuGic_Connect函數(shù)這也即SW_intr_Handler(1)或參數(shù)為2、3。最終IRQ中斷執(zhí)行了SW_intr_Handler函數(shù)。

編輯:hfy


聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • ARM
    ARM
    +關(guān)注

    關(guān)注

    134

    文章

    9027

    瀏覽量

    366484
  • Zynq
    +關(guān)注

    關(guān)注

    9

    文章

    607

    瀏覽量

    47101
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    什么是ARM中斷事件?ARM中斷異常處理具體過(guò)程

    ARM處理器是一種流行的處理器架構(gòu),用于許多現(xiàn)代移動(dòng)設(shè)備和嵌入式系統(tǒng)中。中斷和異常是ARM
    發(fā)表于 09-05 15:45 ?1767次閱讀
    什么是<b class='flag-5'>ARM</b><b class='flag-5'>中斷</b>事件?<b class='flag-5'>ARM</b><b class='flag-5'>中斷</b>異常<b class='flag-5'>處理</b>具體過(guò)程

    ARM處理器體系架構(gòu)詳細(xì)說(shuō)明

    本帖最后由 i2c 于 2014-10-13 16:10 編輯 ARM 體系結(jié)構(gòu)是構(gòu)建每個(gè) ARM 處理器的基礎(chǔ)。ARM
    發(fā)表于 10-13 16:08

    Cortex系列處理器是從ARM哪個(gè)架構(gòu)開(kāi)始的?

    Cortex系列處理器是從ARM哪個(gè)架構(gòu)開(kāi)始的?arm架構(gòu)和x86架構(gòu)有什么區(qū)別?
    發(fā)表于 07-06 10:49

    談?wù)勄度胧?b class='flag-5'>處理器的體系架構(gòu)

    當(dāng)我們談及嵌入式處理器體系架構(gòu)時(shí),一般都是想到Intel的X86架構(gòu)ARM公司的ARM
    發(fā)表于 12-15 06:59

    ARM處理器的特點(diǎn)及其架構(gòu)解析

    如下:1.3 ARM處理器系列1.3.1 Classic ARM Processors (經(jīng)典 ARM 處理器)?
    發(fā)表于 04-13 12:08

    基于ARM處理器的SOC系統(tǒng)講解

    處理器的區(qū)別。ARM體系架構(gòu)的發(fā)展體系架構(gòu)的定義:體系
    發(fā)表于 08-17 15:20

    ARM體系結(jié)構(gòu)、處理器和設(shè)備開(kāi)發(fā)文章

    ARM產(chǎn)品必須如何運(yùn)行的體系結(jié)構(gòu)規(guī)范。 此外,一些合作伙伴還授權(quán)實(shí)施符合架構(gòu)規(guī)范的自己的ARM處理器。 這導(dǎo)致了分層劃分為三個(gè)級(jí)別的規(guī)范,這
    發(fā)表于 08-21 07:28

    ARM處理器中斷處理的編程實(shí)現(xiàn)

    摘要:本文首先簡(jiǎn)要概述了ARM處理器的異常中斷種類(lèi)、響應(yīng)和返回過(guò)程;然后重點(diǎn)討論了中斷解析程序的原理和實(shí)現(xiàn),并分別給出了普通
    發(fā)表于 03-11 12:18 ?843次閱讀
    <b class='flag-5'>ARM</b><b class='flag-5'>處理器</b><b class='flag-5'>中斷</b><b class='flag-5'>處理</b>的編程實(shí)現(xiàn)

    ARM9系列微處理器軟件體系架構(gòu)工具

    本內(nèi)容提供了ARM9系列微處理器軟件體系架構(gòu)工具
    發(fā)表于 04-29 16:50 ?187次下載
    <b class='flag-5'>ARM</b>9系列微<b class='flag-5'>處理器</b>軟件<b class='flag-5'>體系</b><b class='flag-5'>架構(gòu)</b>工具

    ARM中斷處理的研究

    對(duì)ARM處理器的普通中斷處理、任務(wù)切換中斷處理、可重人中斷
    發(fā)表于 07-06 12:08 ?4246次閱讀
    <b class='flag-5'>ARM</b><b class='flag-5'>中斷</b><b class='flag-5'>處理</b>的研究

    ARM處理器編程模型之異常中斷處理分析

    3.4 異常中斷處理 異?;?b class='flag-5'>中斷是用戶(hù)程序中最基本的一種執(zhí)行流程和形態(tài)。這部分主要對(duì)ARM架構(gòu)
    發(fā)表于 10-18 13:29 ?1次下載

    淺談ARM處理器的特點(diǎn)和體系結(jié)構(gòu)

    ARM處理器包括ARM7、ARM9、ARM9E、ARM10E、SecurCore、以及Int
    發(fā)表于 04-03 11:17 ?1.7w次閱讀

    米爾科技ARM處理器體系架構(gòu)介紹

    ARM 體系結(jié)構(gòu)是構(gòu)建每個(gè) ARM 處理器的基礎(chǔ)。ARM 體系結(jié)構(gòu)隨著時(shí)間的推移不斷發(fā)展,其中包
    的頭像 發(fā)表于 11-20 10:04 ?4563次閱讀
    米爾科技<b class='flag-5'>ARM</b><b class='flag-5'>處理器</b><b class='flag-5'>體系</b><b class='flag-5'>架構(gòu)</b>介紹

    arm處理器有哪些中斷源?arm處理器對(duì)異常中斷的響應(yīng)過(guò)程

    arm處理器有哪些中斷源?arm處理器對(duì)異常中斷的響應(yīng)過(guò)程?
    的頭像 發(fā)表于 10-19 16:35 ?1360次閱讀

    中斷ARM體系中對(duì)中斷處理

    今天來(lái)看一下中斷ARM體系中對(duì)中斷處理,直接進(jìn)入正題。 中斷是指計(jì)算機(jī)運(yùn)行過(guò)程中,出現(xiàn)某些意
    的頭像 發(fā)表于 11-07 17:11 ?649次閱讀
    <b class='flag-5'>中斷</b>及<b class='flag-5'>ARM</b><b class='flag-5'>體系</b>中對(duì)<b class='flag-5'>中斷</b>的<b class='flag-5'>處理</b>