Platform PYNQ-Z2
Realize the function
Here achieve emio access button button IRQ interrupts with pynq
Hardware EMIO 54 pick btn0, through input, triggers an interrupt # 52, to GIC
By SPI, interrupt operation and other cpu registers specified trigger IRQ
hardware design
A EMIO of GPIO_0_0_tri_io discipline leads to btn0
constraint
set_property -dict { PACKAGE_PIN D19 IOSTANDARD LVCMOS33 } [get_ports { GPIO_0_0_tri_io }]; #IO_L4P_T0_35 Sch=btn[0]
software design
#include <stdio.h>
#include "platform.h"
#include "xgpiops.h"
#include "xgpiops_hw.h"
#include "XSCUGIC.H"
#include "XSCUGIC_HW.H"
#include "sleep.h"
#define ICCPMR *(volatile unsigned int *) 0xf8f00104
//printf(" ICCPMR = %0X @ line = %d \n", ICCPMR ,__LINE__ );
//(__FILE__, __LINE__);
#define GPIO_NO 54
static void GpioHandler(void *CallBackRef, int Bank, u32 Status)
{
static int i = 0;
if (Status ==0 ) return ;
XGpioPs* pGpioPs=(XGpioPs*)CallBackRef;
XGpioPs_IntrDisablePin(pGpioPs,GPIO_NO);
printf("Gpio Handler %d...\n\r",i++);
// while (1 == XGpioPs_ReadPin( pGpioPs , GPIO_NO )) ;
usleep(100*1000);
XGpioPs_IntrClearPin(pGpioPs,GPIO_NO);
XGpioPs_IntrEnablePin(pGpioPs,GPIO_NO);
}
int main()
{
XGpioPs Gpio;
XGpioPs_Config *ConfigPtr;
printf(" ICCPMR = %0X @ line = %d \n", ICCPMR ,__LINE__ );
ConfigPtr = XGpioPs_LookupConfig(0);
XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);
//初始化GPIO的输入以及中断。
XGpioPs_SetDirectionPin(&Gpio,GPIO_NO,0x0);
XGpioPs_SetIntrTypePin(&Gpio,GPIO_NO,XGPIOPS_IRQ_TYPE_EDGE_RISING);
XGpioPs_SetCallbackHandler(&Gpio, (void *)&Gpio, GpioHandler);
XGpioPs_IntrEnablePin(&Gpio,GPIO_NO);
XScuGic ScuGic;
XScuGic_Config* pScuGicCfg;
pScuGicCfg=XScuGic_LookupConfig(XPAR_SCUGIC_SINGLE_DEVICE_ID);
XScuGic_CfgInitialize(&ScuGic,pScuGicCfg,pScuGicCfg->CpuBaseAddress);
XScuGic_Connect(&ScuGic, 52,
(Xil_ExceptionHandler)XGpioPs_IntrHandler,
(void *)&Gpio);
XScuGic_SetPriorityTriggerType(&ScuGic,52,0xa0,0x01);//优先级阈值f0
XScuGic_Enable(&ScuGic,52);
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,&ScuGic);
Xil_ExceptionEnable();
printf("Intr test: \n\r");
while(1)
{
}
}
result
button
ICCICR (IC CPU IC REG)->
ICDDC R( UC distributor C REG)->
GPIO interrupt function analysis library
void XGpioPs_SetCallbackHandler(XGpioPs *InstancePtr, void *CallBackRef,
XGpioPs_Handler FuncPointer)
XGpioPs_SetCallbackHandler(&Gpio, (void *)&Gpio, GpioHandler);
XGpioPs_Handler function pointer
Interrupt
Processor speed with the speed of the peripheral hardware devices are often not on a order of magnitude, so if you take the core processor to send a request to the hardware, and then wait for a special way to respond, apparently to reduce core efficiency.
Therefore, up to us to provide a mechanism for hardware kernel again send a signal (active initiative to change the kernel hardware) when needed, this is the break mechanism.
Different devices corresponding to different interrupts, each interrupt through a unique digital identity.
For example, it is different from the keyboard interrupt interrupts from the hard disk, so that the operating system is able to distinguish between interruption and know which hardware devices which generated the interrupt. In this way, the operating system in order to provide different different interrupt interrupt handler.
When it executes a program, if there is another event occurs (such as the user has opened a program) so that by the time you need to interrupt mechanism of a computer system to deal with.
Including hardware interrupt mechanismInterruption meansAnd operating systemInterrupt service routine。
Let hardware kernel again signaled when needed.
Early computer system interrupts generated by hardware identification code (identification of the interrupt source, may be used to form the corresponding interrupt service routine entry address or storage address of the first interrupt service routine) is calledInterrupt vectorVariable interrupt address
Interrupt vector table: interrupt the connection between the table number and the type of interrupt source entry address corresponding interrupt handler;
_vector_table:
B _boot
B Undefined
B SVCHandler
B PrefetchAbortHandler
B DataAbortHandler
NOP /* Placeholder for address exception vector*/
B IRQHandler
B FIQHandler
Interrupt service routine: break the code executed when the transmit interrupt
compilation
IRQHandler: /* IRQ vector handler */
stmdb sp!,{r0-r3,r12,lr} /* state save from compiled code*/
#if FPU_HARD_FLOAT_ABI_ENABLED
vpush {d0-d7}
vpush {d16-d31}
vmrs r1, FPSCR
push {r1}
vmrs r1, FPEXC
push {r1}
#endif
#ifdef PROFILING
ldr r2, =prof_pc
subs r3, lr, #0
str r3, [r2]
#endif
bl IRQInterrupt /* IRQ vector */
C
/*****************************************************************************/
/**
*
* This is the C level wrapper for the IRQ interrupt called from the vectors.s
* file.
*
* @param None.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void IRQInterrupt(void)
{
XExc_VectorTable[XIL_EXCEPTION_ID_IRQ_INT].Handler(XExc_VectorTable[
XIL_EXCEPTION_ID_IRQ_INT].Data);
}
#if !defined (__aarch64__)
ref
https://blog.csdn.net/qq_18077275/article/details/89304215?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
zynq break
Sources divided into three categories SPI, PPI, SGI total of 96 interrupt ID number
After a break to run multiple interrupt hander interrupt handler, the following steps
-
STEP 1, the first to jump to the interrupt vector to turn the IRQ service routine. It corresponds to the function
-
STEP 2, there are dozens of ways to generate IRQ (ID No. 96), so we need to know specifically what happened happened IRQ interrupts interrupt number. The corresponding call the appropriate handler if found.
-
STEP 3, which find particular interrupt ID number, corresponding to the steps is to re-process may have to be subdivided
(for example, to 118, 52 GPIO can generate interrupts to determine the specific one of which). As well as other appropriate process.