本文以XIlinx ZCU102 UltraScale+ MPSoC作为实例,总结在学习嵌入式开过程中对中断系统或机制的理解。

ZYNQ其中包含FPGA、 Arm处理器以及与之相关的外设,是一款非常强大的SoC系统芯片。由于在科研项目中需要基于ZCU102开发一套数据传输系统用于粒子物理实验探测器前端数据的处理和传输。常规的方法便是完全直接通过FPGA(Programmable Logic, PL)进行汇编语言实现数据的存储和高速传输,而本课题尝试采用Programmable Logic(PL)和Process System(PS)协同开发数据获取系统。作为从未接触过FPGA开发或者嵌入式协同设计的物理学方向的研究僧,自学并尝试该设计实属不易,作此文为了更好记录学习过程。在最后以DMA中断循环做实例介绍。

什么是中断?

中断是计算机发展中一个重要的技术,它的出现很大程度上解放了CPU,提高了CPU的执行效率。
在中断出现之前,CPU对IO采用的是轮询的方式进行服务,这使的CPU纠结在某一个IO上,一直在等待它的响应,如果它不响应,CPU就在原地一直的等下去。这样就导致了其他IO口也在等待CPU的服务,如果某个IO出现了important or emergency affairs,CPU也抽不出身去响应这个IO。为了解决这个纠结的问题就------>出现了中断

中断控制的主要优点是只有在IO接口需要服务时才去响应它,使得CPU很淡定的做它自己的事情,只有IO口有需求的时候才去响应它。同时中断中也设计了中断优先级,来处理一些很紧急的事件。在任何的嵌入式系统设计中都离不开中断机制的使用,一般意思为处理器在运行程序过程中,遇到外部信号的干预(中断信号),致使处理器停止当前的程序运行,转而运行由中断指定的程序(函数),中断服务函数执行完毕后再返回主程序中执行先前暂定的程序。

1.所谓中断,是指CPU在正常运行程序时,由于程序的预先安排或内外部事件,引起CPU中断正在运行的程序,而转到发生中断事件程序中。这些引起程序中断的事件称为中断源。
其实从 物理学的角度看,中断是一种电信号,由硬件设备产生,并直接送入中断控制器(如 8259A)的输入引脚上,然后再由中断控制器向处理器发送相应的信号。处理器一经检测到该信号,便中断自己当前正在处理的工作,转而去处理中断。此后, 处理器会通知 OS 已经产生中断。这样,OS 就可以对这个中断进行适当的处理。不同的设备对应的中断不同,而每个中断都通过一个唯一的数字标识,这些值通常被称为中断请求线。

2.那么 当产生一个中断时,CPU是如何识别的呢?为了使处理器能识别每种中断源,给它们进行了编号----->叫做中断向量。比如在ZCU102中xczu9eg芯片支持:私有中断(每个CPU连接5个私有中断,中断ID27—31), 软件中断(16个,中断号:0—15。通过CPU私有总线向ICDSGIR寄存器写中断号,并且制定CPU), 共享中断(接收来自如GPIO、DMA、定时器等模块的中断信号。中断号32-95)。

3.异常和中断的区别:
1>异常:是指CPU内部出现的中断,即在CPU执行特定指令时出现的非法情况。同时异常也称为同步中断,因此只有在一条指令执行后才会发出中断 ,不可能在指令执行期间发生异常。

  1. 产生的原因:

程序的错误产生的(eg:除数为0)
内核必须处理的异常条件产生的(eg:缺页)

  1. 异常又分为故障和陷阱,它们都不使用中断控制器,也不能被屏蔽
  2. X86处理处理器中大约有20中异常。Linux内核必须为每种异常提供一个专门的异常处理程序。

2>中断:也称为异步中断。因此它是由其他硬件设备依照 CPU 时钟信号随机产生,即意味着中断能在指令之间发生。

  1. 中断又分为外部可屏蔽中断(INTR)和外部非屏蔽中断(NMI)

所用I0设备产生的中断请求均引起可屏蔽中断
硬件故障引起的故障则产生非屏蔽中断。

在CPU执行一个异常处理程序时,就不再响应其他异常和中断请求服务.那么如果此时发生了一个异常,CPU不能去响应它,又不能把它的信息丢失该怎么办呢?

