基於ZYNQ的中斷的使用(1)

參考文獻

[1]、V3學院
[2]、 judyzhong

項目簡述

接觸過單片機、ARM的同學應該都瞭解中斷,因爲這是保證CPU實時性的前提。學到這裏的同學會不免發出疑惑,爲什麼FPGA沒事有實時性的要求呢,因爲FPGA本身就是併發執行,這也是其本身最重要的特性。ZYNQ中有兩個CPU,又分爲不同的中斷類型,將在下面的文章中一一介紹。如果學不會中斷,那麼ZYNQ的學習將沒有意義。

工程描述:運行ZYNQ的兩個ARM核,利用ZYNQ的軟中斷,用CPU0中斷CPU1,同時CPU1中斷CPU0。

本次實驗所用到的軟硬件環境如下:
1、VIVADO 2019.1
2、米聯客MZ7015FA開發板

ZYNQ中斷描述

ZYNQ中的中斷主要包括三種類型,如下:
在這裏插入圖片描述
從上面可以看出三種終端類型包括:
1.軟件中斷(SGI,Software generatedinterrupts,中斷號0-15)(16–26 reserved) :被路由到一個或者兩個CPU上,通過寫ICDSGIR寄存器產生SGI.
2.私有外設中斷(PPI,private peripheralinterrupts ,中斷號27-31):每個CPU都有一組PPI,包括全局定時器、私有看門狗定時器、私有定時器和來自PL的FIQ/IRQ.
3.共享外設中斷(SPI,shared peripheralinterrupts,中斷號32-95):由PS和PL上的各種I/O控制器和存儲器控制器產生,這些中斷信號被路由到相應的CPU. 其中共享中斷包括外設中斷和PL中斷

中斷控制器(GIC,generic interrupt controller ):用於集中管理從PS和PL產生的中斷信號的資源集合。控制器可以使能、關使能、屏蔽中斷源和改變中斷源的優先級,並且會將中斷送到對應的CPU中,CPU通過私有總線訪問這些寄存器。

PL和PS之間的中斷有:
在這裏插入圖片描述
兩個CPU都具有各自16個軟件中斷,CPU可以中斷自己,也可以中斷其他CPU,上升沿觸發,不可修改
在這裏插入圖片描述
CPU的私有中斷,這些中斷都是固定死的,不能修改:
在這裏插入圖片描述
共享中斷就是一些端口共用一箇中斷請求線, PL部分有16個共享中斷,他們的觸發方式可以設置
在這裏插入圖片描述
這些中斷的使用在接下來的文章中都會進行相應的講解,本篇文章我們主要講解軟中斷,軟中斷CPU可以中斷自己,也可以中斷其他CPU,上升沿觸發,不可修改。

ZYNQ中斷的整個註冊流程如下,上面三種類型的中斷都遵循下面的過程,只是稍許細節不一樣,詳細的情況可以觀察我們下面給出的代碼:
在這裏插入圖片描述

PL端設計

因爲我們這篇文章主要講解兩個CPU之間的中斷,那麼關於PL側的設計將沒有什麼重要設計,只需要例化相應的ZYNQ IP核,然後分配相應的DDR3即可。相應的Block Design如下:
在這裏插入圖片描述

PS端設計

這裏因爲要跑雙核程序,那麼就需要進行相應的設置,詳細的設置可以觀察博主的這篇文章基於ZYNQ的雙核CPU之間的通信,注意這裏的設置特別重要,否則ZYNQ的雙核無法正常工作。

CPU0代碼

這裏我們廢話不多說直接給出CPU0的代碼:
這裏使用了13,14軟中斷

#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 0x0d
#define CPU1_SW_INTR 0x0e

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){
		usleep(100000);
		XScuGic_SoftwareIntr(&ScuGic,CPU1_SW_INTR,XSCUGIC_SPI_CPU1_MASK);
	}
    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("cpu1 interrupt cpu0 success! \n\r");
}

這裏需要特別注意軟中斷的觸發函數:
在這裏插入圖片描述
第二個參數是軟中斷編號,第三個參數是CPU編號。

CPU1代碼

CPU1的代碼如下:

#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 0x0d
#define CPU1_SW_INTR 0x0e

static XScuGic ScuGic;
static XScuGic_Config * ScuGicCfgPtr;

//initial gic & software intr
int initSwIntr();
//callback func
void cpu1IntrHandler(void * callbackref);

int main()
{
		int status;
		status = initSwIntr();
		if(status != XST_SUCCESS){
			return status;
		}
		while(1){
			XScuGic_SoftwareIntr(&ScuGic,CPU0_SW_INTR,XSCUGIC_SPI_CPU0_MASK);
			usleep(100000);
		}

    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,CPU1_SW_INTR,(Xil_ExceptionHandler)cpu1IntrHandler,&ScuGic);
	if(status != XST_SUCCESS){
			return status;
	}
	XScuGic_Enable(&ScuGic,CPU1_SW_INTR);
	Xil_ExceptionEnable();
	return XST_SUCCESS;
}


void cpu1IntrHandler(void * callbackref){
	printf("cpu0 interrupt cpu1 success! \n\r");
}

這裏特別提醒何爲中斷,中斷的頻率肯定不會太高,因爲那樣就不是中斷了,當頻率特別高的時候中斷會因爲響應不及時而出現錯誤。

測試結果

我們將代碼進行雙核運行的必要控制,並且下板可以觀察到如下現象:
在這裏插入圖片描述
從上面的實驗結果我們可以看出我們的軟中斷實驗成功執行,進而驗證了我們實驗的正確性。

總結

創作不易,認爲文章有幫助的同學們可以關注、點贊、轉發支持。爲行業貢獻及其微小的一部分。或者對文章有什麼看法或者需要更近一步交流的同學,可以加入下面的羣:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章