FreeRTOS 任务管理之任务转移

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jnu_fangzebin/article/details/51781054

任务转移

任务状态

讲到任务调度,就要先讲讲任务的几种状态:大类分为:非运行态和运行态,非运行态又可分为三种状态,如下:

  • 阻塞状态:非运行态的子状态,表示任务正处于等待某个事件的状态;
    任务可以进入阻塞态以等待以下两种不同类型的事件:

    定时(时间相关)事件——这类事件可以是延迟到期或是绝对时间到点。比如说某个任务可以进入阻塞态以延迟 10ms;

    这个有两个API函数可以调用来进行延时,第一个函数
    void vTaskDelay( const TickType_t xTicksToDelay )
    xTicksToDelay:表示延时多少个心跳周期,调用该延迟函数的任务将进入阻塞态,经延迟指定的心跳周期数后,再转移到就绪态;经常使用portTICK_PERIOD_MS将延时周期转换为Ms为单位,如延时100Ms:
    VTaskDelay(100/portTICK_PERIOD_MS);
    第二个函数
    void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement )
    该函数于实现某个任务以固定频率周期性执行,
    pxPreviousWakeTime: 保存了上次被唤醒的时刻值,
    xTimeIncrement :则指定任务固定频率的周期;举个例子:

static void vLEDTask( void *pvParameters )  
    {  
        TickType_t previousWakeTime;
        previousWakeTime = xTaskGetTickCount();
        while(1)
        {
            LED_Toggle(GREEN_LED_Toggle);
            printf("LED Toggle\n");
            vTaskDelay(300/portTICK_PERIOD_MS);//延时300Ms
            vTaskDelayUntil(&previousWakeTime, 100/portTICK_PERIOD_MS);//以100Ms为单位周期性执行
        }
    }

同步事件——源于其它任务或中断的事件。比如说,某个任务可以进入阻塞
态以等待队列中有数据到来。同步事件囊括了所有板级范围内的事件类型。

  • 挂起状态:非运行态的子状态,在这个状态下,调度器无法调度该任务;进入该状态只能调用 vTaskSuspend() API 函数,而将一个挂起的任务唤醒只能调用vTaskResume() 或
    vTaskResumeFromISR() API 函数。

  • 就绪状态:非运行态的子状态,处于非运行态的任务如果没有被挂起或阻塞,那么该任务处于准备运行状态及就绪状态,但是还没有运行,只是准备运行。

  • 运行态:表示该任务当前正在运行,执行相关的代码。

任务状态转移图

下面就用一个图来说明个状态之间的转移:

猜你喜欢

转载自blog.csdn.net/jnu_fangzebin/article/details/51781054