FreeRTOS的中断配置是一个很重要的内容,这里需要根据dsPIC33C的中断知识来配置。我们首先了解下dsPIC33C的中断向量表(IVT),IVT位于程序存储器中,如下图所示。起始单元地址是0x000004,IVT包含6个不可屏蔽陷阱向量和最多246个中断源。一般来说每个中断源都有自己的中断向量。每个中断向量都包含一个24位宽的地址。每个中断向量单元中编程的值是其相关的中断服务程序(ISR)的起始地址。对于0x000014~0x001FE的中断向量在指定的用户优先级内具有固定的优先级,同一用户优先级的中断向量根据其自然优先级区分优先顺序。自然优先级与中断向量在向量表中的位置有关。一般来说,较低地址的中断向量具有较高的自然优先级。例如,与向量0(地址0x000014)相关的中断比任何其他向量地址的中断具有更高的自然优先级。
每个中断可以指定的用户优先级有7个1~7。1是用户可选的最低优先级,7是最高优先级。滴答定时器Timer1初始化函数vApplicationSetupTickTimerInterrupt()中将中断优先级设为configKERNEL_INTERRUPT_PRIORITY,这里是最低优先级1。每个用户中断优先级最简单的设置方法为借助MAPLAB x IDE的插件MCC进行图形化的配置,如下图。
介绍完了每个用户中断的优先级情况,我们继续了解dsPIC33CK CPU的优先级设定,CPU优先级的设定由SR寄存器中的IPL[2:0]和CORCON寄存器中的IP[3]共同组合形成的IPL[3:0]制定。但从寄存器可以看出IPL[3]不可写'1',因此实际CPU的优先级并不能大于7,所以用户软件不能屏蔽陷阱事件(不可屏蔽中断的中断优先级大于7)。同时由SR寄存器可知,默认CPU的优先级IPL[2:0]为0,低于用户中断的最低优先级1,因此所有的用户中断都可以打断CPU。
根据上一节FreeRTOS裁剪中关于中断优先级的宏定义配置情况,我们可以画出下图,也就是RTOS希望优先级5~7的中断永远不被禁止,不会因为执行FreeRTOS内核而延迟,并且这些中断不可调用FreeRTOS的API函数;而优先级1~4是可以被RTOS管理的,也就是RTOS可以根据需要禁止这些中断,这些中断可以调用FreeRTOS的API函数。
FreeRTOS开关中断函数为portENABLE_INTERRUPTS()和portDISABLE_INTERRUPTS(),这两个函数其实是宏定义,在portmacro.h中有定义,如下:
可以看出,关中断时将CPU的优先级IPL[2:0]设置为configMAX_SYSCALL_INTERRUPT_PRIORITY,因此优先级小于等于configMAX_SYSCALL_INTERRUPT_PRIORITY的中断会被FreeRTOS内核屏蔽;类似的开中断的实现通过将CPU的优先级IPL[2:0]设置为0。