FreeRTOS任务创建与删除(二)

任务创建API函数

        任务创建和删除的API函数,而任务创建有动态创建任务和静态创建任务

        (1)动态创建任务:任务的任务控制块以及任务的栈空间所需的内存,均由 FreeRTOS 从         FreeRTOS 管理的堆中分配 。

        (2)静态创建任务:任务的任务控制块以及任务的栈空间所需的内存,需用户分配提供

        动态任务创建函数:

BaseType_t xTaskCreate(
                TaskFunction_t                                          pxTaskCode,

                const char * const                                      pcName,

                const configSTACK_DEPTH_TYPE          usStackDepth,

                void * const                                                pvParameters,

                UBaseType_t                                             uxPriority,

                TaskHandle_t * const                                pxCreatedTask

)

        

        参数:

                pxTaskCode                 /* 指向任务函数的指针 */

                pcName                        /* 任务名字,最大长度configMAX_TASK_NAME_LEN */

                usStackDepth,              /* 任务堆栈大小,注意字为单位 */

                pvParameters,              /* 传递给任务函数的参数 */

                uxPriority                      /*任务优先级,范围:0 ~ configMAX_PRIORITIES - 1 */

                pxCreatedTask            /* 任务句柄,就是任务的任务控制块 */

        返回值:

                成功:pdPASS

                失败:errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY

        实现动态创建任务流程:
        (1)将宏configSUPPORT_DYNAMIC_ALLOCATION 配置为 1

        (2)定义函数入口参数

        (3)编写任务函数

        使用示例:

/*任务创建任务相关定义*/

#define START_TASK_PRIO 1 /*任务优先级*/

#define START_STK_SZIE 128 /*任务堆栈大小*/

TaskHandle_t START_Handle_t; /*任务句柄*/

void Start_Task(void *p); /*任务函数*/

/*LED闪烁任务相关定义*/

#define LED_TASK_PRIO 3 /*任务优先级*/

#define LED_STK_SZIE 128 /*任务堆栈大小*/

TaskHandle_t LED_Handle_t; /*任务句柄*/

void LED_Task(void *p); /*任务函数*/

/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */

void FreeRTOS_Dome(void)

{

          /*创建任务创建函数*/

        xTaskCreate(Start_Task,"Start_Task",START_STK_SZIE,NULL,START_TASK_PRO,&START_Handle_t);

        /*启动任务调度*/

        vTaskStartScheduler();

}

/*任务创建函数*/

void Start_Task(void *p)

{

        taskENTER_CRITICAL(); /*进入临界区*/

        /*创建LED闪烁任务函数*/

        xTaskCreate(LED_Task,"LED_Task",LED_STK_SZIE,NULL,LED_TASK_PRIO,&LED_Handle_t);

        vTaskDelete(START_Handle_t); /*删除任务创建函数*/

        taskEXIT_CRITICAL(); /*退出临界区*/

}

/*LED闪烁任务函数*/

void LED_Task(void *p)

{

        while(1)

        {

                HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);

                vTaskDelay(500);

                HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);

                vTaskDelay(500);

        }

}

        任务控制块结构体成员介绍

typedef struct tskTaskControlBlock       

{

        /* 任务栈栈顶,必须为TCB的第一个成员 */

            volatile StackType_t * pxTopOfStack;

        /* 任务状态列表项 */  

            ListItem_t xStateListItem;      

        /* 任务事件列表项 */      

        ListItem_t xEventListItem;

        /* 任务优先级,数值越大,优先级越大 */

            UBaseType_t uxPriority;   

        /* 任务栈起始地址 */             

            StackType_t * pxStack;

        /* 任务名字 */

            char pcTaskName[ configMAX_TASK_NAME_LEN ];

         …

        省略很多条件编译的成员

} tskTCB;

        任务栈栈顶,在任务切换时的任务上下文保存、任务恢复息息相关

        注意:每个任务都有属于自己的任务控制块,类似身份证

        静态创建任务函数:

TaskHandle_t xTaskCreateStatic(

             TaskFunction_t                 pxTaskCode,

             const char * const            pcName,

             const uint32_t                  ulStackDepth,

             void * const                      pvParameters,

             UBaseType_t                   uxPriority,

            StackType_t * const         puxStackBuffer,

             StaticTask_t * const         pxTaskBuffer );

        参数:

                pxTaskCode, /* 指向任务函数的指针 */

                pcName, /* 任务函数名 */

                ulStackDepth, /* 任务堆栈大小注意字为单位 */

                pvParameters, /* 传递的任务函数参数 */

                uxPriority, /* 任务优先级 */

                puxStackBuffer, /* 任务堆栈,一般为数组,由用户分配

                pxTaskBuffer /* 任务控制块指针,由用户分配 */

        返回值:

                成功:任务句柄

                失败:NULL

      静态创建任务使用流程:
        (1)需将宏configSUPPORT_STATIC_ALLOCATION 配置为 1

        (2)定义空闲任务&定时器任务的任务堆栈及TCB

        (3)实现两个接口函数:

                1.vApplicationGetIdleTaskMemory();

                2.vApplicationGetTimerTaskMemory();

        (4)定义函数入口参数

        (5)编写任务函数

        此函数创建的任务会立刻进入就绪态,由任务调度器调度运行

        使用示例:

