中断:ZYNQ

news2025/1/21 1:02:04

整个中断系统架构中,只包含以下三种中断:

 软件生成中断(Software Generated Interrupts,SGI)

 私有外设中断(Private Peripheral Interrupts,PPI)

 共享外设中断(Shared Peripheral Interrupts,SPI)

        每种中断都各自包含特定的中断源,如: PPI 包括全局定时器(global timer)、 私有看门狗定时器(private timer)、私有定时器(private timer)和 PL 中的 FIQ。

        SGI 则是通过写入通用中断控制器(Generic Interrupt Controller,GIC)中的寄存器 生成。SPI 是由 PS 和 PL 中的各种 I/O 和内存控制器生成的。

        对于一般的中低端 CPU 系统来说,上面的结构就足够实现中断的产生和处 理功能了。但是,我们 zynq 的 PS 可不是一般的处理器系统,它是一个结构复 杂,性能强劲的双核 Cortex-A9 处理器系统。其包含一级缓存 L1 ,二级缓存 L2, 缓存能够提升 CPU 读写总线数据的性能。但是使用不当,也会造成 CPU 读写数 据实时性的下降,甚至因为缓存一致性的问题,把一些已经由其他外设更新但 是缓存中还是旧值的数据取用,从而产生错误。由于中断的实时性和重要性,中断控制器的相关寄存器的读写是不能因为缓存的存在而被延误的,所以 CPU 并不通过 L2 来访问 GIC 中的寄存器,而是通过一个名为窥探控制单元 Snoop Control Unit(简称 SCU),采用私有总线访问 GIC 的寄存器,以此来提升中断 的处理效率。

IRQ和FRQ:普通中断和快中断

        通用中断控制器(GIC)是一种集中式资源,是联系中断和 CPU 的桥梁,也是各 CPU 之间中断互联的通道(也带有管理功能),它负责管理、分发从 PS 和 PL 发送到 CPU 的中断。

        当 CPU 接口接受下一个中断时,控制器启用、禁用、 屏蔽中断源并确定其优先级,然后按照编程设定将它们发送给选定的 CPU。

        当然,并不是说所有的中断请求一发出都能立马被 CPU 处理。所有中断源 都有唯一的中断标识号标识以及自己可配置的优先级和目标 CPU 列表。

        图中的 中断分发器(Interrupt Controller Distributor ,ICD)保存着每个 CPU 的挂起中断列表。它会集中所有的中断源,随后根据其优先级(优先级设置值越大,优先级越小),优先将高优先级的中断源分配给指定 CPU 处理,以确保针对多个 CPU 的中断一次只能由一个 CPU 处理。

        但是优先级逻辑在物理上是重复的,也 就是说不同的中断也可以设置为同一优先级。对于这种情况,中断分发器会优先将中断标识号最低的中断源分配给 CPU 处理。

软中断

        每个 CPU 都可以使用软件生成的中断 (SGI) 来中断自身、另一个 CPU 或两个 CPU。
        有 16 个软件生成的中断(见表 7-2)。通过将 SGI 中断号写入 ICDSGIR 寄存器并指定目标 CPU 来生成 SGI。此写入通过 CPU 自己的专用总线进行。每个 CPU 都有自己的一组 SGI 寄存器,用于生成 16 个软件生成的中断中的一个或多个。通过读取 ICCIAR(中断应答)寄存器或将 1 写入 ICDICPR(中断清除挂起)寄存器的相应位来清除中断。

        所有 SGI 都是边沿触发的。 SGI 的灵敏度类型是固定的且无法更改; ICDICFR0 寄存器是只读的,因为它指定了所有 16 个 SGI 的灵敏度类型。

        每个 CPU 专用的一组 16 个中断源,可以路由到最多 16 个公共中断目标,其中每个目标可以是一个或多个 CPU。