这是就用到了堆栈,把所有的信息压入栈。等当前异常处理后,才从堆栈中取出信息再响应刚才的异常。(当产生多个非屏蔽中断时,CPU的处理方法同上)

ARM和ZYNQ中断机制

  • Arm中断体系
    ARM体系中,在存储地址的低位,固化了一个32字节的硬件中断向量表。异常中断发生时,程序计数器PC所指的位置不同,异常中断就不同。中断结束后,中断不同,返回地址也不同。但是,对于系统复位中断,不需要返回,因为整个应用系统就是从复位中断中开始的。ARM通常存在七种基本的中断处理(异常处理机制)。

    数据访问终止:数据访问的地址不存在,或者当前地址不允许访问。
    快速中断请求:外部引脚的快速中断请求,比外部中断请求等级高,但是一般外设的中断请求使用外部中断请求。
    指令预取终止:预取指令的地址不存在,或者当前地址不允许访问。
    未定义的指令:ARM或协处理器认为当前指令未定义。

    ARM基本中断流程如下图所示。从图中明显可以看出,在主程序中发生IRQ中断请求,程序跳转到中断向量表中查找IRQ中断对应的解析程序地址,也就是根据地址进入到中断服务函数(中断解析程序),执行服务函数之后将中断返回,并最终返回进入到主程序。

  • ZYNQ中断体系
    ZYNQ芯片中包含有Programmable Logic和Processing System,因此其中包含丰富的中断系统,

    私有中断: 每个CPU连接着5个私有中断,中断ID分别为27-31.

    软件中断:总共有16个,中断号:0—15。通过CPU私有总线向ICDSGIR寄存器写中断号,并且制定CPU。
    共享中断:接收来自如GPIO、DMA、定时器等模块的中断信号。中断号32-95。
    所有中断的关系如下图所示:

ZYNQ中断过程实现

中断系统的使用总是与相应的设备相联系的通用中断控制器(GIC)初始化和配置, 连接GIC、中断ID和回调函数, 使能中断, Arm中断异常处理。下面是DMA环通测试例子:
其中XAxiDma_Setup是最主要的函数,包括DMA设备配置信息;SetupInterruptInt是中断系统设置函数,包含XScuGic通用中断控制器的配置,连接DMA 中断和中断服务函数,Arm异常处理;CheckData是中断服务函数,每次主程序中断后,将执行此函数。

#include "xaxidma.h"
#include "xparameters.h"
#include "xil_printf.h"
#include "xscugic.h"#define DMA_DEV_ID        XPAR_AXIDMA_0_DEVICE_ID
#define INT_DEVICE_ID   XPAR_SCUGIC_SINGLE_DEVICE_ID
#define INTR_ID         XPAR_FABRIC_AXI_DMA_0_S2MM_INTROUT_INTR#define FIFO_DATABYTE    4
#define TEST_COUNT      80
#define MAX_PKT_LEN     TEST_COUNT*FIFO_DATABYTE#define TEST_START_VALUE 0xC#define NUMBER_OF_TRANSFERS 2/*-------------- Function Declaration --------------------*/
int XAxiDma_Setup(u16 Device_Id);
static int CheckData(void);
int SetupInterruptInit(XScuGic *InstacnePtr, u16 IntrId, XAxiDma *XAxiDmaPtr);/* Interrupt and DMA instance */
XScuGic INST;
XAxiDma AxiDma;/** Define the Transfer and Receive Array* Their memory are allocated inside DDR3.* Because Cache is used between CPU and Memory DDR3.*/
u8 TXBufferPtr[MAX_PKT_LEN];
u8 RXBufferPtr[MAX_PKT_LEN];int main()
{int Status;xil_printf("\r\n--- Entering main() --- \r\n");/* Main DMA Interrupt Loop function */Status = XAxiDma_Setup(DMA_DEV_ID);if (Status != XST_SUCCESS){xil_printf("XAxiDma Test Failed\r\n");return XST_FAILURE;}xil_printf("Successfully Ran XAxiDma Test\r\n");xil_printf("--- Exiting main() --- \r\n");return XST_SUCCESS;
}int XAxiDma_Setup(u16 Device_Id)
{XAxiDma_Config *CfgPtr;int Status;int Tries = NUMBER_OF_TRANSFERS;int Index;u8 Value;/* Initialize the DMA Device */CfgPtr = XAxiDma_LookupConfig(Device_Id);xil_printf("DeviceId Address %p : %d\r\n", &(CfgPtr->DeviceId), CfgPtr->DeviceId);if (!CfgPtr){xil_printf("No configuration found for %d\r\n", Device_Id);return XST_FAILURE;}Status = XAxiDma_CfgInitialize(&AxiDma, CfgPtr);xil_printf("XAxiDma Memory Length: %d\r\n", sizeof(XAxiDma));if (Status != XST_SUCCESS){xil_printf("Initialization failed %d\r\n", Status);return XST_FAILURE;}// Read the value in memory//xil_printf("SG Check : %d\r\n", (&AxiDma)->HasSg);// Read the address in memory for XAxiDma Structurexil_printf("RegBase Address %p : %d\r\n", &(AxiDma.RegBase), (&AxiDma)->RegBase); // Virtual address has no meaningful valuexil_printf("HasMm2S Address %p : %d\r\n", &(AxiDma.HasMm2S), AxiDma.HasMm2S);xil_printf("HasS2Mm Address %p : %d\r\n", &(AxiDma.HasS2Mm), AxiDma.HasS2Mm);xil_printf("Initialized Address %p: %d\r\n", &(AxiDma.Initialized), AxiDma.Initialized);xil_printf("SG Mode Address %p : %d\r\n", &(AxiDma.HasSg), (&AxiDma)->HasSg);/* Check if SG mode is used from the DMA Configuration file */if (XAxiDma_HasSg(&AxiDma)){xil_printf("Device configured as SG mode \r\n");return XST_FAILURE;}/** This is an MAIN interrupt system setup function* including initialization, interrupt id,* interrupt handler and exception handler*/Status = SetupInterruptInit(&INST, INTR_ID, &AxiDma);if (Status != XST_SUCCESS){return XST_FAILURE;}/* Disable MM2S interrupt, Enable S2MM interrupt (Control Register)*//* xaxidma_hw.h @ BitMasks for Interrupts* These masks are shared by XAXIDMA_CR_OFFSET register and XAXIDMA_SR_OFFSET register* which means XAXIDMA_IRQ_MASK (register address can be used in CR and SR)*//* Enable Completion Interrupt* DataFIFO write data to DMA so DEVICE_TO_DMA(DataFIFO->DMA) interrupt need to be enabled* After writing finished, DataFIFO will generate an interrupt to DMA.*/XAxiDma_IntrEnable(&AxiDma, XAXIDMA_IRQ_IOC_MASK, XAXIDMA_DEVICE_TO_DMA);// Close All Interrupt  (Completion, Delay, Error)/* Even if DMA transfer data to DataFIFO, It is not necessary* to occur one interrupt, thus the DMA_TO_DEVICE(DMA->DataFIFO) is disabled.*/XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DMA_TO_DEVICE);/** Write the data to the Cache that means* the initialization of TXBufferPtr (Note: NOT in the Memory)* CPU and DDR3 communicate through Cache,* so the initialized data maybe be saved into Cache.* By Loop to initialize, it is possible that the data don't save into DDR3.** So It must flush the data inside Cache to the DDR3 by Xil_DCacheFlushRange.* This flush function need two parameters: Memory Address and Length.*/Value = TEST_START_VALUE;for (Index=0; Index < MAX_PKT_LEN; Index++){TXBufferPtr[Index] = Value;Value = (Value + 1) & 0xFF;}/** Flush the Data cache for the given address range* before the DMA transfer in case the data cache is enabled.*/Xil_DCacheFlushRange((UINTPTR)TXBufferPtr, MAX_PKT_LEN);Xil_DCacheFlushRange((UINTPTR)RXBufferPtr, MAX_PKT_LEN);for (Index=0; Index < Tries; Index++){/** Open MM2S Channel* Data inside TXBufferPtr are save in Memory DDR3 by FlushRange function* DMA read the data from DDR3 and write them to DataFIFO.* Because XAxiDma_IntrDisable close all of interrupts,* this function cannot generate one interrupt which embodies* that CheckData function is not called.*/Status = XAxiDma_SimpleTransfer(&AxiDma, (UINTPTR)TXBufferPtr,MAX_PKT_LEN, XAXIDMA_DMA_TO_DEVICE);if (Status != XST_SUCCESS){return XST_FAILURE;}/** Open S2MM Channel* DataFIFO transfer the data to DMA, and then send data to RXBufferPtr* RXBufferPtr address are in DDR3 Memory.** Transfer finished.**/Status = XAxiDma_SimpleTransfer(&AxiDma, (UINTPTR)RXBufferPtr,MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA);if (Status != XST_SUCCESS){return XST_FAILURE;}while((XAxiDma_Busy(&AxiDma, XAXIDMA_DEVICE_TO_DMA)) ||(XAxiDma_Busy(&AxiDma, XAXIDMA_DMA_TO_DEVICE)) ){/* Wait for minutes */}}return XST_SUCCESS;
}/** Interrupt system setup function is mainly used to make the connections* between instantiated DMA and GIC(General Interrupt Controller)*/
int SetupInterruptInit(XScuGic *InstancePtr, u16 IntrId, XAxiDma *XAxiDmaPtr)
{XScuGic_Config *Config;int Status;/* Lookup the device according to the INTR_DEVICE_ID */Config = XScuGic_LookupConfig(INT_DEVICE_ID);Status = XScuGic_CfgInitialize(&INST, Config, Config->CpuBaseAddress);if (Status != XST_SUCCESS){return XST_FAILURE;}/** The connection function for GIC instance, Intr_Id,* Interrupt Handler function and DMA Instance*/Status = XScuGic_Connect(InstancePtr, IntrId,(Xil_ExceptionHandler)CheckData,XAxiDmaPtr);if (Status != XST_SUCCESS){return XST_FAILURE;}XScuGic_Enable(InstancePtr, IntrId);/** Each interrupt system must use the ARM exception handler function* It involves the initialization, register and enable for ARM exception.*/Xil_ExceptionInit();Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,InstancePtr);Xil_ExceptionEnable();return XST_SUCCESS;}/** This is a interrupt handler function that means* the CheckData function will be invoked when an interrupt event occur.*/
static int CheckData(void)
{u8 *RxPacket;int Index = 0;u8 Value;RxPacket = RXBufferPtr;Value = TEST_START_VALUE;xil_printf("Enter interrupt: \r\n");xil_printf("each interrupt will call this function one time!!!\r\n");/* Clear the interrupt *//** MM2S Status register: bit 12, 13, 14 represent interrupt status, 1 means clear.* XAXIDMA_IRQ_IOC_MASK(0x00001000 == 0001 0000 0000 0000 )  => Course S2 page 245* means the address for completion interrupt at the twelfth(shi er bit) bit.** Write the value XAXIDMA_DEVICE_TO_DMA (0x01) to clear the interrupt.**/XAxiDma_IntrAckIrq(&AxiDma, XAXIDMA_IRQ_IOC_MASK, XAXIDMA_DEVICE_TO_DMA);/** Invalidate the Data cache for the given address range.* But the transfered data has been wrote to the DDR3, thus* Invalidate data cache doesn't have any bad influence.*/Xil_DCacheInvalidateRange((UINTPTR)RxPacket, MAX_PKT_LEN);/** Data inside RXBufferPtr is saved in DDR3* which are transfered to DDR3 by DMA (DataFIFO -> DMA -> DDR3)*/for (Index=0; Index<MAX_PKT_LEN; Index++){if (RxPacket[Index] != Value){xil_printf("Data Error %d : %x/%x\r\n",Index, (unsigned int)RxPacket[Index], (unsigned int)Value);return XST_FAILURE;}Value = (Value + 1) & 0xFF;}return XST_SUCCESS;
}

