FreeRTOS—-改变任务优先级,任务删除

vTaskPrioritySet() API  函数可以用于在调度器启动后改变任何任务的优先级。

函数原型:

void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority );

uxTaskPriorityGet() API 函数用于查询一个任务的优先级。

函数原型:unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask );

调度器总是在所有就绪态任务中选择具有最高优先级的任务,并使其进入运行态。

修改任务优先级的任务实现:

 

任务在查询和修改自己的优先级时,并没有使用一个有效的句柄——使用 NULL代替。只有在某个任务需要引用其它任务的时候才会用到任务句柄。好比任务 1 想要改变任务 2 的优先级,为了让任务 1 能够使用到任务 2 的句柄,在任务 2 被创建时其句柄就被获得并保存下来。如下面注释所示:

执行流程图如下:

   删除任务

vTaskDelete() API 函数

  任务可以使用 API 函数 vTaskDelete()删除自己或其它任务。

  任务被删除后就不复存在,也不会再进入运行态。

  空闲任务的责任是要将分配给已删除任务的内存释放掉。因此有一点很重要,那就是使用 vTaskDelete() API 函数的任务千万不能把空闲任务的执行时间饿死。

  需要说明一点,只有内核为任务分配的内存空间才会在任务被删除后自动回收。任务自己占用的内存或资源需要由应用程序自己显式地释放。

函数原型:  void vTaskDelete( xTaskHandle pxTaskToDelete );

[eg]  : 任务 1 在 main()中创建在优先级 1 上。任务 1 运行时,以优先级 2 创建任务 2。现在任务 2 具有最高优先级,所以会立即得到执行。

  任务 2 什么也没有做,只是删除自己。可以通过传递 NULL 值以 vTaskDelete()来删除自己,但是为了纯粹的演示,传递的是任务自己的句柄。

  当任务 2 被自己删除之后,任务 1 成为最高优先级的任务,所以继续执行,调用vTaskDelay()阻塞一小段时间。

  当任务 1 进入阻塞状态后,空闲任务得到执行的机会。空闲任务会释放内核为已删除的任务 2 分配的内存。

  任务 1 离开阻塞态后,再一次成为就绪态中具有最高优先级的任务,因此会抢占空闲任务。又再一次创建任务 2,如此往复。

 函数执行流程:

 


static TaskHandle_t xHandleTaskLED1 = NULL;
static TaskHandle_t xHandleTaskBeep = NULL;

static void AppTaskCreate(void)
{
    xTaskCreate(vTaskLed1,           /* 任务函数名 */
                "Task Led1",         /* 任务名,字符串形式,方便调试 */
                 512,                /* 栈大小,单位为字,即4个字节 */
                 NULL,               /* 任务形参 */
                 1,                  /* 优先级,数值越大,优先级越高 */
                 &xHandleTaskLED1);  /* 任务句柄 */
    
    xTaskCreate(vTaskBeep,"Task Beep",512,NULL,2,&xHandleTaskBeep);
}

 

 //在任务beep中删除led任务

void vTaskBeep(void *pvParameters)
{
    /* 任务都是一个无限循环,不能返回 */
    while(1)
    {
        BEEP_ON;
    /* 阻塞延时,单位ms */        
        vTaskDelay( 20 );
        BEEP_OFF;    
        vTaskDelay( 500 );
        if(xHandleTaskLED1 != NULL)
            vTaskDelete(xHandleTaskLED1);
    }    
}

led的任务句柄,虽然初始化为NULL,但是任务创建函数执行之后,任务句柄(是个一级指针)会被二级指针改变,所以当它不是NULL的时候,证明led任务被创建,就可以在beep中将其删除,如果要删除beep任务自身,vTaskDelete(NULL)即可。

posted @ 2017-07-02 16:37  Liu_Jing  Views(2715)  Comments(0Edit  收藏  举报