私有设备中断

        每个 CPU 连接到一组私有的五个外设中断。 PPI 列于表 7-3 中。
        PPI 的敏感度类型是固定的且无法更改;因此,ICDICFR1 寄存器是只读的,因为它指定了所有 5 个 PPI 的灵敏度类型。请注意,来自 PL 的快速中断 (FIQ) 信号和中断 (IRQ) 信号被反转,然后发送到中断控制器。因此,尽管 ICDICFR1 寄存器将它们反映为低电平有效,但它们在 PS-PL 接口处为高电平有效。

共享设备中断

        来自各个模块的一组大约 60 个中断可以路由到一个或两个 CPU 或 PL。中断控制器管理 CPU 的这些中断的优先级和接收。
        除了 IRQ #61 至 #68 和 #84 至 #91 之外,所有中断敏感度类型均由请求源固定且无法更改。 GIC 必须进行编程以适应这种情况。引导 ROM 不会对这些寄存器进行编程;因此,SDK 设备驱动程序必须对 GIC 进行编程以适应这些敏感度类型。

        对于电平敏感类型的中断,请求源必须提供一种机制,以便中断处理程序在中断被应答后清除中断。此要求适用于任何具有高级别灵敏度类型的 IRQF2P[n](来自 PL)。
        对于上升沿敏感的中断,请求源必须提供足够宽的脉冲供 GIC 捕获。这通常至少是 2 个 CPU_2x3x 周期。此要求适用于任何具有上升沿敏感类型的 IRQF2P[n](来自 PL)。
        ICDICFR2 至 ICDICFR5 寄存器配置所有 SPI 的中断类型。每个中断都有一个 2 位字段,指定敏感类型和处理模型。
        GPIO中断号为 #52,触发类型为高电平。

        而 AXI GPIO 由于是 PL 逻辑构成的,因此 AXI GPIO 中断属于 PL 中断,中断号为#[91:84]和#[68:61],触发类型为高电平或上升沿。 该中断在使用时需要在 ZYNQ 核中使能对应中断端口。

具体开发情况

开发步骤:

ZYNQ-实现GPIO的中断控制_zynq gpio中断_Vuko-wxh的博客-CSDN博客

  1. 初始化CPU异常功能
  2. 初始化中断控制器
  3. 向CPU注册异常处理回调函数(CPU在中断以后执行的函数)
  4. 向中断控制器中对应的中断ID和中断控制器相连接(并且注册第六步的回调函数)
  5. 设置中断的类型
  6. 设置GPIO中断的回调函数(用户自己设置)
  7. 使能对应引脚的中断
  8. 使能中断控制器
  9. 使能异常处理功能

GIC驱动程序组件。

        中断控制器驱动程序对各种处理程序使用优先级的概念:

        优先级是 1 到 31 范围内的整数,默认值 1 是最高优先级中断源。各种源的优先级可以根据需要通过硬件配置动态更改。
        6通用中断控制器支持以下功能: 特定的单独中断 启用/禁用特定的单独中断确认 附加特定的回调函数来处理中断源 如果默认值不可接受,则为中断源分配所需的优先级。
        有关连接驱动程序中断处理程序的详细信息包含在特定于中断处理的源文件 xscugic_intr.c 中。
        该驱动程序旨在独立于 RTOS 和处理器。它仅适用于物理地址。任何对动态内存管理、线程或线程互斥、虚拟内存或高速缓存控制的需求都必须由该驱动程序之上的层来满足。


中断向量表

        驱动程序使用中断控制器设备的设备 ID 作为配置数据表的直接索引。用户应使用XScuGic_Connect() 和 XScuGic_Disconnect() 函数在运行时使用处理程序和回调填充向量表。
        每个向量表条目对应一个可以产生中断的设备。每个条目都包含一个中断处理程序函数和一个在中断发生时传递给处理程序的参数。当中断处理程序采用基地址以外的参数时,用户必须使用 XScuGic_Connect()。


嵌套中断处理

该驱动程序不支持嵌套中断。
        注意:通用中断控制器不是监听控制单元的一部分,如驱动程序名称中的前缀“scu”所示。它是APU中的一个独立模块。

函数介绍:

步骤1:初始化CPU异常功能

