ZYNQ基本使用(4) 中断 -- 私有定时器中断

article/2025/11/10 19:19:24

目录

 

中断

中断简介

私有、共享和软中断

通用中断控制器GIC

复位和时钟

模块图

CPU中断信号直通

功能说明

软件生成的中断 SGI

CPU私有外设中断PPI

共享外围中断SPI

硬件系统

软件系统

私有定时器中断

函数API

参考


 

中断

中断简介

UG585 CH7 Interrupts

以下主要是翻译的文档。

 

中断通过GIC pl390连接CPU。

CPU接收的中断包括来自外围I/O和PL侧。主要包括下面关键点:

私有、共享和软中断

每个CPU都一组私有外设中断PPI,使用分组寄存器专用访问。PPI包括全局全局定时器、私有看梦定时器、私有定时器和PL侧的FIQ/IRQ。(是ARM的两种不同的中断模式)

软中断SGI被路由到一个或两个CPU。SGIs由通用中断控制器GIC的寄存器生成。

共享外设中断SPIs由各种I/O和PS和PL的内存控制器,被连接到一个或两个CPU。SPIs同时也被路由到PL侧。

(从上面的图,可以看到中断分为三类,SGI、PPI和SPI,其中SPI由包括PS和PL两部分)

通用中断控制器GIC

GIC是一个管理来自PS和PL中断的集中资源。当CPU接口接收下一个中断是,GIC使能、禁用、屏蔽和优先处理中断源并以编程方式发送中断给选定的CPU。

此外,GIC支持安全扩展以实现安全感知系统。

GIC基于ARM GIC v1.0 非矢量

为了快速读写响应,GIC通过私有总线访问寄存器,避免暂时阻塞或其他瓶颈。

GIC集中所有的中断资源进行调度,分发最该优先级的中断给各个CPU。

当一个中断面向多个CPU时,GIC确保一次只有一个CPU执行。

所有的中断源都有唯一的中断标识号。

所有的中断源都有自己的可配置的优先级和目标CPU列表。

(从上面的图可以看到,SGI、PPI和SPI都是发给GIC,通过IRQ/FIQ发送给CPU)

复位和时钟

GIC的复位由复位子系统控制,由系统级控制寄存器SLCRA9_CPU_RST_CTRL寄存器的PERI_RST位.控制。该信号也复位CPU的私有定时器和私有看梦定时器AWDT。复位后,所有挂起或正在进行的中断全部被忽略。

GIC操作的时钟是CPU_3x2x(一半CPU的频率)。

模块图

SPIs由各种子系统生成,包括PS的I/O外设和PL的逻辑。

CPU中断信号直通

PL的中断可以路由到GIC作为PPI #4或#1中断,或者绕过GIC通过直通复用器。

两个CPU都可以使用。直通模式由mpcore.ICCICR寄存器控制。

 

功能说明

软件生成的中断 SGI

每个CPU能中断自身,另一个CPU或者两个CPU使用一个SGI。有16个软中断。中断的产生,通过写SGI中断号到ICDSGIR寄存器和指定目标CPU。通过CPU自己的私有总线。

每个CPU有自己的一组SGI寄存器来生成16个中断。通过读取ICCIAR寄存器(中断确认)或写1到ICDIPR(中断清挂起)寄存器相应位。

所有的SGI都是边沿触发,SGI的敏感类型是固定不可改变的;ICDIFR0寄存器是只读的,因为它指定了所有16个SGI敏感类型。

CPU私有外设中断PPI

每个CPU都有一组五个私有中断。

PPIs的敏感类型全是固定不可改变的,因此指定所有五个PPIs敏感类型的寄存器ICDICFR1是只读类型的。注意,来自的PL的快中断FIQ和中断IRQ信号被反转,然后再发送给中断控制器。因此,它们在PS-PL接口是高有效,但在ICDICFR1寄存器反映为低有效。

 

共享外围中断SPI

一组大约有60个来自各样模块的中断可以被路由到一个或两个CPUs或PL。中断控制器为CPU管理这些中断的优先级和接收。

除了IRQ#61#68#84#91,所有的中断敏感类型都是由请求源固定不可改变的。必须对GIC编程以适应。引导ROM不编程这些寄存器,因此,SDK设备驱动必须编程GIC以适应这些敏感类型。

对于电平敏感类型中断,请求源必须提供一种机制以便中断处理程序在确认中断后的清除中断。这需求适用于任何具有高敏感类型的 IRQF2P[n](来自PL)。

