原创 EDK 中XPS中断控制器的使用

2010-10-22 19:36 5006 5 6 分类: FPGA/CPLD
嵌入式应用中往往需要用到多个中断来提高系统响应的及时性,而MICROBLAZE处理器只提供一个中断输入信号来产生一个中断,因此一般基于MICROBLAZE的应用都需要进行外扩中断,XILINX提供的XPS中断控制器IP可以使我们十分方便地进行中断扩展。下面首先简单介绍下XPS中断控制器的特性与寄存器,然后在上一节的基础上结合一个实例来说明它的使用。
1.中断控制器的特性与寄存器(XPS Interrupt Controller,v1.00)
XPS中断控制器采用PLB接口,可以提供多达32个中断输入源、产生一个中断输出信号。每一中断输入源可以单独的使能和不使能,每一中断输入源可以配置为边缘触发中断或电平触发中断。边缘触发中断可配置为上沿触发或下沿触发,电平触发中断可配置为高电平触发或低电平触发。中断的优先级由矢量位置决定,最低位有最高优先级。中断控制器提供八个32位的寄存器用来编程控制(有些寄存器是可选的),分别为:
①中断状态寄存器(ISR:Interrupt Status Register):地址为C_BASEADDR + 0x0,可读写寄存器,读时每一位对应一个中断输入的标志位,当MER的HIE位为0时可写。
②中断挂起寄存器(IPR:Interrupt Pending Register):地址为C_BASEADDR + 0x4,可选的只读寄存器,读出结果为中断标志位与中断使能位的AND。
③中断使能寄存器(IER:Interrupt Enable Register):地址为C_BASEADDR + 0x8,可读写寄存器,每一位对应一个中断输入的使能位。
④中断应答寄存器(IAR:Interrupt Acknowledge Register):地址为C_BASEADDR + 0xC,只写寄存器,每位写1清对应的中断标志位。
⑤设置中断使能寄存器(SIE:Set Interrupt Enables):地址为C_BASEADDR + 0x10,只写寄存器,每位写1设对应的中断使能位。
⑥请除中断使能寄存器(CIE:Clear Interrupt Enables):地址为C_BASEADDR + 0x14,只写寄存器,每位写1清对应的中断使能位。
⑦中断矢量寄存器(IVR:Interrupt Vector Register):地址为C_BASEADDR + 0x18,可选的只读寄存器,读出结果为当前激活的最高优先级中断的中断矢量,无中断时读为全1。
⑧主使能寄存器(MER:Master Enable Register):地址为C_BASEADDR + 0x1C,可读写寄存器,只用到两位,最低位ME使能IRQ,次低位HIE为硬件中断使能。
2.一个实例
上一节我们基于μC/OS-II的延时函数实现了一个LED灯闪烁的实验,本节准备在上一节的基础上实现下面的功能:通过GPIO中断来激活或挂起一个比LED灯闪烁任务更高优先级的任务,以验证中断控制器的使用和任务的抢占,下面是具体步骤:
(1).打开上一节的工程,在XPS 界面右边的System Assembly View里点Port栏,再双击DIP_Switches_4Bit图标,在弹出的IP配置窗口里的Use栏里勾选 “GPIO Supports Interrupts”。点OK退出配置窗口。展开DIP_Switches_4Bit图标前的加号,选择IP2INTC_Irpt线为New Connection。
(2). 在XPS界面右边的System Assembly View里点Port栏,展开xps_intc_0图标前的加号,
在Intr里把DIP_Switches_4Bi_IP2INTC_Irpt_0加为中断源,并把优先级设为比xps_timer_0_Interrupt低,点OK退出窗口。
(3) 然后在XPS界面顺序选择:
①Hardware → Clean Netlist
②Hardware → Clean Bits
③Hardware → Generate Netlist
④Hardware → Generate Bitstream
(4) 修改C:\MICRIUM\Software\EvalBoards\Xilinx\Generic\GNU\EX1_OS\ app.c文件增加一个显示流水灯的任务。具体修改如下:
①. 在main函数前加入如下代码:
INT16U flag1;
OS_STK AppTaskSecondStk [256];
void AppTaskSecond(void *p_arg)
{
INT8U i;
INT32U j;

i=2;
BSP_InitIO();


while (1) {
LED_Off(0);
LED_On(i);
i++;
if(i>4)
{
i=2;
}


for(j=0;j<699999; j++); //Delay1
}
}
② 在main 函数里的OSInit();后面加入如下代码:
f lag1 =0;
OSTaskCreateExt(AppTaskSecond,
(void *)0,
&AppTaskSecondStk[255],
2,
2,
&AppTaskSecondStk[0],
256,
(void *)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
③ 把AppTaskFirst函数里调用的BSP_InitIO();语句删除,因为我们在更高优先级的AppTaskSecond任务里已经调用过了。
(5) 修改C:\MICRIUM\Software\EvalBoards\Xilinx\Generic\GNU\EX1_OS\app_cfg.h如下:
#define APP_TASK_FIRST_ID 3
#define APP_TASK_FIRST_PRIO 3
#define APP_TASK_FIRST_STK_SIZE 256
即降低第一个任务的优先级和减少堆栈容量。
(6) 修改C:\MICRIUM\Software\EvalBoards\Xilinx\Generic\GNU\BSP\bsp.c文件
①.在BSP_InitIntCtrl中断初始化函数前加入GPIO的中断函数如下:
extern INT16U flag1;
void BSP_GpioHandler(void *baseaddr_p)
{
for(gpio_status=0; gpio_status<69999; gpio_status++); //Delay2
if(flag1==0)
{
OSTaskSuspend(2);
flag1=1;
}
else
{
OSTaskResume(2);
flag1=0;
}
XGpio_mWriteReg(XPAR_DIP_SWITCHES_4BIT_BASEADDR, 0x120, 0x1);
}
②在BSP_InitIntCtrl函数内的
init_status = XIntc_Connect(&int_ctl, BSP_INTC_TIMER1_ID,BSP_Timer1Handler,(void *)0);语句下面添加下列语句:
init_status = XIntc_Connect(&int_ctl, XPAR_XPS_INTC_0_DIP_SWITCHES_4BIT_IP2INTC_IRPT_INTR,BSP_GpioHandler,(void *)0);
XIntc_Enable(&int_ctl, XPAR_XPS_INTC_0_DIP_SWITCHES_4BIT_IP2INTC_IRPT_INTR);


XGpio_mWriteReg(XPAR_DIP_SWITCHES_4BIT_BASEADDR, XGPIO_TRI_OFFSET, 0xffffffff);
XGpio_mWriteReg(XPAR_DIP_SWITCHES_4BIT_BASEADDR, XGPIO_GIE_OFFSET, XGPIO_GIE_GINTR_ENABLE_MASK);
XGpio_mWriteReg(XPAR_DIP_SWITCHES_4BIT_BASEADDR, XGPIO_IER_OFFSET, 0x1);
(7) 在XPS界面选择:
①Software → Clean Libraries
②Software → Generate Libraries and BSPs
③点击TEST工程名,在右键弹出菜单选择Set Compiler Options...,
在Debug and Optimization选择 No Optimization。
再在右键弹出菜单选择选择Clean Project 后在选择Build Project编译工程。
④Device Configuration → Update Bitstream
⑤Device Configuration → Download Bitstream
下载成功后可以看到系统首先运行高优先级的任务使LED[2:4]跑流水灯,拨下DIP开关产生GPIO中断,进入中断函数内把高优先级任务挂起,则系统运行次优先级的任务使LED1闪烁,在拨下DIP开关,进入中断后恢复高优先级任务,又可以看到LED[2:4]跑流水灯,
次优先级任务由于抢占已经不在运行(LED1不再闪烁)。
3.最后总结一下调试中遇到问题:
(1).要用XPS中断控制器进行中断扩展,有三个地方相应的使能位都要打开,否则中断进不来,一个MICROBLAZE的中断使能位,二是中断控制器各个输入的使能位和输出使能位,三是具体中断源的使能位(GPIO的单独位的使能位和总使能位),而硬件上也要确认连接好。
(2).进入中断后要清标志位,包括中断控制器和中断源两个地方的标志位,否则出现中断退出后又立刻进来的现象。
(3). DIP开关由手工拨动,一般有按键反弹现象,所以要延时下消抖,这就是上面代码//Delay2的作用,如果不消抖,可能出现拨一下进入中断多次的现象。
(4) 带了操作系统后,如果任务多点或堆栈大一点,往往不能把全部代码放在BRAM里,这时在Device Configuration → Update Bitstream步骤时会报错说容量不够,所以这里我把堆栈改为256了,实际项目使用的话往往要外扩FLASH和RAM。


(注:这是我以前写的一篇BLOG,转到此处收藏)

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户377235 2016-5-8 10:26

MB中如何用汇编指令读取变量的首地址?如指定变量的存储地址?知道的朋友请发email给我jjb15820109@163.com,非常地感谢!
相关推荐阅读
wdzfd 2020-06-16 19:13
【富芮坤物联网开发板评测】FR8016H开发板体验及与上位机通信测试
【富芮坤物联网开发板评测】FR8016H开发板体验及与上位机通信测试    首先感谢富芮坤微电子有限公司和面包板社区搞得这次活动,本人有幸参与到活动,按惯例先上开发板的全家福照片:...
wdzfd 2014-01-19 16:48
一位工程师的FPGA项目开发经验总结
1. 要和人配合。以我们做硬件的工程师为例,测试的时候一般都需要软件的配合,一个对硬件来说无比复杂的工作,可能在软件工程师看来就是几行简单的代码。所以要和人配合,多听听别人的意见,这样必然可以产生...
wdzfd 2014-01-07 08:55
关于硬件设计经验
一:成本节约 现象一:这些拉高/拉低的电阻用多大的阻值关系不大,就选个整数5K吧 点评:市场上不存在5K的阻值,最接近的是4.99K(精度1%),其次是5.1K(精度5%),其成本分别比精度为...
wdzfd 2013-11-10 18:52
FPGA一体化高级设计方法
尽管 FPGA 为嵌入式设计带来了强大的功能与灵活性,但额外的开发流程也给设计工作增加了新的复杂性和限制问题。整合传统的硬件-FPGA-软件设计流程并充分利用 FPGA 的可再编程功能是我们的一个...
wdzfd 2013-10-25 11:10
HP大中华区总裁 / 孙振耀 退休感言(3)
五、跳槽与积累    首先要说明,工作是一件需要理智的事情,所以不要在工作上耍个性,天涯上或许会有人觉得你很有个性而叫好,煤气公司电话公司不会因为觉得你很有个性而免了你的帐单。当你很帅地炒掉了...
wdzfd 2013-10-25 11:09
HP大中华区总裁 / 孙振耀 退休感言(2)
三、什麽是好工作     当初微软有个唐骏,很多大学里的年轻人觉得这才是他们嚮往的职业生涯,我在清华bbs里发的帖子被这些学子们所不屑,那个时候学生们只想出国或者去外企,不过如今看来,我还是对的...
EE直播间
更多
我要评论
1
5
关闭 站长推荐上一条 /3 下一条