6,FreeRTOS临界区代码保护与任务调度器的挂起与恢复

一、临界区代码保护


       如果我们想在执行某段代码时不被中断打断,此时需要进行临界区代码保护 。在临界区内关闭中断,临界区结束后开启中断。

        需要注意的是临界区的进入和退出需要成对出现,如果进入两次,那么需要退出两次才可以成功开启中断。

注:本实验基于正点原子FreeRTOS教程的学习总结。

1..所需API函数介绍

        taskENTER_CRITICAL函数用来进入临界区。在任务中调用。

#define taskENTER_CRITICAL()               portENTER_CRITICAL()

          taskENTER_CRITICAL_FROM_ISR函数用来进入临界区,返回值为临界区状态。在FreeRTOS管理的中断中调用。

#define taskENTER_CRITICAL_FROM_ISR()      portSET_INTERRUPT_MASK_FROM_ISR()
//例子:
uint_t status;
status = taskENTER_CRITICAL_FROM_ISR();

      taskENTER_CRITICAL函数用来退出临界区。在任务中调用。

#define taskEXIT_CRITICAL()                portEXIT_CRITICAL()

          taskENTER_CRITICAL_FROM_ISR函数用来退出临界区,输入值为临界区状态。在FreeRTOS管理的中断中调用。

#define taskEXIT_CRITICAL_FROM_ISR()      portSET_INTERRUPT_MASK_FROM_ISR()
//例子:
taskEXIT_CRITICAL_FROM_ISR(status);

2.临界区的任务代码内容

        taskENTER_CRITICAL()函数进入临界区,关闭中断(任务不会切换)。

        taskEXIT_CRITICAL()函数退出临界区,开启中断。

void start_task(void *pvParameters)
{
		taskENTER_CRITICAL();					//进入临界区,关闭中断(任务不会切换)
		//创建task1
    xTaskCreate((TaskFunction_t )task1,                 /* 任务函数 */
                (const char*    )"task1",          			/* 任务名称 */
                (uint16_t       )TASK1_STK_SIZE,        /* 任务堆栈大小 */
                (void*          )NULL,                  /* 传入给任务函数的参数 */
                (UBaseType_t    )TASK1_PRIO,       			/* 任务优先级 */
                (TaskHandle_t*  )&Task1_Handler);   		/* 任务句柄 */					
		vTaskDelete(NULL);//删除start_task任务
		taskEXIT_CRITICAL();			//推出临界区,开启中断
}

二、任务调度器的挂起与恢复


       任务调度器的挂起与进入临界区不同,任务调度器的挂起主要防止任务间的资源争夺。任务调度器挂起后当前任务不能切换,相当于屏蔽PendSV标志,但是可以被中断打断;而进入临界区,任务不可以切换,中断不能打断。

1..所需API函数介绍

        vTaskSuspendAll函数用来任务调度器的挂起。在任务中调用。

void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION;

         xTaskResumeAll函数用来任务调度器的恢复,返回值表示是否需要进行任务切换,pdTRUE表示需要任务切换,pdFAULT表示不需要任务切换。在任务中调用。

BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION;

  2.任务调度器的挂起与恢复代码内容

        vTaskSuspendAll()函数挂起任务调度器(任务不会切换)。

        xTaskResumeAll()函数恢复任务调度器(任务可以切换)。

void start_task(void *pvParameters)
{
		taskENTER_CRITICAL();					//进入临界区,关闭中断(任务不会切换)
		//创建task1
    xTaskCreate((TaskFunction_t )task1,                 /* 任务函数 */
                (const char*    )"task1",          			/* 任务名称 */
                (uint16_t       )TASK1_STK_SIZE,        /* 任务堆栈大小 */
                (void*          )NULL,                  /* 传入给任务函数的参数 */
                (UBaseType_t    )TASK1_PRIO,       			/* 任务优先级 */
                (TaskHandle_t*  )&Task1_Handler);   		/* 任务句柄 */					
		vTaskDelete(NULL);//删除start_task任务
		taskEXIT_CRITICAL();			//推出临界区,开启中断
}

你可能感兴趣的:(FreeRTOS学习笔记,单片机,stm32,嵌入式硬件,freeRTOS,FreeRTOS)