对于上升沿触发的中断,请求源需要提供足够的脉宽供GIC捕获。这通常是2个CPU_2x3x周期。这需求适用于任何具有上升沿敏感类型的 IRQF2P[n](来自PL)。

寄存器ICDIFR2ICDIFR5配置所有SPIs的中断类型。每个中断由2bit字段定制敏感类型和处理模型。

 

 

 

硬件系统

使用之前的版本。

软件系统

私有定时器中断

初始化中断控制器和私有定时器。打开私有定时器中断,连接中断操作。

/** main.c**  Created on: 2020/3/21*      Author: liny*/#include "intr_sys_timer.h"XScuTimer PriTimer;		/* Cortex A9 SCU Private Timer Instance */
XScuGic Scugic ; /* Scu GIC */int main()
{int Status;xil_printf("SCU Timer Intr! \r\n");Status = init_intr_sys(&Scugic, &PriTimer);if (Status != XST_SUCCESS) {xil_printf("Intr failed...\r\n");return XST_FAILURE;}xil_printf("SCU Timer start \r\n");/* Start the Scu Private Timer device.*/PriTimer_Start(&PriTimer);while (1){;}//	/* Stop the Scu Private Timer device.*/PriTimer_Stop(&PriTimer);Timer_Disable_Intr_System(&Scugic, TIMER_IRPT_INTR);xil_printf("SCU Timer Intr END! \r\n");return 0;
}
/** timer.h**  Created on: 2020/3/21*      Author: liny*/#ifndef SRC_INTR_SYS_TIMER_H_
#define SRC_INTR_SYS_TIMER_H_#include "xparameters.h"
#include "xscutimer.h"
#include "Xscugic.h"
#include "xil_exception.h"
#include "xil_printf.h"#define SCUGIC_DEVICE_ID		XPAR_SCUGIC_SINGLE_DEVICE_ID
#define SCUGIC_BASE_ADDR		XPAR_SCUGIC_0_CPU_BASEADDR
#define SCUGIC_DIST_BASE_ADDR	XPAR_SCUGIC_0_DIST_BASEADDR
#define TIMER_IRPT_INTR		    XPAR_SCUTIMER_INTR// param
#define PRIVATE_TIMER_DEVICE_ID		XPAR_XSCUTIMER_0_DEVICE_ID
// 1 Sec
#define TIMER_LOAD_VALUE	XPAR_PS7_CORTEXA9_0_CPU_CLK_FREQ_HZ / 2 -1/************************** Function Prototypes ******************************/
// Private Timer
int  PriTimer_Init(XScuTimer *TimerInstancePtr, u16 DeviceId, u32 LoadValue);
void PriTimer_Start(XScuTimer *TimerInstancePtr);
void PriTimer_Stop(XScuTimer *TimerInstancePtr);
void Timer_Intr_Enable(XScuTimer *TimerInstancePtr);
void Timer_Setup_Intr_System(XScuGic *IntcInstancePtr, XScuTimer * TimerInstancePtr);
void Timer_Disable_Intr_System(XScuGic *IntcInstancePtr, u16 TimerIntrId);
void timer_callback(XScuTimer * TimerInstancePtr);
// GIC
int Init_Intr_System(XScuGic * IntcInstancePtr);
void Setup_Intr_Exception(XScuGic * IntcInstancePtr);int init_intr_sys(XScuGic *IntcInstancePtr, XScuTimer * TimerInstancePtr) ;#endif /* SRC_INTR_SYS_TIMER_H_ */
/** timer.c**  Created on: 2020/3/21*      Author: liny*/#include "intr_sys_timer.h"/* Lookup , Initialize & Slef_Test*/
int PriTimer_Init(XScuTimer *TimerInstancePtr, u16 DeviceId, u32 LoadValue){int Status;XScuTimer_Config *ConfigPtr;ConfigPtr = XScuTimer_LookupConfig(DeviceId);Status = XScuTimer_CfgInitialize(TimerInstancePtr, ConfigPtr,ConfigPtr->BaseAddr);if (Status != XST_SUCCESS) {xil_printf("Scutimer Cfg initialization failed...\r\n");return XST_FAILURE;}elsexil_printf("Private Timer Initial Success! \n");Status = XScuTimer_SelfTest(TimerInstancePtr);if (Status != XST_SUCCESS) {xil_printf("Scutimer Self test failed...\r\n");return XST_SUCCESS;}elsexil_printf("Private Timer Initial Success! \n");/* Auto Reload mode. *///XScuTimer_DisableAutoReload(TimerInstancePtr);XScuTimer_EnableAutoReload(TimerInstancePtr);/* set the Load timer counter register value. */XScuTimer_LoadTimer(TimerInstancePtr, LoadValue);return XST_SUCCESS;
}void Timer_Setup_Intr_System(XScuGic *IntcInstancePtr,XScuTimer * TimerInstancePtr)
{Xil_ExceptionInit();XScuGic_DeviceInitialize(SCUGIC_DEVICE_ID);/** Connect the interrupt controller interrupt handler to the hardware* interrupt handling logic in the processor.*/Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,(Xil_ExceptionHandler)XScuGic_DeviceInterruptHandler,(void *)SCUGIC_DEVICE_ID);/** Connect the device driver handler that will be called when an* interrupt for the device occurs, the handler defined above performs* the specific interrupt processing for the device.*/XScuGic_Connect(IntcInstancePtr, TIMER_IRPT_INTR,(Xil_ExceptionHandler)timer_callback,(void *)TimerInstancePtr);
//	XScuGic_RegisterHandler(SCUGIC_BASE_ADDR, TIMER_IRPT_INTR,
//					(Xil_ExceptionHandler)timer_callback,
//					(void *)TimerInstancePtr);/** Enable the interrupt for scu timer.*/XScuGic_Enable(IntcInstancePtr, TIMER_IRPT_INTR);
//	XScuGic_EnableIntr(SCUGIC_DIST_BASE_ADDR, TIMER_IRPT_INTR);return ;
}
void Timer_Intr_Enable(XScuTimer *TimerInstancePtr)
{//Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);XScuTimer_EnableInterrupt(TimerInstancePtr);return;
}void Timer_Disable_Intr_System(XScuGic *IntcInstancePtr, u16 TimerIntrId)
{/** Disconnect and disable the interrupt for the Timer.*/XScuGic_Disconnect(IntcInstancePtr, TimerIntrId);
}
void PriTimer_Start(XScuTimer *TimerInstancePtr)
{XScuTimer_Start(TimerInstancePtr);return;
}void PriTimer_Stop(XScuTimer *TimerInstancePtr)
{XScuTimer_Stop(TimerInstancePtr);return;
}
void timer_callback(XScuTimer * TimerInstancePtr)
{xil_printf("Private Timer Intr Enable...\r\n");/* Clear Interrupt */XScuTimer_ClearInterruptStatus(TimerInstancePtr);
}
/**/
int Init_Intr_System(XScuGic * IntcInstancePtr)
{int Status;XScuGic_Config *IntcConfig;/** Initialize the interrupt controller driver so that it is ready to* use.*/IntcConfig = XScuGic_LookupConfig(SCUGIC_DEVICE_ID);if (NULL == IntcConfig) {return XST_FAILURE;}Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,IntcConfig->CpuBaseAddress);if (Status != XST_SUCCESS) {return XST_FAILURE;}return XST_SUCCESS;
}
/**/
void Setup_Intr_Exception(XScuGic * IntcInstancePtr)
{/* Enable interrupts from the hardware */Xil_ExceptionInit();Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,(void *)IntcInstancePtr);//	XScuGic_Connect(IntcInstancePtr, TIMER_IRPT_INTR,
//			(Xil_ExceptionHandler)timer_callback,
//			(void *)TimerInstancePtr);//	XScuGic_Enable(IntcInstancePtr, TIMER_IRPT_INTR);Xil_ExceptionEnable();
}int init_intr_sys(XScuGic *IntcInstancePtr, XScuTimer * TimerInstancePtr)
{int Status;/* Initialize the interrupt controller */Status = Init_Intr_System(IntcInstancePtr);if (Status != XST_SUCCESS) {xil_printf("Scutimer Cfg initialization failed...\r\n");return XST_FAILURE;}/* Initialize Private Timer */Status = PriTimer_Init(TimerInstancePtr, PRIVATE_TIMER_DEVICE_ID, TIMER_LOAD_VALUE);if (Status != XST_SUCCESS) {xil_printf("Scutimer Cfg initialization failed...\r\n");return XST_FAILURE;}/* Enable interrupts from the hardware */Setup_Intr_Exception(IntcInstancePtr);/* Set up timer Interrupt  */Timer_Setup_Intr_System(IntcInstancePtr, TimerInstancePtr);/* Enable Timer interrupts */Timer_Intr_Enable(TimerInstancePtr);return XST_SUCCESS;
}

 

函数API

中断使用的库函数由xscugic.h和xscugic_hw.h和xil_exception.h两个。

函数库xscugic.h和xscugic_hw.h提供通用中断控制器的操作函数

 

s32  XScuGic_Connect(XScuGic *InstancePtr, u32 Int_Id,

                     Xil_InterruptHandler Handler, void *CallBackRef);

连接中断源的中断号和中断程序

void XScuGic_Enable(XScuGic *InstancePtr, u32 Int_Id);

使能中断控制器关联的中断号中断。

 

函数库xil_exception.h提供异常处理的操作函数

extern void Xil_ExceptionInit(void);

初始化异常处理程序

extern void Xil_ExceptionRegisterHandler(u32 Exception_id,

                                    Xil_ExceptionHandler Handler,

                                    void *Data);

注册异常处理程序

Xil_ExceptionEnable();

使能IRQ异常

参考

UG585:Zynq-7000 SoC Technical Reference Manual

 


http://chatgpt.dhexx.cn/article/UWrkki7C.shtml

相关文章

Zynq-PS-SDK(4) 之 GIC 配置

目录 1、Configuration 2、GIC SDK Architecture 2.1、Structures 2.1.1、GIC interrupt vector table 2.1.2、GIC info 2.1.3、GIC 2.2、Functions 2.2.1、Basic 2.2.2、APIs 2.3、Configure flow 2.3.1、XScuGic_LookupConfig 2.3.2、XScuGic_CfgInitialize 2.3…

