在裸机下跑PS的timer计时器中断,PL到PS的按键中断均工作正常,但是将代码移植到freertos工程时,中断不执行,跟中断无关联的task可以运行。产生这个问题的主要原因,在于PS部分只有一个中断控制器,因此我们只能申请一个中断控制器设备,如果申请了两个,那么不工作是必然的。我们在裸机下申请了一个:XScuGic INST ,另外一个被FreeRTOS申请了,在如下图,这样就“冲突”了,所以:我们将原先自己申请的中断控制器改用FreeRTOS申请的XScuGicxInterruptController,这就需要在我们自己写的函数中,去全局的声明一下FreeRTOS定义的那个XScuGicxInterruptController变量,方法就是在main()前面加上extern XScuGic xInterruptController;。
下图是Xilinx的一位员工给出的意见,也就是,在开启调度器时会初始化中断控制器,因此我们初始化中断控制器只能在线程中执行,也就是在vTaskStartScheduler()开启任务调度之前。反正我看到有中断控制器传参的函数都放到一个task中去了,另外在FreeRTOS中,什么Task,线程等等,貌似不区分,概念一样,如果看到FreeRTOS有线程相关的函数,多半是被别人封装过吧。
验证microblaze也有相同的问题。
解决方法:
不要在main函数中注册外设中断,建议main函数中首先创建一个task用来初始化所有外设,并注册中断。然后再创建其余task。
中断注册接口如下:
Status = xPortInstallInterruptHandler(INTC_ID (XInterruptHandler)func_ISR, (void *)i );
if( Status == pdPASS )
{
vPortEnableInterrupt(INTC_ID );
}