[1].V3学院
前面的一篇文章我们已经讲解了ZYNQ中软中断的使用,通过学习CPU之间的相互中断,我们已经学习了软中断,那么接下来我们将进行共享中断的学习,从上一篇文章我们可知,共享中断主要分为两类:PL给CPU的中断,PS的IO中断。这里提醒读者一定要看上一篇文章,否则学习会特别困难。
工程描述:PL每隔1s发起中断信号,PS接收终端并通过串口打印信息。
本次实验所用到的软硬件环境如下:
1、VIVADO 2019.1
2、米联客MZ7015FA开发板
这里为了清晰表述,再次引入中断分类:
从上面可以看出共享中断分为PL的中断和PS的IO中断,然后下面的共享中断的详细情况:
其实这里博主说明,PL共享中断的初始化与软中断的初始化除了中断编号不同完全一摸一样,我们甚至连代码都没进行相应的更改。这里还有一点不一样,软中断的触发是由CPU掉一哦那个函数触发的,而PL端的共享中断是PL端给出的信号。
因为这次我们使用的是PL端的共享中断,所以PL端会产生中断信号,这里需要注意这里的中断信号不要太短,太短的话PS端根本接收不到这个信号,尤其高电平触发中断的情况下,这里我们实验中中断信号拉高了200个时钟周期。代码如下:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : [email protected]
// Website : https://blog.csdn.net/zhangningning1996
// Module Name : intr.v
// Create Time : 2020-06-23 21:36:42
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module intr(
input sclk ,
input rst_n ,
output reg flag
);
//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
parameter DELAY_1S = 100000000-1 ;
reg [29:0] cnt ;
//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
cnt <= 30'd0;
else if(cnt == DELAY_1S)
cnt <= 30'd0;
else
cnt <= cnt + 1'b1;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
flag <= 1'b0;
else if(cnt > DELAY_1S-200)
flag <= 1'b1;
else
flag <= 1'b0;
endmodule
将上述代码进行相应的封装IP操作。
整个Block Design的设计图如下:
同学们这里需要注意,因为PL端我们没办法指定中断编号,所以PL共享中断默认是从61开始增加。
我们前面说过PL共享中断与软中断的区别,说他们两个中断初始化除了中断编号完全一摸一样,这里同学们可以对比下面的代码与上篇文章的代码进行相互验证。代码如下:
#include
#include "xscugic.h"
#include "xparameters.h"
#include "sleep.h"
#define GIC_ID XPAR_PS7_SCUGIC_0_DEVICE_ID
#define CPU0_SW_INTR 61
static XScuGic ScuGic;
static XScuGic_Config * ScuGicCfgPtr;
//initial gic & software intr
int initSwIntr();
//callback func
void cpu0IntrHandler(void * callbackref);
int main()
{
int status;
status = initSwIntr();
if(status != XST_SUCCESS){
return status;
}
while(1){
}
return 0;
}
int initSwIntr(){
int status;
Xil_ExceptionInit();
ScuGicCfgPtr = XScuGic_LookupConfig(GIC_ID);
status = XScuGic_CfgInitialize(&ScuGic,ScuGicCfgPtr,ScuGicCfgPtr->CpuBaseAddress);
if(status != XST_SUCCESS){
return status;
}
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,&ScuGic);
status = XScuGic_Connect(&ScuGic,CPU0_SW_INTR,(Xil_ExceptionHandler)cpu0IntrHandler,&ScuGic);
if(status != XST_SUCCESS){
return status;
}
XScuGic_Enable(&ScuGic,CPU0_SW_INTR);
Xil_ExceptionEnable();
return XST_SUCCESS;
}
void cpu0IntrHandler(void * callbackref){
printf("pl interrupt ps success! \n\r");
}
这里饿哦们只使用了一个CPU,所以这里的代码设计是比较简单的。与上面一篇文章的中断也几乎一摸一样。
将代码下板可以观察到如下现象:
从上面的实验结果我们可以看出我们的PL共享中断实验成功执行,进而验证了我们实验的正确性。
创作不易,认为文章有帮助的同学们可以关注、点赞、转发支持。为行业贡献及其微小的一部分。或者对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群: