声明及感谢: 跟随正点原子资料学习, 在此作为学习的记录和总结
环境 keil , stm32f103
背景知识, Cotex-M3的NVIC最多支持240个IRQ(中断请求),1个不可屏蔽(NMI),1个Systick(滴答定时器)
Cortex-M处理器有三个固定的优先级(优先级为负数那几个就是固定的) 和256(因为每个中断都由中断优先级设置寄存器来设置,此寄存器为8位的,所以是256优先级)可编程的优先级, 最多有128个抢占优先级
但是芯片厂家根据实际应用的情况会,将优先级最高分组会进行固定设置(软件不能够改变),
stm32 设置的优先级为16级优先级。在寄存器中是高4位有效,
在FreeRTOS中关于中断管理的宏定义配置为下面几个宏
使用
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 // 中断优先级
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 // 系统可管理的最高中断优先级
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
其中 configPRIO_BITS 为4 也就是所说的高4位有效, 将 configLIBRARY_LOWEST_INTERRUPT_PRIORITY 左移4bit位
其中 configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 表示FreeRTOS管理的最大优先级, 也就是说0-4(因为数数字越低,优先级越高)优先级FreeRTOS管理不了,同时中断不可调用FreeRTOS的API函数。
低于或者等于configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY的中断即可被FreeRTOS管理。
FreeRTOS开关中断
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() // 关中断
#define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 ) // 开中断
这两个宏定义深度追踪会设置到最底层的寄存器, 在此先不深追。 根据就上面说的,当中断的优先级高于
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 宏定义,上面的开关中断宏定义对其无效,只能对
低于或等于configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY宏定义有作用。
示例
// 中断测试任务函数
void interrupt_task(void *pvParameters)
{
static u32 total_num=0;
while(1)
{
total_num+=1;
if(total_num==5)
{
printf("关闭中断.............\r\n");
portDISABLE_INTERRUPTS(); // 关闭中断
delay_xms(5000); // 延时5S
printf("´打开中断............\r\n"); // 打开中断
portENABLE_INTERRUPTS();
}
LED0=~LED0;
vTaskDelay(1000);
}
}
这是一个中断测试的任务, 当运行5次此任务之后,低于configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY宏定义中断优先级的中断会被关闭, 再等5秒,被关闭的中断将会被打开。