Xil_ExceptionInit

        将中断控制器中断处理程序连接到ARM 处理器中的硬件中断处理逻辑。

        我在新的例子中没有看到这个函数了。

        * @brief 该函数是一个通用 API,用于在所有支持的手臂上初始化异常处理程序 *处理器。对于 ARM Cortex-A53、Cortex-R5、* 和 Cortex-A9,异常处理程序正在静态初始化,并且该函数不执行任何操作。
        * 然而,它仍然存在以解决向后兼容性 * 问题(在早期版本的 BSP 中,此 API 用于 * 初始化异常处理程序)。

/****************************************************************************/
/**
* @brief	The function is a common API used to initialize exception handlers
*			across all supported arm processors. For ARM Cortex-A53, Cortex-R5,
*			and Cortex-A9, the exception handlers are being initialized
*			statically and this function does not do anything.
* 			However, it is still present to take care of backward compatibility
*			issues (in earlier versions of BSPs, this API was being used to
*			initialize exception handlers).
*
* @return	None.
*
*****************************************************************************/
void Xil_ExceptionInit(void)
{
	return;
}

步骤2:初始化中断控制器

        和配置其他的没什么不同,不详细列举。

	GicConfig = XScuGic_LookupConfig(DeviceId);
	if (NULL == GicConfig) {
		return XST_FAILURE;
	}

	Status = XScuGic_CfgInitialize(&InterruptController, GicConfig,
					GicConfig->CpuBaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

步骤3:向CPU注册异常处理回调函数Xil_ExceptionRegisterHandler()

void Xil_ExceptionRegisterHandler(u32 Exception_id,
                    Xil_ExceptionHandler Handler,
                    void *Data)

/******************************************************** **************************/ 
/** * @brief 为特定异常注册处理程序。当处理器遇到指定的异常时,将调用此处理程序。
* * @param Exception_id 包含异常源的 ID,并且应该 
* 在 0 到 XIL_EXCEPTION_ID_LAST 的范围内。
* 有关更多信息,请参阅 xil_exception.h。
* @param Handler 到该异常的处理程序。
* @param Data 是对数据的引用,当处理程序被调用时,该数据将被传递给处理程序。
* * @返回无。
********************************************************* **************************/ 
/*****************************************************************************/
/**
* @brief	Register a handler for a specific exception. This handler is being
*			called when the processor encounters the specified exception.
*
* @param	Exception_id contains the ID of the exception source and should
*			be in the range of 0 to XIL_EXCEPTION_ID_LAST.
*			See xil_exception.h for further information.
* @param	Handler to the Handler for that exception.
* @param	Data is a reference to Data that will be passed to the
*			Handler when it gets called.
*
* @return	None.
*
****************************************************************************/
void Xil_ExceptionRegisterHandler(u32 Exception_id,
				    Xil_ExceptionHandler Handler,
				    void *Data)
{
#if (defined (versal) && !defined(ARMR5) && EL3) || defined(ARMR52)
	if ( XIL_EXCEPTION_ID_IRQ_INT == Exception_id )
	{
	/*
	 * Cortexa72 processor in versal is coupled with GIC-500, and
	 * GIC-500 supports only FIQ at EL3. Hence, tweaking this API
	 * to act on IRQ, if Exception_id is pointing to IRQ
	 */
		Exception_id = XIL_EXCEPTION_ID_FIQ_INT;
	}
#endif
	XExc_VectorTable[Exception_id].Handler = Handler;
	XExc_VectorTable[Exception_id].Data = Data;
}

步骤4:连接GPIO中断信号并注册GPIO回调函数:XScuGic_Connect()

s32  XScuGic_Connect(XScuGic *InstancePtr, u32 Int_Id,
                Xil_InterruptHandler Handler, void *CallBackRef)

/******************************************************** ****************************/ 
/** * * 在中断源的 Int_Id 和关联的处理程序之间建立连接是在识别到中断时运行。 
* 在此调用中作为 Callbackref 提供的参数在调用处理程序时用作处理程序的参数。
* * @param InstancePtr 是指向 XScuGic 实例的指针。
* @param Int_Id 包含中断源的 ID,并且应在 0 到 XSCUGIC_MAX_NUM_INTR_INPUTS - 1 的范围内 
* @param Handler 指向该中断的处理程序。
* @param CallBackRef 是回调引用,通常是连接驱动程序的实例指针。
* * @return * * - XST_SUCCESS 如果处理程序连接正确。
* * @note * 
* 警告:作为参数提供的处理程序将覆盖之前连接的任何处理程序。
********************************************************* ****************************/
/*****************************************************************************/
/**
*
* Makes the connection between the Int_Id of the interrupt source and the
* associated handler that is to run when the interrupt is recognized. The
* argument provided in this call as the Callbackref is used as the argument
* for the handler when it is called.
*
* @param	InstancePtr is a pointer to the XScuGic instance.
* @param	Int_Id contains the ID of the interrupt source and should be
*		in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
* @param	Handler to the handler for that interrupt.
* @param	CallBackRef is the callback reference, usually the instance
*		pointer of the connecting driver.
*
* @return
*
*		- XST_SUCCESS if the handler was connected correctly.
*
* @note
*
* WARNING: The handler provided as an argument will overwrite any handler
* that was previously connected.
*
****************************************************************************/
s32  XScuGic_Connect(XScuGic *InstancePtr, u32 Int_Id,
				Xil_InterruptHandler Handler, void *CallBackRef)
{
	/*
	 * Assert the arguments
	 */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
	Xil_AssertNonvoid(Handler != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/*
	 * The Int_Id is used as an index into the table to select the proper
	 * handler
	 */
	InstancePtr->Config->HandlerTable[Int_Id].Handler = (Xil_InterruptHandler)Handler;
	InstancePtr->Config->HandlerTable[Int_Id].CallBackRef = CallBackRef;

	return XST_SUCCESS;
}

步骤5:设置GPIO中断类型XGpioPs_SetIntrType()

void XGpioPs_SetIntrType(const XGpioPs *InstancePtr, u8 Bank, u32 IntrType,

              u32 IntrPolarity, u32 IntrOnAny)

/******************************************************** **************************/ 
/** * * 该函数用于设置中断类型、中断极性和 * Interrupt On Any对于指定的 GPIO Bank 引脚。
* * @param InstancePtr 是指向 XGpioPs 实例的指针。
* @param Bank 是要操作的 GPIO 的 Bank 号。
* Zynq 中的有效值为 0-3,Zynq Ultrascale+ MP 中的有效值为 0-5。
* @param IntrType 是中断类型的 32 位掩码。
* 0 表示电平敏感,1 表示边缘敏感。
* @param IntrPolarity 是中断极性的 32 位掩码。
* 0 表示低电平有效或下降沿,1 表示高电平有效或 * 上升沿。
* @param IntrOnAny 是边沿触发中断的中断触发的 32 位掩码。 
* 0 表示使用配置的中断极性在单边沿触发,1 表示在双边沿触发。
* * @返回无。
* * @note 该函数用于设置指定bank中所有引脚的中断相关属性。引脚之前的 * 状态不会保持。
* 要更改单个 GPIO 引脚的中断属性,请使用函数 XGpioPs_SetPinIntrType()。
********************************************************* ****************************/
/****************************************************************************/
/**
*
* This function is used for setting the Interrupt Type, Interrupt Polarity and
* Interrupt On Any for the specified GPIO Bank pins.
*
* @param	InstancePtr is a pointer to an XGpioPs instance.
* @param	Bank is the bank number of the GPIO to operate on.
*		Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP.
* @param	IntrType is the 32 bit mask of the interrupt type.
*		0 means Level Sensitive and 1 means Edge Sensitive.
* @param	IntrPolarity is the 32 bit mask of the interrupt polarity.
*		0 means Active Low or Falling Edge and 1 means Active High or
*		Rising Edge.
* @param	IntrOnAny is the 32 bit mask of the interrupt trigger for
*		edge triggered interrupts. 0 means trigger on single edge using
*		the configured interrupt polarity and 1 means  trigger on both
*		edges.
*
* @return	None.
*
* @note		This function is used for setting the interrupt related
*		properties of all the pins in the specified bank. The previous
*		state of the pins is not maintained.
*		To change the Interrupt properties of a single GPIO pin, use the
*		function XGpioPs_SetPinIntrType().
*
*****************************************************************************/
void XGpioPs_SetIntrType(const XGpioPs *InstancePtr, u8 Bank, u32 IntrType,
			  u32 IntrPolarity, u32 IntrOnAny)
{
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertVoid(Bank < InstancePtr->MaxBanks);
#ifdef versal
        if(InstancePtr->PmcGpio == (u32)TRUE) {
                Xil_AssertVoid(Bank != XGPIOPS_TWO);
        } else {
                Xil_AssertVoid((Bank !=XGPIOPS_ONE) && (Bank !=XGPIOPS_TWO));
        }
#endif

	XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
			  ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
			  XGPIOPS_INTTYPE_OFFSET, IntrType);

	XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
			  ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
			  XGPIOPS_INTPOL_OFFSET, IntrPolarity);

	XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
			  ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
			  XGPIOPS_INTANY_OFFSET, IntrOnAny);
}