/*任务优先级、任务句柄、任务堆栈大小、任务控制块指针*/

#define START_TASK_PRIO 1

#define START_SIZE 128

TaskHandle_t start_task_handle;

StackType_t start_task_stack[START_SIZE];

StaticTask_t start_task_tcb;

/*任务优先级、任务句柄、任务堆栈大小、任务控制块指针*/

#define TASK1_PRIO 2

#define TASK1_SIZE 50

TaskHandle_t task1_handle;

StackType_t task1_stack[TASK1_SIZE];

StaticTask_t task1_tcb;

/*空闲任务内存配置*/

StaticTask_t idle_task_tcb;

StackType_t idle_task_stack[configMINIMAL_STACK_SIZE];

/*软件定时器内存配置*/

StaticTask_t timer_task_tcb;

StackType_t timer_task_stack[configTIMER_TASK_STACK_DEPTH];

/* 空闲任务内存分配 */

void vApplicationGetIdleTaskMemory(

                StaticTask_t ** ppxIdleTaskTCBBuffer,

                StackType_t ** ppxIdleTaskStackBuffer,

                uint32_t * pulIdleTaskStackSize )

{

        * ppxIdleTaskTCBBuffer = &idle_task_tcb;

        * ppxIdleTaskStackBuffer = idle_task_stack;

        * pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;

}

/* 软件定时器内存分配 */

void vApplicationGetTimerTaskMemory(

                StaticTask_t ** ppxTimerTaskTCBBuffer,

                StackType_t ** ppxTimerTaskStackBuffer,

                uint32_t * pulTimerTaskStackSize )

{

        * ppxTimerTaskTCBBuffer = &timer_task_tcb;

        * ppxTimerTaskStackBuffer = timer_task_stack;

        * pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;

}

/**
 * @brief       FreeRTOS例程入口函数
 * @param       无
 * @retval      无
 */

void freertos_dome(void)

{

        start_task_handle = xTaskCreateStatic(

                                        (TaskFunction_t ) start_task,

                                        (char * ) "start_task",

                                        (uint32_t ) START_SIZE,

                                        (void * ) NULL,

                                        (UBaseType_t ) START_TASK_PRIO,

                                        (StackType_t * )      start_task_stack,

                                        (StaticTask_t * )   &start_task_tcb );

        vTaskStartScheduler();          //开启任务调度

}

void start_task(void *pvParameters)

{

        taskENTER_CRITICAL();           //进入临界区

        task1_handle = xTaskCreateStatic(

                                (TaskFunction_t ) task1,

                                (char * ) "task1",

                                (uint32_t ) TASK1_SIZE,

                                (void * ) NULL,

                                (UBaseType_t ) TASK1_PRIO,

                                (StackType_t * ) task1_stack,

                                (StaticTask_t * ) &task1_tcb );

                                vTaskDelete(start_task_handle);

                                taskEXIT_CRITICAL();            //退出临界区

}

//实现LED0每500ms反转一次

void task1(void *pvParameters)

{

        while(1)

        {

                printf("-----task1正在运行-----\n");

                LED0 = 0;

                vTaskDelay(200);

                LED0 = 1;

                vTaskDelay(200);

        }

}

·  任务删除函数

        void vTaskDelete(TaskHandle_t xTaskToDelete);

                参数:xTaskToDelete /*待删除任务的任务句柄*/

                返回值:无

        用于删除已被创建的任务

        被删除的任务将从就绪态任务列表、阻塞态任务列表、挂起态任务列表和事件列表中移除

        注意

                1、当传入的参数为NULL,则代表删除任务自身(当前正在运行的任务)

                2、空闲任务会负责释放被删除任务中由系统分配的内存,但是由用户在任务删除前申请的内存, 则需要由用户在任务被删除前提前释放,否则将导致内存泄露。

        ·删除任务流程

                (1)使用删除任务函数,需将宏INCLUDE_vTaskDelete 配置为 1

                (2)入口参数输入需要删除的任务句柄(NULL代表删除本身)

  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值