FreeRTOS中断测试避坑指南

电子说

1.2w人已加入

描述

FreeRTOS中断简介

任何调用中断安全FreeRTOS API函数的中断服务例程都可以使用的最高中断优先级。不要从任何优先级高于此的中断调用中断安全FREERTOS API函数(优先级越高,数值越低)。

代码如下(版本FreeRTOS V202107.00):

/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS
 /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
 #define configPRIO_BITS         __NVIC_PRIO_BITS
#else
 #define configPRIO_BITS         4        /* 15 priority levels */
#endif

/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY   0xf

/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5

/* Interrupt priorities used by the kernel port layer itself.  These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY   ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY  ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

 

configMAX_SYSCALL_INTERRUPT_PRIORITY 高于此优先级的中断,不能被禁止。

cpu

测试过程

开启定时器TIM6和TIM7,两个定时器每隔一定时间串口打印一次,设置定时器TIM6中断优先级为4,定时器TIM7中断优先级为5, 高于 5 的优先级(即优先级数小于5)不归操作系统管理。

简而言之,定时器TIM6不归FreeRTOS管理,在关闭中断时,低于优先级5的都会被关闭,高于或者等于优先级5的都会被关闭。

1、创建中断测试任务

 

xTaskCreate((TaskFunction_t )interrupt_task,            //任务函数
            (const char*    )"interrupt_task",          //任务名称
            (uint16_t       )INTERRUPT_STK_SIZE,        //任务堆栈大小
            (void*          )NULL,                      //传递给任务函数的参数
            (UBaseType_t    )INTERRUPT_TASK_PRIO,       //任务优先级
            (TaskHandle_t*  )&INTERRUPTTask_Handler);   //任务句柄

 

2、中断测试任务函数

 

void interrupt_task(void *pvParameters)
{
    static u32 count_num=0;
    while(1)
    {
        count_num++;
        if(count_num==5) 
        {
            printf("关闭中断.............
");
            portDISABLE_INTERRUPTS();              //关闭中断
            delay_xms(5000);                       //延时5s
            printf("打开中断.............
");    
            portENABLE_INTERRUPTS();               //打开中断
        }
        vTaskDelay(1000);//延时1000个时钟节拍,就是1s   configTICK_RATE_HZ
    }
}  

 

3、定时器中断服务函数

 

void TIM6_IRQHandler(void)
{
  if(TIM_GetITStatus(TIM6, TIM_IT_Update)) //是否产生中断
   {
         printf("TIM6中断
");
         TIM_ClearITPendingBit(TIM6,TIM_IT_Update);//清除中断标志位
   }
}

void TIM7_IRQHandler(void)
{
  if(TIM_GetITStatus(TIM7, TIM_IT_Update)) //是否产生中断
   {
         printf("TIM7中断
");
         TIM_ClearITPendingBit(TIM7,TIM_IT_Update);//清除中断标志位
   }
}

 

4、测试结果

cpu

5、注意事项

临界区、中断服务函数、开关中断中不能使用vTaskDelay()函数,此函数就是要交出CPU一段时间,如果任务一直不延时或者挂起,那么低优先级的任务会无法获得CPU。







审核编辑:刘清

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分