中断
理论部分:在黑金pdf的11.1中断控制器和计数器
1.PL
板子上使能中断,好像不用再加中断的ip。
2.PS
都要通过DIC(中断控制器)
(1)dma有个中断,但dma由cpu控制,dma中断不用手动连在ps上。见dma。
(2)PL中断请求
(以下内容来自 https://blog.csdn.net/u014485485/article/details/79059095)
按键中断实例+总结,里面还有一些使用表格,妙!
os学的中断就是(大概):接受中断信号(硬件上是啥),屏蔽其他中断,保护现场,分析中断,跳入中断处理程序。。。
注意触发方式!pos还是neg,低有效还是高有效!!
中断触发有固定的处理顺序,现阶段我们能看懂函数功能,会改就可以了。 XScuGic //产生一个中断控制器实例 XScuGic_Config //中断控制器配置实例 XScuGic_LookupConfig //找到scugic实体 XScuGic_CfgInitialize //初始化scugic Xil_ExceptionRegisterHandler //Xilinx提供的通用异常处理程序,中断触发之后统一由XScuGic_InterruptHandler先处理,然后在HandlerTable中查找相应的处理函数 Xil_ExceptionEnable //使能异常处理 XScuGic_Connect //连接到我们自己定义的中断处理函数 XScuGic_Enable //使能我们设立的中断实例 这里我们设置的中断处理函数是:一旦按键按下,串口打印出相关信息: static void SW_intr_Handler(void *param){ int sw_id = (int)param; printf("SW%d int\n\r", sw_id); } --------------------- 作者:ChuanjieZhu 来源:CSDN 原文:https://blog.csdn.net/u014485485/article/details/79059095 版权声明:本文为博主原创文章,转载请附上博文链接!
代码阅读:没看懂怎么用的dout,什么时候访问了irq_f2p?那是和什么连的?通过什么接受的?是不是只有连上才能时时监测dout的变化?
但代码哪里用了吗?为什么要把dout连到irq那里?
应该是中断口连在了中断寄存器上,read终端寄存器得到输入,然后操作一番迎合中断寄存器的触发方式,出发后跳到中断处理程序。
https://blog.csdn.net/husipeng86/article/details/52206439:分析具体过程
#include <stdio.h> #include "xscugic.h" #include "xil_exception.h" #define INT_CFG0_OFFSET 0x00000C00 //寄存器0的地址?配中断寄存器使 #define SW1_INT_ID 61 //中断寄存器号,61是公用的 #define SW2_INT_ID 62 #define INTC_DEVICE_ID XPAR_PS7_SCUGIC_0_DEVICE_ID//我一直找不到这些id在哪里 #define INT_TYPE_RISING_EDGE 0x03 #define INT_TYPE_HIGHLEVEL 0x01 #define INT_MASK 0x03 static XScuGic INTCInst;//实例化中断控制器 static void SW_intr_Handler(void *param);//自定义的函数声明 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_MASK; mask = XScuGic_DistReadReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4); mask &= ~(INT_MASK << (intId%16)*2); mask |= intType << ((intId%16)*2); //写中断寄存器,mask是data //是一旦reg不是1就算作发生中断了吗??看表,按表写!! XScuGic_DistWriteReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4, mask); } //中断设置的主函数 int IntcInitFunction(u16 DeviceId){ //声明设备数据结构体指针 XScuGic_Config *IntcConfig; int status; //找出数据结构,用这个结构体初始化inst实例 //这里纯套路,没有个性化逻辑 IntcConfig = XScuGic_LookupConfig(DeviceId); status = XScuGic_CfgInitialize(&INTCInst, IntcConfig, IntcConfig->CpuBaseAddress); if(status != XST_SUCCESS) return XST_FAILURE; // Call to interrupt setup //初始化登记函数?handler应该是分发代码 Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, //头文件的宏定义 (Xil_ExceptionHandler)XScuGic_InterruptHandler, //这是一个库函数 &INTCInst);//本文件的inst实例(*data。这些参数啥意思?直接抄就行? Xil_ExceptionEnable();//使能 //将自定义的中断寄存器接入handler,填表 // Connect SW1~SW3 interrupt to handler status = XScuGic_Connect(&INTCInst, SW1_INT_ID, (Xil_ExceptionHandler)SW_intr_Handler,//自定义的中断处理函数 (void *)1);//这个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; // Set interrupt type of SW1~SW3 to rising edge //自定义的函数,设置触发方式,和自定义的线和逻辑联系在一起 //结合上面的,可以理解成监测函数,一旦发现就写中断reg,让cpu发现,开始调用handler IntcTypeSetup(&INTCInst, SW1_INT_ID, INT_TYPE_RISING_EDGE); IntcTypeSetup(&INTCInst, SW2_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); return XST_SUCCESS; } int main(void){ printf("PL int test\n\r"); IntcInitFunction(INTC_DEVICE_ID); while(1); return 0; }
2.sd自带的中断教程:在Main函数里首先初始化LED和GPIO,并配置它们的输入输出方向和LED灯初值。然后调用中断初始化话程序IntcInitFunction,在中断初始化话程序里,先初始化中断控制器并建立中断,再注册GPIO中断和中断调用函数数,最后是使能中断。:
流程:初始化中断控制器==》建立中断==》注册特定的中断==》写中断处理函数。