ZYNQ多中断冲突问题

转载原文地址:Xilinx-ZYNQ7000系列-学习笔记(28):ZYNQ多中断冲突问题Xilinx-ZYNQ7000系列-学习笔记(28):ZYNQ多中断冲突问题_赵小琛在路上的博客-优快云博客_zynq中断冲突

Xilinx-ZYNQ7000系列-学习笔记(28):ZYNQ多中断冲突问题
当PS端使用2个以上中断时,如果机械性地将两部分中断代码移植到一起,会出现只有最后初始化的中断能使用,前面的都不可用。
例如:初始化两个中断,(1)串口中断:接收到数则触发中断。(2)定时器中断:1s打印一个信息。

先初始化串口中断,后初始化定时器中断:

结果为只有定时器中断能用:


先初始化定时器中断,后初始化串口中断:


结果为只有串口中断能用:

这是因为两个中断的初始化同时使用了同一个指针,所以后初始化的中断使用的虽然是本身的变量,但指向了同一个内存,致使前一个初始化的中断被清空,所以只有后一个中断能够正常运行。修改方法为初始化两个中断时选用同一个XScuGic 实例指针。

譬如这里将定时器中断初始化的实例指针选用跟串口中断的相同:
这样两个就都能用了。


帮助到大家的话麻烦点个赞和关注哦,谢谢支持!
————————————————
版权声明:本文为优快云博主「赵小琛在路上」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/qq_42826337/article/details/121982178

### Zynq平台中中断嵌套的实现方式或问题解决 在Zynq平台上实现中断嵌套时,需要考虑中断控制器(XScuGic)的配置、优先级设置以及中断嵌套的硬件支持。以下是对实现方式及问题解决方法的详细说明。 #### 1. 中断控制器初始化 中断控制器的初始化是实现中断嵌套的基础。通过`XScuGic_LookupConfig()`函数获取中断控制器的配置信息,并使用`XScuGic_CfgInitialize()`函数完成初始化[^1]。此外,还需要调用`Xil_ExceptionInit()`和`Xil_ExceptionRegisterHandler()`将中断处理程序连接到ARM处理器的异常处理机制中[^2]。 ```c XScuGic_Config *IntcConfig; IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID); if (NULL == IntcConfig) { return XST_FAILURE; } Status = XScuGic_CfgInitialize(Intc, IntcConfig, IntcConfig->CpuBaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } Xil_ExceptionInit(); Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, Intc); Xil_ExceptionEnable(); ``` #### 2. 中断优先级触发类型设置 为了实现中断嵌套,必须正确设置每个中断源的优先级和触发类型。通过`XScuGic_SetPriorityTriggerType()`函数为每个中断源分配优先级和触发模式。优先级较高的中断可以在优先级较低的中断处理过程中被响应,从而实现中断嵌套[^3]。 ```c XScuGic_SetPriorityTriggerType(IntcTimer, TIMER_IRPT_INTR, 16, 1); // 设置优先级和触发类型 ``` #### 3. 中断连接使能 对于每个外设的中断,需要调用`XScuGic_Connect()`函数将中断对应的中断处理函数关联起来。然后通过`XScuGic_Enable()`函数使能该中断[^2]。 ```c XScuGic_Connect(IntcTimer, TIMER_IRPT_INTR, (Xil_ExceptionHandler)timer_callback, (void *)&TimerInstance); XScuGic_Enable(IntcTimer, TIMER_IRPT_INTR); ``` #### 4. 解决中断冲突问题Zynq平台上,如果中断共享同一个中断控制器实例指针,则可能导致后初始化的中断覆盖前一个中断的配置,从而引发中断冲突[^5]。为避免此类问题,应确保所有中断共用同一个`XScuGic`实例指针。 #### 5. 等待队列进程管理 当设备数据不可访问时,可以通过等待队列将当前进程挂起,直到中断处理程序唤醒该进程。使用`add_wait_queue()`函数将进程添加到等待队列中[^4]。 ```c wait_queue_head_t my_wait_queue; DECLARE_WAIT_QUEUE_HEAD(my_wait_queue); add_wait_queue(&my_wait_queue, &wait); set_current_state(TASK_INTERRUPTIBLE); schedule(); remove_wait_queue(&my_wait_queue, &wait); ``` #### 6. 示例代码 以下是一个完整的中断初始化示例: ```c #include "xscugic.h" #include "xparameters.h" #include "xil_exception.h" XScuGic InterruptController; int InitInterrupts() { int Status; XScuGic_Config *IntcConfig; // 初始化中断控制器 IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID); if (NULL == IntcConfig) { return XST_FAILURE; } Status = XScuGic_CfgInitialize(&InterruptController, IntcConfig, IntcConfig->CpuBaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } // 配置异常处理 Xil_ExceptionInit(); Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, &InterruptController); Xil_ExceptionEnable(); // 设置中断优先级和触发类型 XScuGic_SetPriorityTriggerType(&InterruptController, TIMER_IRPT_INTR, 16, 1); // 连接中断处理函数并使能中断 Status = XScuGic_Connect(&InterruptController, TIMER_IRPT_INTR, (Xil_ExceptionHandler)timer_callback, (void *)&TimerInstance); if (Status != XST_SUCCESS) { return XST_FAILURE; } XScuGic_Enable(&InterruptController, TIMER_IRPT_INTR); return XST_SUCCESS; } ``` ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值