首先是config文件里的宏
/*ARM Cortex-M 架构自身允许最多 256 个不同的优先级(最多有 8 个 优先级位,因此从 0 到 0xff 的优先级都是可能的),但绝大多数使用 ARM Cortex-M 核心的微控制器 仅允许使用其中一部分*/
#define configKERNEL_INTERRUPT_PRIORITY 255
/*芯片使用几位来支持优先级查看这个宏,我的是4位*/
#define __NVIC_PRIO_BITS 4 /*!< STM32 uses 4 Bits for the Priority Levels */
/*在STM32中可以通过优先级分组来区分抢占优先级个数和响应优先级个数,使用 RTOS 时建议全部改为使用抢占优先级,也就是NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);0-15级抢占优先级。
/*RTOS 的中断嵌套方案将可用的中断优先级分为2两组:一组将被 RTOS 临界区屏蔽,另一组永远不会被 RTOS 临界区屏蔽。它的边界由configMAX_SYSCALL_INTERRUPT_PRIORITY这个宏定义
/*如何设置这个宏呢,ARM Cortex-M 核心将中断优先级值存储在其8位中断优先级寄存器的最高有效位中,其余位设置为1。例如把界限设置为5,如下:对于用三位来设置优先级的,5就是191
对于4位表示优先级的,5就是95
我的芯片是4位的自然就是设置为95
我们目前将中断组设置为4,将中断分割设置为5,此时,在中断优先级为0-4的中断服务函数中,不应该使用from_ISR这一组api任务函数,而在5-15级的任务中就可以使用from_ISR这一组函数,用来让中断服务函数和任务之间进行通信
举个例子:以任务通知为例
//主函数
void task2(void *pvParameters)
{
while(1)
{
ulTaskNotifyTake(pdTRUE,portMAX_DELAY);//一直阻塞,直到收到通知
USART_SendString(USART1,"task2 is runing!\r\n");
//OLED_ShowString(2,1,"nihao");
}
}
int main(void)
{
//中断分组:15抢占
Usart1_Init(); //串口初始化
it_key_init(); //外部中断初始化
//OLED_Init(); //显示屏初始化
//OLED_ShowString(1,1,"hello,");
xTaskCreate(task2, "Task 2", 1000, NULL, 2, &task2_handle);
vTaskStartScheduler();//开启任务调度器
return 0;
}
/*******************************************************/
//中断函数
void it_key_init(void)
{
//开启GPIO和AFIO的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//初始化GPIOB
GPIO_InitTypeDef GPIOB_STRU;
GPIOB_STRU.GPIO_Pin=GPIO_Pin_12;
GPIOB_STRU.GPIO_Mode=GPIO_Mode_IPU;
GPIOB_STRU.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIOB_STRU);
//接入外部中断线
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource12);
//外部中断初始化
EXTI_InitTypeDef EXTI_InitStruct;
EXTI_InitStruct.EXTI_Line=EXTI_Line12;
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_InitStruct.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStruct);
//NVIC管理外部中断
//中断分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel=EXTI15_10_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=6;
NVIC_InitStruct.NVIC_IRQChannelSubPriority=0;
NVIC_Init(&NVIC_InitStruct);
}
//中断服务函数
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line12)==SET)
{
USART_SendString(USART1,"enter itterrupt\r\n");
extern TaskHandle_t task2_handle;
vTaskNotifyGiveFromISR(task2_handle,(void *)pdFALSE);//给任务tsak2通知
EXTI_ClearITPendingBit(EXTI_Line12);
}
}
结果:任务2没收到通知时,一直阻塞,直到中断服务函数给通知后,才从阻塞变为就绪状态
freertos最大任务优先级通过这个宏来配置,最大不超过32,越小越好
#define configMAX_PRIORITIES ( 16 ) //任务最大优先级数
注意,任何的硬件中断皆可以打断任务,最低优先级的中断也可以打断最高优先级的任务,它俩并没有关系。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)