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,转到此处收藏)
用户377235 2016-5-8 10:26