• FreeRtos——任务删除,改变任务优先级


    以下转载自安富莱电子: http://forum.armfly.com/forum.php

    vTaskDelete() API 函数
    任务可以使用 API 函数 vTaskDelete()删除自己或其它任务。
    任务被删除后就不复存在,也不会再进入运行态。
    空闲任务的责任是要将分配给已删除任务的内存释放掉。因此有一点很重要,那就
    使用 vTaskDelete() API 函数的任务千万不能把空闲任务的执行时间饿死
    需要说明一点,只有内核为任务分配的内存空间才会在任务被删除后自动回收。任
    务自己占用的内存或资源需要由应用程序自己显式地释放。

    在使用这个API函数之前,需要配置INCLUDE_vTaskDelete == 1。

    刚开始,看历程有点不解,给一个任务句柄初始化为NULL,为什么删除任务(非自身任务)的时候,传入的还是句柄,句柄不是初始化为NULL了吗?思前想后觉得应该是xTaskCreate创建函数会更改任务句柄的值,果然,xTaskCreate函数接受的任务句柄是个二级指针,就算我们给任务句柄初始化为NULL,xTaskCreate函数执行之后,任务句柄会被更改为一个非NULL指针。所以就有了下面的代码:

    //初始化任务句柄

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

    //创建任务

    static void AppTaskCreate(void)
    {
        xTaskCreate(vTaskLed1,           /* 任务函数名 */
                    "Task Led1",         /* 任务名,字符串形式,方便调试 */
                     512,                /* 栈大小,单位为字,即4个字节 */
                     (void *)&task_led3, /* 任务形参 */
                     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)即可。

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

     函数 vTaskPrioritySet 用于实现 FreeRTOS 任务优先级的修改。
    第 1 个参数是任务句柄,用于区分不同的任务。
    第 2 个参数是给任务配置的新优先级。
    使用这个函数要注意以下问题:
    1. 使用此函数需要在 FreeRTOSConfig.h 配置文件中配置如下宏定义为 1
    #define INCLUDE_vTaskPrioritySet 1
    2. 如果第一个参数里面填的是 NULL,即数值 0 的话,那么配置的就是当前正在执行的任务。
    3. 如果被修改的任务的优先级,修改后高于正在执行的任务,将执行任务切换,切换到修改好的高优先级任务。
    4. 第二个参数数值不可大于等于 FreeRTOSConfig.h 文件中的宏定义:
    #define configMAX_PRIORITIES 配置的数值。

    使用这个函数要注意以下问题:
    1. 使用此函数需要在 FreeRTOSConfig.h 配置文件中配置如下宏定义为 1
    #define INCLUDE_vTaskPriorityGet 1
    2. 如果第一个参数里面填的是 NULL,即数值 0 的话,那么获取的优先级就是当前正在执行的任务。

    改变任务优先级
    调度器总是在所有就绪态任务中选择具有最高优先级的任务,并使其进入运行态。
    本例即是通过调用 vTaskPrioritySet() API 函数来改变两个任务的相对优先级,以达到
    对调度器这一行为的演示。
    在不同的优先级上创建两个任务。这两个任务都没有调用任何会令其进入阻塞态的
    API 函数,所以这两个任务要么处于就绪态,要么处于运行态——这种情形下,调度器
    选择具有最高优先级的任务来执行。
    所以,我们创建任务一LED亮,优先级1,任务二,蜂鸣器响,优先级2。这样在不阻塞的情况下,只会执行任务2,蜂鸣器响,但是,我们在任务二中,修改任务一的优先级,使它高于任务二。步骤如下:

    void vTaskLed1(void *pvParameters)
    {
        /* 任务都是一个无限,不能返回 */
        int *piParameters;
        piParameters=(int *)pvParameters;
        while(1)
        {
            if(*piParameters==1)
            {
                LED1( ON );
                /* 阻塞延时,单位ms */        
                vTaskDelay( 500 );
                LED1( OFF );    
                vTaskDelay( 500 );
            }
            else if(*piParameters==2)
            {
                LED2( ON );
                /* 阻塞延时,单位ms */        
                vTaskDelay( 500 );
                LED2( OFF );    
                vTaskDelay( 500 );
            }
            else if(*piParameters==3)
            {
                LED3( ON );
    
            }
        }    
    }
    /*********************************************************************************
      * @ 函数名  : vTaskBeep
      * @ 功能说明: Beep 任务
      * @ 参数    : pvParameters,当任务创建的时候传进来,可以没有  
      * @ 返回值  : 无
      ********************************************************************************/
    void vTaskBeep(void *pvParameters)
    {
        /* 任务都是一个无限循环,不能返回 */
        while(1)
        {
            BEEP_ON;    
    
        }    
    }

    上面代码,任务2,beep优先级为2,任务1,led优先级为1,没有阻塞操作,调度器只执行优先级高的任务2,但是,我们更改任务2代码如下:

    void vTaskBeep(void *pvParameters)
    {
        /* 任务都是一个无限循环,不能返回 */
        while(1)
        {
            BEEP_ON;
            vTaskPrioritySet(xHandleTaskLED1,3);
            
        }    
    }

    把任务一优先级设成3,这样任务2运行到vTaskPrioritySet ()函数后(就算vTaskPrioritySet 函数后面还有程序都不会再执行),调度器会重新选择优先级更高的执行。

    再试试我们用vTaskPrioritySet 的NULL参数修改自身优先级为1,这样任务1,2优先级都是1,这样都可以运行。

    void vTaskBeep(void *pvParameters)
    {
        /* 任务都是一个无限循环,不能返回 */
        while(1)
        {
            BEEP_ON;
            vTaskPrioritySet(NULL,1);
        }    
    }
  • 相关阅读:
    Django之POST GET与前后端交互
    Django中用户权限模块
    Django运算表达式与Q对象/F对象
    Django中Middleware中间件
    Form表单 JSON Content-type解析
    浅析ajax原理与用法
    浅析Django之session与cookie
    浅谈HTTP协议
    Django 项目搭建(ubuntu系统)
    h5 和之前版本的区别
  • 原文地址:https://www.cnblogs.com/yangguang-it/p/7097408.html
Copyright © 2020-2023  润新知