zedboard第十九课(standaloneOS,Interrupt专题,PL_PS中断)

GIC掌管整个中断系统。
前面我们已经分析了PS的两个中断源,GPIO输入源和TIMER中断源。

最灵活的中断是SPIntr,既可以是PL发送给PS,也可以是PS发送给PL。

GIC一共有96个中断源,即,IRQ_ID是从0#95。具体分配如下:
IRQ#0~IRQ#15,分配给了SGIntr.
IRQ#16~IRQ#31,分配给了PPIntr。
IRQ#32~IRQ#95,分配给了SPIntr。
其中,就有我们熟悉的IRQ#52,这是GPIO的中断号。

SPIntr,如果在配置PS7时,配置了中断,那么就会有一组PORT出现在PS和PL的边界上。
PS发送给PL的中断,信号名为IRQP2F[28:0]。
PL发送给PS的中断,信号名为IRQF2P[15:0]。

PL_PS的中断,大体流程与TIMER类似。只到FhSISR就结束了。
BSP中,并没有提供PL_PS的中断模块例程,所以需要我们自己来编写中断模块。
基于SOD设计思想,首先我们需要定义结构体。
先来看一个最简单的例子。

typedef struct{
	int i;
	char* desc;
}PL0_Intr_ID61;

定义了IRQ#61的RDB。

int  PL0_init(PL0_Intr_ID61* ptr, char* s)
{

	ptr->i=0;
	ptr->desc= s;
     return 1;
}

这个函数填充了IRQ#61的RDB。

static void PL0_IntrHandler(void *CallBackRef)
{
	PL0_Intr_ID61* IntrID61ptr;
	IntrID61ptr= (PL0_Intr_ID61*)CallBackRef;
   printf("%s  :  %d\n",IntrID61ptr->desc,IntrID61ptr->i++);

}
void  PL0_Setup_Intr(XScuGic *GicInstancePtr, PL0_Intr_ID61* PL0_Intr_ID61ptr)
{
        XScuGic_Connect(GicInstancePtr, 61,
                        (Xil_ExceptionHandler)PL0_IntrHandler,//set up the PL0 interrupt
                        (void *)PL0_Intr_ID61ptr);

        XScuGic_Enable(GicInstancePtr, 61);//enable the interrupt for the Timer at GIC
        XScuGic_SetPriorityTriggerType(GicInstancePtr,  61, 0X90 , 3) ;

 }

定义了IRQ#61的IntrHandler,并在GIC中注册这个HandlerVectorEntry。

static XScuGic GIC; //GIC
static PL0_Intr_ID61 PL0_Intr_ID61_inst;
static char PL0_desc[] = "This is PL0 up key " ;
int main()
{
    init_platform();
    print("Hello World\n\r");
    
    	Init_GIC(&GIC);
    	PL0_init(&PL0_Intr_ID61_inst,PL0_desc);
    	
		PL0_Setup_Intr( &GIC,&PL0_Intr_ID61_inst);
    	//Timer_Setup_Intr(&GIC,&Timer,TIMER_IRPT_INTR);
    	
    	Exception_Init_Register_Enable();   	
    	
    	//XScuTimer_Start(&Timer);
    	
    	while(1) ;
    cleanup_platform();
    return 0;
}

这个例子,实现了最基本的中断响应机制。用于EventTrigger。
PL利用这个中断,仅仅是向PS发送一个事件Event,并没有更多的数据。

对于一个良好的SOD程序架构而言,这些并不足够。
我们可以仿照TIMER的设计架构,设计出IRQ#61的模块。

typedef struct{
	IRQF2P_ID61_Config intr61_config;
	u32 isReady;
	char* desc;
}XIRQF2P_ID61;

typedef struct{
	u16 DeviceId;	/**< Unique ID of device */
	u32 BaseAddr;	/**< Base address of the device */
}XIRQF2P_ID61_Config;

我们定义了RCB和RDB。

XIRQF2P_ID61_Config* XIRQF2P_ID61_LookupConfig(u16 DeviceId);

s32 XIRQF2P_ID61_CfgInitialize(XIRQF2P_ID61 *InstancePtr,
			 XIRQF2P_ID61_Config *ConfigPtr, u32 EffectiveAddress);

s32 XIRQF2P_ID61_setRegisterValue(XIRQF2P_ID61 *InstancePtr,
			  u32 RegisterOffset, u32 Value);
			  
s32 XIRQF2P_ID61_getRegisterValue(XIRQF2P_ID61 *InstancePtr,
			  u32 RegisterOffset, u32* Value);

根据不同的需要,我们可以补充定义RCB和RDB,也可以补充新的操作函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值