步骤6:设置GPIO的回调函数XGpioPs_SetCallbackHandler()

void XGpioPs_SetCallbackHandler(XGpioPs *InstancePtr, void *CallBackRef,

                 XGpioPs_Handler FuncPointer)

/******************************************************** **************************/ 
/** * * 该函数设置状态回调函数。当中断发生时,回调函数由 XGpioPs_IntrHandler 调用。
* * @param InstancePtr 是指向 XGpioPs 实例的指针。
* @param CallBackRef 是调用回调函数时传回的上层回调引用。
* @param FuncPointer 是回调函数的指针。
* * * @return 无。
* 
* @note 处理程序是在中断上下文中调用的,因此它应该快速完成其工作,
* 并将可能耗时的工作排队到任务级线程。
********************************************************* *****************************/
/*****************************************************************************/
/**
*
* This function sets the status callback function. The callback function is
* called by the  XGpioPs_IntrHandler when an interrupt occurs.
*
* @param	InstancePtr is a pointer to the XGpioPs instance.
* @param	CallBackRef is the upper layer callback reference passed back
*		when the callback function is invoked.
* @param	FuncPointer is the pointer to the callback function.
*
*
* @return	None.
*
* @note		The handler is called within interrupt context, so it should do
*		its work quickly and queue potentially time-consuming work to a
*		task-level thread.
*
******************************************************************************/
void XGpioPs_SetCallbackHandler(XGpioPs *InstancePtr, void *CallBackRef,
				 XGpioPs_Handler FuncPointer)
{
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(FuncPointer != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	InstancePtr->Handler = FuncPointer;
	InstancePtr->CallBackRef = CallBackRef;
}

步骤7:使能对应pin的中断XGpioPs_IntrEnable()

void XGpioPs_IntrEnable(const XGpioPs *InstancePtr, u8 Bank, u32 Mask)

/******************************************************** **************************/ 
/** * * 该函数启用指定* Bank 中指定引脚的中断。
* * @param InstancePtr 是指向 XGpioPs 实例的指针。
* @param Bank 是要操作的 GPIO 的 Bank 号。
* Zynq 中的有效值为 0-3,Zynq Ultrascale+ MP 中的有效值为 0-5。
* @param Mask 是要启用中断的引脚的位掩码。位位置 1 将被启用。位位置 
* 为 0 将保留先前的设置。
* * @返回无。
* * @note 无。
********************************************************* **************************/
/****************************************************************************/
/**
*
* This function enables the interrupts for the specified pins in the specified
* bank.
*
* @param	InstancePtr is a pointer to the XGpioPs instance.
* @param	Bank is the bank number of the GPIO to operate on.
*		Valid values are 0-3 in Zynq and 0-5 in Zynq Ultrascale+ MP.
* @param	Mask is the bit mask of the pins for which interrupts are to
*		be enabled. Bit positions of 1 will be enabled. Bit positions
*		of 0 will keep the previous setting.
*
* @return	None.
*
* @note		None.
*
*****************************************************************************/
void XGpioPs_IntrEnable(const XGpioPs *InstancePtr, u8 Bank, u32 Mask)
{
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
        Xil_AssertVoid(Bank < InstancePtr->MaxBanks);
#ifdef versal
        if(InstancePtr->PmcGpio == (u32)TRUE) {
                Xil_AssertVoid(Bank != XGPIOPS_TWO);
        } else {
                Xil_AssertVoid((Bank !=XGPIOPS_ONE) && (Bank !=XGPIOPS_TWO));
        }
#endif

	XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
			  ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
			  XGPIOPS_INTEN_OFFSET, Mask);
}

步骤8:使能中断控制器中的gpio中断XScuGic_Enable()

void XScuGic_Enable(XScuGic *InstancePtr, u32 Int_Id)

/******************************************************** **************************/ 
/** * * 启用作为参数 Int_Id 提供的中断源。 
* 调用此函数后,将发生指定 Int_Id 的任何未决中断条件。
* 该 API 还将中断映射到请求的 CPU。
* * @param InstancePtr 是指向 XScuGic 实例的指针。
* @param Int_Id 包含中断源的 ID,并且应该 * 在 0 到 XSCUGIC_MAX_NUM_INTR_INPUTS - 1 的范围内 * * @return None。
* * @note 无。
********************************************************* **************************/
/*****************************************************************************/
/**
*
* Enables the interrupt source provided as the argument Int_Id. Any pending
* interrupt condition for the specified Int_Id will occur after this function is
* called.
* This API also maps the interrupt to the requesting CPU.
*
* @param	InstancePtr is a pointer to the XScuGic instance.
* @param	Int_Id contains the ID of the interrupt source and should be
*		in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1
*
* @return	None.
*
* @note		None.
*
****************************************************************************/
void XScuGic_Enable(XScuGic *InstancePtr, u32 Int_Id)
{
	u32 Mask;
	u8 Cpu_Identifier = (u8)CpuId;

#if defined (GICv3)
	u32 Temp;
#endif
	/*
	 * Assert the arguments
	 */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

#if defined (GICv3)
	if (Int_Id < XSCUGIC_SPI_INT_ID_START) {

		Int_Id &= 0x1f;
		Int_Id = 1 << Int_Id;

		Temp = XScuGic_ReDistSGIPPIReadReg(InstancePtr,XSCUGIC_RDIST_ISENABLE_OFFSET);
		Temp |= Int_Id;
		XScuGic_ReDistSGIPPIWriteReg(InstancePtr,XSCUGIC_RDIST_ISENABLE_OFFSET,Temp);
		return;
	}
#endif
	XScuGic_InterruptMaptoCpu(InstancePtr, Cpu_Identifier, Int_Id);
	/*
	 * Call spinlock to protect multiple applications running at separate
	 * CPUs to write to the same register. This macro also ensures that
	 * the spinlock mechanism is used only if spinlock is enabled by
	 * user.
	 */
	XIL_SPINLOCK();
	/*
	 * The Int_Id is used to create the appropriate mask for the
	 * desired bit position.
	 */
	Mask = (u32)0x00000001U << (Int_Id % 32U);
	/*
	 * Enable the selected interrupt source by setting the
	 * corresponding bit in the Enable Set register.
	 */
	XScuGic_DistWriteReg(InstancePtr, (u32)XSCUGIC_ENABLE_SET_OFFSET +
				((Int_Id / 32U) * 4U), Mask);

	/*
	 * Release the lock previously taken. This macro ensures that the lock
	 * is given only if spinlock mechanism is enabled by the user.
	 */
	XIL_SPINUNLOCK();
}

步骤9:使能异常处理Xil_ExceptionEnableMask()

/****************************************************************************/
/**
* @brief	Enable the IRQ exception.
*
* @return   None.
*
* @note     None.
*
******************************************************************************/
#if (defined (versal) && !defined(ARMR5) && EL3) || defined(ARMR52)
#define Xil_ExceptionEnable() \
                Xil_ExceptionEnableMask(XIL_EXCEPTION_FIQ)
#else
#define Xil_ExceptionEnable() \
		Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ)
#endif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1064093.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为云云耀云服务器L实例评测|云耀云服务器L实例部署DjangoBlog个人博客系统

华为云云耀云服务器L实例评测&#xff5c;云耀云服务器L实例部署DjangoBlog个人博客系统 一、云耀云服务器L实例介绍1.1 云耀云服务器L实例简介1.2 云耀云服务器L实例特点 二、DjangoBlog介绍2.1 DjangoBlog介绍2.2 DjangoBlog特点 三、本次实践介绍3.1 本次实践简介3.2 本次环…

java socket实现代理Android App

实现逻辑就是转发请求和响应。 核心代码 // 启动代理服务器private void startProxyServer() {new Thread(new ProxyServer()).start();}// 代理服务器static class ProxyServer implements Runnable {Overridepublic void run() {try {// 监听指定的端口int port 8098; //一…