Xilinx软件开发:FreeRTOS快速入门

目录 第一章. 测试环境和软件版本 第二章. 创建hello world 第三章. 创建FreeRTOS2 第四章. 增加两个任务 1. 增加任务 2. 增加计数 第五章. 发送增加延时 第六章. 接收增加消息判断 第七章. 创建两个生产者 第八章. 注意事项 1. …

关于xilinx vitis 中的报错“fatal error: xil_printf.h: No such file or directory helloworld.c“问题解决

问题源:此问题是由于在VIVADO中使用了自动有AXI—IP造成的; 分析:在自定义了AXI-IP之后,会在自定义IP文件夹下生成“makefile”文件,该文件用于在vitis中生成对应文件的,所以需要修改你自定义IP的文件下的…

Vivado2019.1 ZYNQ7020无Uart SDK调试打印调试信息xil_printf

Vivado2019.1 ZYNQ7020无Uart SDK调试打印调试信息xil_printf Vivado2019.1 ZYNQ7020无Uart SDK调试打印调试信息xil_printf 前提条件:步骤: ** Vivado2019.1 ZYNQ7020无Uart SDK调试打印调试信息xil_printf ** 前提条件: Vivado 2019.1已…

ZYNQ开发中SDK输出串口选择以及打印函数print、printf、xil_printf的差别

ZYNQ开发系列——SDK输出串口选择以及打印函数print、printf、xil_printf的差别 前言两个串口到底是谁在打印?print 和 printf 和 xil_printf 前言 在最初的helloworld工程中,我们实现了通过串口每个1秒钟打印一次Hello World。 这里我们就来搞清楚以下…

Xilinx SDK Xil_In 内存对齐

SDK 的"xil_io.h"中提供了对地址的直接读写操作 不过我在实践中发现,对于Xil_In32(),当偏移为1不断读取时,会出现不正确的值。 我当时是在某连续若干地址中写了 0x0000 00ff(假如基址是0xc000 0000吧),但是读取的时候 0xc000 0001 读取的值是 0x0000 00ff; …

对Xil_Out32未定义的引用

第一次在HLS中遇见一个官方库函数未定义问题,这就把解决方法记录下来。 在创建好工程,写完工程代码后,发现报错如下 ./src/led_controller_test_tut_4A.o:在函数‘main’中:/home/greedyhao/Projects/LearningAndWor…

vivado sdk中xil_out函数对指定的BRAM地址写数据为什么会导致程序挂起?

是有关zynq芯片的网口程序调试的,我在例程lwip_echo_server程序中加入了往指定的bram地址写数据的语句,想要实现PS到PL数据的交互,但是程序执行到xil_out这块直接就运行不下去了,也不会打印下面的东西 下面是BRAM地址在SDK中的声明…

