新手入门
- 积分
- 8
- 金钱
- 8
- 注册时间
- 2020-8-7
- 在线时间
- 2 小时
|
1金钱
本帖最后由 shaowq 于 2021-11-14 19:12 编辑
开发版:正点原子领航者V1 + ZYNQ7020
开发环境:Vivado 2019.2 + Vitis 2019.2
软件环境:裸机(无OS)
开发需求:1. 在软中断中,执行大量的运算处理。(中断优先级低)
2. 在GPIO中断中,执行少量处理。(中断优先级高)
3. 在软中断的执行过程中,如果发生GPIO中断,暂停软中断的执行,优先执行GPIO中断。
即,高优先级中断要打断(抢占)低优先级的中断。
问题点:为实现上述需求,通过 XScuGic_SetPriorityTriggerType 函数将软中断的优先级设为 0xC0,
将GPIO中断的优先级设为0x80。
但程序跑起来后发现,GPIO中断并不能打断软件中断,而是等软中断执行完成后再执行。
想请教大神,ZYNQ的中断是否可以嵌套?高优先级中断是否可以打断(抢占)低优先级中断?
如果可以嵌套,可以打断(抢占)低优先级中断,那是不是下面的中断配置有问题。
或者,有没有哪位大神发一个可以测试中断嵌套的参考代码。
中断配置代码(无法实现嵌套,打断):
//建立中断系统,使能KEY按键的下降沿中断
// @param GicInstancePtr是一个指向XScuGic驱动实例的指针
// @param gpio是一个指向连接到中断的GPIO组件实例的指针
// @param GpioIntrId是Gpio中断ID
// @return 如果成功返回XST_SUCCESS, 否则返回XST_FAILURE
int setup_interrupt_system(XScuGic *gic_ins_ptr, XGpioPs *gpio, u16 GpioIntrId)
{
u8 nIntId;
u8 nPriority;
u8 nTrigger;
u32 nICCPMR;
int status;
XScuGic_Config *IntcConfig; //中断控制器配置信息
//查找中断控制器配置信息并初始化中断控制器驱动
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
if (NULL == IntcConfig) {
return XST_FAILURE;
}
status = XScuGic_CfgInitialize(gic_ins_ptr, IntcConfig,
IntcConfig->CpuBaseAddress);
if (status != XST_SUCCESS) {
return XST_FAILURE;
}
//设置并使能中断异常
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler) XScuGic_InterruptHandler, gic_ins_ptr);
Xil_ExceptionEnable();
//为GPIO中断设置中断处理函数
status = XScuGic_Connect(gic_ins_ptr, GpioIntrId,
(Xil_ExceptionHandler) intr_handler_gpio, (void *) gpio);
if (status != XST_SUCCESS) {
return status;
}
//为GPIO中断设置优先级
XScuGic_GetPriorityTriggerType(gic_ins_ptr, GpioIntrId, &nPriority, &nTrigger);
XScuGic_SetPriorityTriggerType(gic_ins_ptr, GpioIntrId, 0x80, nTrigger);
//使能来自于Gpio器件的中断
XScuGic_Enable(gic_ins_ptr, GpioIntrId);
//设置KEY按键的中断类型为下降沿中断
XGpioPs_SetIntrTypePin(gpio, KEY, XGPIOPS_IRQ_TYPE_EDGE_FALLING);
//使能按键KEY中断
XGpioPs_IntrEnablePin(gpio, KEY);
//为软中断(IRQ ID:15)设置中断处理函数
XScuGic_Connect(gic_ins_ptr, 15, (Xil_ExceptionHandler)intr_handler_soft, (void *)gic_ins_ptr);
//为软中断(IRQ ID:15)设置优先级
XScuGic_GetPriorityTriggerType(gic_ins_ptr, 15, &nPriority, &nTrigger);
XScuGic_SetPriorityTriggerType(gic_ins_ptr, 15, 0xC0, nTrigger);
//使能软中断
XScuGic_Enable(gic_ins_ptr, 15);
return XST_SUCCESS;
}
|
最佳答案
查看完整内容[请看2#楼]
通过这两天的调查,终于有了结果。
首先,说下结论。
ZYNQ的中断是可以嵌套的,也就是说,高优先级中断是否可以打断(抢占)低优先级中断的。
然后,上面的代码中,对于中断优先级的配置也没有问题,只是,在执行中断处理函数时,CPU处于IRQ模式,此模式下无法实现中断嵌套。
所以,需要在中断处理函数开始的地方调用 Xil_EnableNestedInterrupts(),使CPU进入系统模式,在中断处理函数结束的地方,调用Xil_DisableNestedInt ...
|