FreeRTOS操作系统,在按键中断函数中恢复被挂起的任务,程序卡死的原因和解决办法

出现问题场景
 
      作为刚接触FreeRTOS实时操作系统的菜鸟,我在练习一个程序功能:按键3按下,将LED闪烁的任务挂起;按键4按下,将LED闪烁的任务恢复到就绪。按键使用外部中断。恢复就绪的语句是   xTaskResumeFromISR(xHandleTaskLED1(该函数用于在中断中恢复一个被挂起的任务)。
    两个按键的中断优先级程序如下:
    /*------------------------------------------------------------------------*/
    HAL_NVIC_SetPriority(EXTI3_IRQn, 2, 0);    //KEY3按键中断优先级配置
    HAL_NVIC_EnableIRQ(EXTI3_IRQn);
    
    HAL_NVIC_SetPriority(EXTI4_IRQn, 3, 0);    //KEY4按键中断优先级配置
    HAL_NVIC_EnableIRQ(EXTI4_IRQn);
   /*------------------------------------------------------------------------*/
 
  按键3的中断优先级配置为2,按键4配置为3。按键3的挂起任务是在另一个任务中实现,按下按键3后正常将LED任务挂起。按键4的恢复任务在中断中,按下按键4出现整个系统卡死,没有任何反应。
 
 
出现问题原因
  • 在使用FreeRTOS系统时,如果想在中断中恢复一个被挂起的任务,需要使用 xTaskResumeFromISR( TaskHandle_t xTaskToResume)函数,而不是 xTaskResume(TaskHandle_t xTaskToResume) 函数。
  • 当单片机芯片使用的是CM内核的MCU,官方强烈建议将NVIC的优先级分组配置为全抢占式优先级,没有响应式优先级。这样方便系统管理。我看了以下我的设置:HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); 全为抢占式优先级,正常。
  • 在系统的 FreeRTOSConfig.h 配置头文件里,定义了一个宏定义: #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 。它的意思是:用户可以在抢占式优先级为 5 - 15的中断里调用FreeRTOS的API函数(抢占式式优先级为0的中断里面不允许调用)。 仔细看,我定义的是从5-15的优先级中断可以去调用系统的API,但是上面的代码中,我把两个按键的优先级设置为2和3,已经超过了5-15的抢占式优先级范围,所以我按下按键后,调用不了恢复任务函数
 
解决办法
  • 我将  #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 宏定义改为  #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 1 (因为0级抢占式优先级不允许用户使用)。这表明 在 1 - 15级的抢占式优先级范围,我的按键3和按键4的中断优先级在范围之内,可以调用系统的API函数了。这样,我的问题就解决了。

你可能感兴趣的:(FreeRTOS操作系统,在按键中断函数中恢复被挂起的任务,程序卡死的原因和解决办法)