知识点:
一、PL中断PS的概况。
中断是一种外设通过打断正在进行CPU处理的程序,而立即执行中断服务程序,来实现外设与处理器之间的深度耦合方式。
我们再回头再看看外设U585。
这里看到虚框内的PL部分可以通过SPI 这部分,产生中断,最终可以通过ICD灵活分配到两个处理器上。
每一个中断源或者一组中断源都对应一个中断ID,处理器运行程序通过ID号来区分是哪个具体中断源产生的中断,UG585列出了中断源与中断号的对应关系。
另外我们也可以在VIVADO的配置里面找到这种对应关系。用中断号对应起来之后,在处理器看来就是和其他中断(比如我们之前将的GPIO中断和 私有定时器的中断)同样对待了,注册程序和处理的框架也就基本一样了。PS端程序的编写是类似的。
- 关于触发方式以及以及边缘触发模式下保持时间。
PL中断PS触发方式可以在PS端编程控制对应寄存器设置为高电平触发和上升边缘触发。在这个我们认为中断源的满足中断和不满足中断分别用1和0表示。高电平就是中断的条件满足了,表现为逻辑1。上升边缘触发表示之前从中断没有发生到中断发生的这个跳变,也就是从逻辑0到逻辑1的跳变。在Z7系统中允许设置PL的中断触发方式。
当设置电平触发时候,只要中断条件一直满足,也就是中断请求线上电平是高,则触发处理器产生中断。
当设置上升边缘触发时候,当且仅当中断条件从不满足到满足的跳变上,也就是中断请求线表现成了一个上升边缘,并且保持高电平至少2个CPU_2X3X周期(也就是说4个以上处理器的时钟周期)。就会产生触发处理器产生中断。
这两种中断触发方式强调的侧重点不一样,电平触发强调的是 特定中断事件之要没有撤销就要反复进行处理。比方说在具体应用中一个来自外界的报警信号,只要报警信号存在说明危险没有被消除,需要继续中断处理器,继续处理。上升缘触发方式强调特定中断事件发生了,对于这个此次特定发生的中断事件,处理器只要做一次处理就可以。如果外设还要再次请求中断处理器,则需要将中断再次产生一个上升边缘进行进行请求。
这里我们将做结合例子来加深一下认识。
- 实验
为了能实验高电平触发和上升边缘触发,我们来写一个模块。用到一个外接按键,分析代码。用此模块的输出产生中断。
我们也可以直接使用上一讲述PS定时器的项目,直接在上面修改,加上PL中断部分,最后导入SDK,修改代码进行实验。
对比高电平触发和上升边缘触发。
同时开时钟中断,对比高低优先级级的效果。
这里的结论是 0)设置数值越大,优先级越低。1)高优先级级别可以中断低有限级的程序。2)低优先级别的中断和高优先级的程序并发产生时候或者正在执行高优先级的程序,则此中断可能被忽略掉。
- 总结
- 两种触发方式。
- 边缘触发方式下高电平最少保持处理器时钟周期的两倍,一般建议时间长一些,20NS。
- 关于中断优先级。
- 操作方面注意VIVADO可以引出信号给模块外。
- 中断输入对应的位数在generate product 的时候才能生成。
- 做中断实验,最好生成不要使用jtag在线调试方式。
另外:
PS与PL有多种交互方式,简单一总结 :
- PS配置PL.
- PS通过AXI总线读写PL的寄存器或者存储器。(AXI LITE 读写外设的寄存器,AXI FULL 读写PL部分的片内或者片外存储器)。
- PL中断PS。
4,PL主动读写PS部分的DDR3存储器。
具体设置:
1、添加中断:
中断号跟ug585一致,15位对应91;
我们如果需要更多的中断,添加
In0:61 In1:62
整体BD:
把key_debounce加进来:
2、打开SDK
PLO_intr.c:
/*
* PL0_intr.c
*
* Created on: 2016年12月6日
* Author: Administrator
*/
#include <stdio.h>
#include "xadcps.h"
#include "xil_types.h"
#include "Xscugic.h"
#include "Xil_exception.h"
#include "xscutimer.h"
static void PL0_IntrHandler(void *CallBackRef)
{
/// XScuTimer *TimerInstancePtr = (XScuTimer *) CallBackRef;
///XScuTimer_ClearInterruptStatus(TimerInstancePtr);
static int i = 0 ;
// printf("%s : %d\n",(char *)CallBackRef,i++);
printf(".");
}
int PL0_init(XScuTimer *TimerPtr, u8 PrescalerValue , u32 Load_Value,u32 DeviceId)
{
/*
XScuTimer_Config *TMRConfigPtr; //timer config
TMRConfigPtr = XScuTimer_LookupConfig(DeviceId);
XScuTimer_CfgInitialize(TimerPtr, TMRConfigPtr,TMRConfigPtr->BaseAddr);
XScuTimer_SetPrescaler(TimerPtr, PrescalerValue) ;
XScuTimer_LoadTimer(TimerPtr, Load_Value);
XScuTimer_EnableAutoReload(TimerPtr);
*/
return 1;
}
char PL0_msg[] = "This is PL0 info " ;
void PL0_Setup_Intr_System(XScuGic *GicInstancePtr)
{
XScuGic_Connect(GicInstancePtr, 61,
(Xil_ExceptionHandler)PL0_IntrHandler,//set up the timer interrupt
(void *)PL0_msg);
XScuGic_Enable(GicInstancePtr, 61);//enable the interrupt for the Timer at GIC
XScuGic_SetPriorityTriggerType(GicInstancePtr, 61, 0X90 , 1 ) ;
}
3、烧写boot,生成fsbl;
烧写flash:BOOT.mcs
改写中断SPI:1或者3,便可以控制为高电平触发和上升边缘触发,可以串口看结果。
高电平触发:反复触发3s
上升:一次
定时器:A0,PS:B0:PS优先级高;