AutoGen - 多个Agent开发LLM应用的框架

文章目录 关于安装使用关于 Enable Next-Gen Large Language Model Applications 用多个Agent开发LLM应用的框架,这些agent可相互交流以解决任务。 官网:https://microsoft.github.io/autogen/github : http://github.com/microsoft/autogendiscord : https://discord.com/i…

LVGL_基础控件滚轮roller

LVGL_基础控件滚轮roller 1、创建滚轮roller控件 /* 创建一个 lv_roller 部件(对象) */ lv_obj_t * roller lv_roller_create(lv_scr_act()); // 创建一个 lv_roller 部件(对象),他的父对象是活动屏幕对象// 将部件(对象)添加到组&#xff0c;如果设置了默认组&#xff0c…

buuctf-crypto 1

rsarsa 题目描述 Math is cool! Use the RSA algorithm to decode the secret message, c, p, q, and e are parameters for the RSA algorithm.p 96484230290105156765905517400104265349457376392357398006439893520398525072984913995610350091634270503701075707336333…

Java循环队列

目录 一、循环队列 二、设计循环队列 一、循环队列 队列&#xff1a;只能在一端进行插入数据操作&#xff0c;另一端进行删除数据操作的特殊线性表&#xff0c;是一种先进先出的存储结构 插入操作的一端为队尾&#xff0c;删除操作的一端为队头 在线性队列中&#xff0c;一…

leetcode 62. 不同路径、63.不同路径||

62. 不同路径 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&…

课题学习(三)----倾角和方位角的动态测量方法(基于陀螺仪的测量系统)

一、内容介绍 该测量系统基于三轴加速度和三轴陀螺仪&#xff0c;安装在钻柱内部&#xff0c;随钻柱一起旋转&#xff0c;形成捷联惯性导航系统&#xff0c;安装如下图所示&#xff1a;   假设三轴加速度和陀螺仪的输出为: f b [ f x f y f z ] T f^b\begin{bmatrix}f_{x} …

C++ 学习系列 -- std::list

一 std::list 介绍 list 是 c 中的序列式容器&#xff0c;其实现是双向链表&#xff0c;每个元素都有两个指针&#xff0c;分别指向前一个节点与后一个节点 链表与数组都是计算机常用的内存数据结构&#xff0c;与数组连续内存空间不一样的地方在于&#xff0c;链表的空间是不…

Springboot实现登录功能(token、redis、登录拦截器、全局异常处理)

登录流程&#xff1a; 1、前端调用登录接口&#xff0c;往接口里传入账号&#xff0c;密码 2、根据账号判断是否有这个用户&#xff0c;如果有则继续判断密码是否正确 3、验证成功后&#xff0c;则是根据账号&#xff0c;登录时间生成token&#xff08;用JWT&#xff09; 4、将…

