參考文獻
[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端的共享中斷,所以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開始增加。
PS端設計
我們前面說過PL共享中斷與軟中斷的區別,說他們兩個中斷初始化除了中斷編號完全一摸一樣,這裏同學們可以對比下面的代碼與上篇文章的代碼進行相互驗證。代碼如下:
#include <stdio.h>
#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共享中斷實驗成功執行,進而驗證了我們實驗的正確性。
總結
創作不易,認爲文章有幫助的同學們可以關注、點贊、轉發支持。爲行業貢獻及其微小的一部分。或者對文章有什麼看法或者需要更近一步交流的同學,可以加入下面的羣: