12 中断管理

参考教程:

B站普中视频教程

12-1 临界段保护

临界段就是一段执行时不能被打断的代码段。不过系统调度和外部中断可能打断临界段。在FreeRTOS中,系统调度本质上是产生PendSV中断,也是一种中断,所以FreeRTOS对临界段的保护本质上就是对中断的开关控制。

12-1-1 Cortex-M内核快速开关中断指令

Cortex-M内核专门设置了一条CPS指令。在FreeRTOS中,对中断的开关时通过操作BASEPRI寄存器实现的,大于等于BASEPRI的值的中断会被临界段屏蔽,反之不会屏蔽,不受FreeRTOS管理。可以通过设置BASEPRI的值来为一些中断设置“特权”。

12-1-2 关中断

不带返回值:portDISABLE_INTERRUPTS(),带返回值:portSET_INTERRUPT_MASK_FROM_ISR()

  • FreeRTOS关中断的函数在portmacro.h中定义。实际上都是改变BASEPRI寄存器的值。

  • 分带返回值和不带返回值两种。

    • 带返回值的关中断函数可以在中断中使用,反之不可。

12-1-3 临界区

临界段代码就是临界区。比如有的外设启动初始化的时候需要严格的时序,不能被打断。

FreeRTOS在进入临界区的时候需要关闭中断,处理完临界区后再打开中断。 FreeRTOS本身就有很多临界区,且都加了临界区保护。有时用户程序也需要且可以添加临界区保护。

FreeRTOS共有两个任务级、两个中断级的临界区保护函数。

12-1-3-1 任务级临界段代码保护

进入临界区:taskENTER_CRITICAL(),退出临界区:taskEXIT_CRITICAL()

成对调用,其中间的代码就是临界段代码,临界段代码需要精简!

void taskCritical_test(void) {
    while(1)
    {
        taskENTER_CRITICAL();
        total_num++;
        printf("total_num 的值为: %.4f\r\n",total_num);
        taskEXIT_CRITICAL();
        vTaskDelay(1000);
    }
}
12-1-3-2 中断级临界段代码保护

进入临界区:taskENTER_CRITICAL_FROM_ISR(),退出临界区:taskEXIT_CRITICAL_FROM_ISR()

用法与任务级一致。

12-2 中断管理

  • 在FreeRTOS中,可以通过更改FreeRTOSConfig.h中的宏configLIBRARY_LOWEST_INTERRUPT_PRIORITY来更改寄存器BASEPRI的。

12-3 示例

#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "usart.h"
#include "FreeRTOS.h"
#include "task.h"
#include "key.h"
#include "timer.h"

//任务优先级
#define START_TASK_PRIO        1
//任务堆栈大小    
#define START_STK_SIZE         128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

// LED1任务
#define LED1_TASK_PRIO        2
#define LED1_STK_SIZE         50  
TaskHandle_t LED1Task_Handler;
void led1_task(void *pvParameters);

// 中断管理任务
#define InterruptCtrl_TASK_PRIO     4
#define InterruptCtrl_STK_SIZE      50
TaskHandle_t InterruptCtrl_Task_Handler;
void InterruptCtrl_task(void *pvParameters);

int main()
{
    SysTick_Init(72);
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
    LED_Init();
    USART1_Init(115200);
    TIM3_Init(10000-1, 7200-1);
    TIM4_Init(10000-1, 7200-1);

    printf("Program starting!\n");

    //创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}

//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区

    //创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler); 

    // 创建中断管理任务
    xTaskCreate((TaskFunction_t )InterruptCtrl_task,     
                (const char*    )"InterruptCtrl_task",   
                (uint16_t       )InterruptCtrl_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )InterruptCtrl_TASK_PRIO,
                (TaskHandle_t*  )&InterruptCtrl_Task_Handler); 

    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
} 

//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
        LED_Ctrl(1, LIGHT_ON);
        LED_Ctrl(2, LIGHT_ON);
        vTaskDelay(800);
        LED_Ctrl(1, LIGHT_OFF);
        LED_Ctrl(2, LIGHT_OFF);
        vTaskDelay(200);
    }
}

// 中断管理任务
void InterruptCtrl_task(void *pvParameters)
{
    while(1)
    {
        printf("InterruptCtrl_task: Disable NVIC\n");
        portDISABLE_INTERRUPTS();
        delay_xms(5000);
        printf("InterruptCtrl_task: Enable NVIC\b");
        portENABLE_INTERRUPTS();
        delay_xms(5000);
    }
}
Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