64位Office API声明语句第111讲

跟我学VBA&#xff0c;我这里专注VBA, 授人以渔。我98年开始&#xff0c;从源码接触VBA已经20余年了&#xff0c;随着年龄的增长&#xff0c;越来越觉得有必要把这项技能传递给需要这项技术的职场人员。希望职场和数据打交道的朋友&#xff0c;都来学习VBA,利用VBA,起码可以提高…

企业使用SSL证书对于SEO有多重要

在当今竞争激烈的在线市场中&#xff0c;搜索引擎优化&#xff08;SEO&#xff09;是企业获得更高排名和增加网站流量的关键。在SEO策略中&#xff0c;企业使用SSL证书已经成为多重不可忽视的重要因素。让我们一起探究企业使用SSL证书对于SEO的重要性。 首先&#xff0c;搜索引…

socket.error: [Errno 10049]错误

今天在pycharm运行rl_server_no_training.py欲启动服务器时&#xff0c;却出现如下错误 Traceback (most recent call last):File "xxx/rl_server_no_training.py", line 333, in <module>main()File "xxx/rl_server_no_training.py", line 326, in…

【C++】运算符重载 ⑧ ( 左移运算符重载 | 友元函数 / 成员函数 实现运算符重载 | 类对象 使用 左移运算符 )

文章目录 一、左移运算符重载1、友元函数 / 成员函数 实现运算符重载2、类对象 使用 左移运算符3、左移运算符 << 重载 二、完整代码示例 一、左移运算符重载 1、友元函数 / 成员函数 实现运算符重载 运算符重载 的正规写法一般都是 使用 成员函数 的形式 实现的 ; 加法…

DLRover - 小记

文章目录 关于 DLRover 关于 DLRover github : https://github.com/intelligent-machine-learning/dlrover DLOver使大型人工智能模型的分布式训练变得简单、稳定、快速和绿色。 它可以在分布式集群上自动训练深度学习模型。 它帮助模型开发人员专注于模型结构&#xff0c;而…

手把手教你从零开始腾讯云服务器部署(连接建站教程)

使用腾讯云服务器搭建网站全流程&#xff0c;包括轻量应用服务器和云服务器CVM建站教程&#xff0c;轻量可以使用应用镜像一键建站&#xff0c;云服务器CVM可以通过安装宝塔面板的方式来搭建网站&#xff0c;腾讯云服务器网txyfwq.com分享使用腾讯云服务器建站教程&#xff0c;…

双周回顾#001 - 火烧云

工作以来&#xff0c;许久未曾见过如此壮观的火烧云景观了。 文章 1、穿透的 DIV &#xff08;pointer-events&#xff09;1 pointer-events 是一个蛮有趣的 CSS3 属性&#xff0c;虽然主要是针对 SVG &#xff0c;但其中几个属性应用在 div 上也是颇有意思。 顾名思义&…

学会自我投资:美团四大名著之<高效能人士的七个习惯>

你有没有这些问题&#xff1f;如果有&#xff0c;那么本文也许对你有用。 受害者心理&#xff0c;如果有人对你说粗话&#xff0c;就怼回去。消极被动。 没有计划。没有目标。不会担心自己的行为带来的后果。随波逐流。及时行乐&#xff0c;做个玩世不恭者。 拖延。总是先做紧…

vue +element 批量删除

1.拿到当前勾选状态 在el-table里边去写 单选用第一个 多选用第二个 select"selectHandle" :当用户手动勾选数据行的 Checkbox 时触发的事件 select-all"selectHandle":当用户手动勾选全选 Checkbox 时触发的事件// 点击勾选选择器selectHandle(selection…

机器学习:决策树

决策树 决策树是一种基于树形结构的模型&#xff0c;决策树从根节点开始&#xff0c;一步步走到叶子节点&#xff08;决策&#xff09;&#xff0c;所有的数据最终都会落到叶子节点&#xff0c;既可以做分类也可以做回归。 特征选择 根节点的选择该用哪一个特征呢&#xff…