部分信息参考来源:

电子网赛灵思创新论坛:http://xilinx.eetrend.com/content/2019/100045024.html
CSDN中断原理:https://blog.csdn.net/aobama12/article/details/61632815

中断机制及ZCU102 DMA中断实例相关推荐

  1. 17. GD32F103C8T6入门教程-adc 使用教程2-dma+连续扫描方式采集数据++dma中断通知

    adc 使用教程3-dma方式采集数据+dma中断通知 adc 的扫描模式就是把配置了规则或注入通道按照配置的顺序采集一轮 adc 的连续转换模式就是把配置了规则或注入通道按照配置的顺序采集N轮 1. ...

  2. STM32CubeMX实现串口DMA中断通信

    文章目录 一. 环境 二. 使用STM32CubeMX 三. USART DMA中断通信 1. UART函数库介绍 2. 编写代码 3. 最终效果 四. 软件调试 五. 总结 一. 环境 硬件:stm ...

  3. GD32E230F6p6的串口DMA中断收发及printf

    GD32E230F6p6的串口DMA中断收发及printf 简介 一.初始化配置 选择DMA通道 头文件 串口&DMA初始化 二.串口DMA收发及printf DMA发送 DMA收发中断处理 ...

  4. 单片机I/O控制方式(UART中断和DMA中断的区别)

    目录 1.程序循环检测方式 2.中断驱动方式 3.直接内存访问方式 单片机I/O设备的控制方式主要有三种:程序循环检测.中断驱动和直接内存访问. 1.程序循环检测方式 程序循环检测方式的基本思路是:在 ...

  5. 设备树之GPIO和中断实例

    概述 设备树不仅仅描述常规硬件信息,还可以描述中断,GPIO,DMA,PINCTRL,时钟,电源管理等内核基础设施信息及其使用情况,下面重点介绍中断,GPIO等结点属性 中断控制器 对于中断控制器结点 ...

  6. 基于STM32F051K8芯片以DMA中断方式控制LED灯(手把手教学)

    DMA基础知识 DMA定义 DMA传输方式 实验 实验目的 cubemx 配置 kail5打开,将代码写入 实验现象 DMA基础知识 DMA,全称Direct Memory Access,即直接存储器 ...

  7. ZYNQ MPSoc 多DMA传输实例

    使用环境:Vivado 2020.1,Vitis 2020.1 使用开发板:ZYNQ MPSoc 15EG Demo Vivado 工程 双DMA回环 开启SG模式,双DMA控制器,开启四个中断. V ...

  8. STM32F051K8U6按键中断实例

    引言 最近要开始做毕设了,准备用STM32做一个平衡小车,好久没做过STM32的裸机项目了,做几个项目练练手,复习一下.本例程使用STM32CubeMX配套hal库来实现按键中断和串口中断.芯片用的是 ...

  9. STM32-HAL库串口DMA空闲中断的正确使用方式+解析SBUS信号

    STM32-HAL库串口DMA空闲中断的正确使用方式+解析SBUS信号 一. 问题描述 二. 方法一--使用HAL_UART_Receive_DMA 三. 方法二--使用HAL_UARTEx_Rece ...