vivado 仿真报错:ERROR: [VRFC 10-2987] ‘xxxxx‘ is not compiled in library ‘xil_defaultlib‘

在Design Sources窗口下,选中报错的IP,比如除法器,右键: 选择第一个Autumatic Update and Compile Order即可。

仿真出现[VRFC 10-2263] Analyzing Verilog fileinto library xil_defaultlib

再Vivado导入quartus的.v文件出现如下情况,仿真例化时例化的模块都是问号。 让我们去仿真文件夹看看。 INFO: [VRFC 10-2263] Analyzing Verilog file "E:/FPGA/sdram0/sdram/sdram.srcs/sim_1/imports/tb_sdram_init/tb_sdram_init.v" into library xil…

GF框架+XIL 项目整合

项目unity版本:2020.3.18f1 XIL版本:Commits on Oct 26, 2021 GameFramework版本:Commits on Sep 28, 2021 UnityGameFramework版本:Commits on Oct 28, 2021 StarForce版本:Commits on Aug 9, 2021 HFS版本:2.3 项目克…

有关 MicroBlaze中xil_prinf/pirntf/print的一些问题

三个函数有什么区别 1.依赖的库文件不同 printf使用C标准库头文件stdio.h print/xil_printf使用xilinx定义的头文件xil_printf.h 2.能够输出的格式不同 print只能打印字符串,不可以带参数格式化输出,函数在print.c中定义 xil_printf可以带参量打印,但是不…

只针对个人遇见卡在Xil_DataAbortHandle循环while的解决办法

只针对本人所遇见的情况&#xff1a; 部分代码&#xff1a;unique_ptr<SatNoSnr[]> SatNo_Snr_Read_main(new SatNoSnr[Wrtie_Num]);// SatNo_Snr_Read_mainflash->FlashRead_JuYan(Wrtie_Num); 当SatNoSnr结构体是129字节(sizeof是136字节)时&#xff0c;上面一…

ZYNQ开发系列——SDK输出串口选择以及打印函数print、printf、xil_printf的差别

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 ZYNQ开发系列——SDK输出串口选择以及打印函数print、printf、xil_printf的差别 前言两个串口到底是谁在打印&#xff1f;print 和 printf 和 xil_printf 前言 在最初的hell…

MBD开发模式下的XIL仿真测试

MBD开发模式下的XIL仿真测试 “想了解MBD模式下的MIL、SIL、PIL、HIL吗&#xff1f;”——虹科 汽车从一个发动机加上几个轮子的简单形态发展到如今机械与电子高度融合的复杂整体&#xff0c;经历了巨变。汽车电子控制单元的数量和复杂度也呈几何级数增加&#xff0c;给软硬件…

SSM 三大框架原理、核心技术,运行流程讲解

作者:arrows 来源:https://www.cnblogs.com/arrows/p/10537733.html 一、Spring部分 1、 Spring的运行流程 第一步&#xff1a;加载配置文件ApplicationContext ac new ClassPathXmlApplicationContext(“beans.xml”); &#xff0c;ApplicationContext接口&#xff0c;它由…

SSM框架介绍以及功能原理

SSM是spingspringMVCmybatis集成的框架。 Spring框架概述 什么是Spring Spring是一个开源框架&#xff0c;Spring是于2003 年兴起的一个轻量级的Java 开发框架&#xff0c;由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来…

ssm框架项目完整流程详解

springMVC项目完整流程详解 1.创建一个maven项目2.修改项目配置&#xff0c;添加tomcat&#xff0c;生成web.xml3.在pom.xml中引入需要用到的包并update project4.在resources下建立如下图所示结构&#xff0c;并创建springmvc-servlet.xml、spring-mybatis.xml、druid.propter…

SSM三大框架工作流程与原理详解

作者&#xff1a;网络笨猪 blog.csdn.net/lyfqyr/article/details/84552278 一、Spring部分 1、Spring的运行流程 第一步&#xff1a;加载配置文件ApplicationContext ac new ClassPathXmlApplicationContext("beans.xml");&#xff0c;ApplicationContext接口&…

SSM框架原理,作用及使用方法,详细解释

1、基本概念 1.1、Spring Spring是一个开源框架&#xff0c;Spring是于2003 年兴起的一个轻量级的Java 开发框架&#xff0c;由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的…