最新文章

  1. 如何卸载office201032位_Office 2010如何手动卸载?
  2. python itertools product函数
  3. 02 - Unit07:显示笔记下拉菜单、笔记的分享功能、笔记的删除功能
  4. Android APK反编译 apktool使用教程
  5. linux之which命令
  6. HDU5391威尔逊定理
  7. PHP检查微信域名屏蔽接口,微信域名检测API接口,实时查询域名是否被微信拦截...
  8. Mac 设置 NDK
  9. linux开源软件_为什么要使用Linux和开源软件?
  10. 凝血超声手术室行业调研报告 - 市场现状分析与发展前景预测
  11. 微信雄踞,头条社交梦破碎?| 畅言
  12. HashMap 在 JDK 1.8 中新增的数据结构 – 红黑树
  13. C语言程序的开发过程
  14. 随机微分方程学习笔记04 Ito公式
  15. 自动更新纯真IP数据库
  16. 做短视频自媒体,常用工具和素材网站分享,新手小白收藏抓紧行动
  17. 一家有两个孩子,已知至少有一个孩子是在星期二出生的男孩。问:两个孩子都是男孩的概率是多大?
  18. Python爬虫:博客被抄袭了还不知道?快来查查
  19. 攻防世界-web shrine
  20. 快@你的好兄弟好姐妹来内卷进程状态

热门文章

  1. 协议和协议栈的区别?
  2. 无偏性、有效性、一致性
  3. CNN Application
  4. 无法打开“kdiff3”,因为Apple无法检查其是否包含恶意软件。
  5. 即将到来的量子计算时代,其商业应用价值在哪里?
  6. 【2023最新】32个web前端实战项目,练完即可就业,从入门到进阶,基础到框架,你想要的全都有,建议码住!
  7. bootstrap-table固定表头固定列
  8. Opencv实践应用之答题卡处理
  9. 掌控板+Mixly+MixIO 初试物联网-摇杆篇
  10. 快捷键大全---windows , idea , linux , 浏览器