[应用相关] 动、静态创建任务

[复制链接]
392|0
paotangsan 发表于 2025-9-10 18:44 | 显示全部楼层 |阅读模式
TI, ST, AC, ar, ID, RT
任务创建和删除API函数

7605768c0f7587419a.png

xTaskCreat() 、vTaskDelete()函数

1.start_task: 用来创建其他两个任务 ,当此任务运行以后会调用删除任务vTaskDelete()

2.task1_task: 普通应用任务,实现LED2闪烁并用串口打印执行次数

3.task2_task: 普通应用任务,实现LED3闪烁并用串口打印执行次数

下面是动态创建任务代码示例:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"

//开始任务
#define START_TASK_SIZE   120  //堆栈大小
#define START_TASK_PRIO   1    //任务优先级
TaskHandle_t StartTask_Hender; //任务句柄
void start_task( void * pvParameters ); //开始函数

//任务1
#define TASK1_TASK_SIZE   120
#define TASK1_TASK_PRIO   2
TaskHandle_t Task1Task_Hender;
void task1_task( void * pvParameters );

//任务2
#define TASK2_TASK_SIZE   120
#define TASK2_TASK_PRIO   3
TaskHandle_t Task2Task_Hender;
void task2_task( void * pvParameters );

int main(void)
{
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组
        delay_init();                                            //延时函数初始化          
        uart_init(115200);                                        //串口初始化
        LED_Init();                                                          //LED初始化


            xTaskCreate( (TaskFunction_t)        start_task,
                   (char *)                "start_task",
                   (configSTACK_DEPTH_TYPE) START_TASK_SIZE,
                   (void *)                 NULL,
                   (UBaseType_t)            START_TASK_PRIO,
                   (TaskHandle_t *)         &StartTask_Hender);
       
    vTaskStartScheduler();          //开启任务调度
}


void start_task( void * pvParameters )
{
           //Task1
      xTaskCreate( (TaskFunction_t)         task1_task,//任务函数
                   (char *)                "task1_task", //任务名
                   (configSTACK_DEPTH_TYPE) TASK1_TASK_SIZE,//任务堆栈大小
                   (void *)                 NULL, //传递给任务函数的参数
                   (UBaseType_t)            TASK1_TASK_PRIO,//任务优先级
                   (TaskHandle_t *)         &Task1Task_Hender);//任务句柄
          //Task2
                  xTaskCreate( (TaskFunction_t)     task2_task,
                   (char *)                "task2_task",
                   (configSTACK_DEPTH_TYPE) TASK2_TASK_SIZE,
                   (void *)                 NULL,
                   (UBaseType_t)            TASK2_TASK_PRIO,
                   (TaskHandle_t *)         &Task2Task_Hender);
       
                                                                         
                                vTaskDelete(StartTask_Hender);//删除开始函数                         
                                                                          
}
//任务1函数
void task1_task( void * pvParameters )
{
    char task_num = 0;
    while(1)
    {
                        task_num++;
                        if(task_num == 5)
                        {
                                vTaskDelete(Task2Task_Hender);//当任务1执行5次删除任务2
                                printf("Task2 is Delete \r\n");
                        }
                LED2 = !LED2;
                            vTaskDelay(1000);
                       
                        printf("Task1 is runing   %d \r\n",task_num);//串口打印任务1执行次数
                       
                }

}
//任务2函数
void task2_task( void * pvParameters )
{
    char task2_num = 0;
    while(1)
    {
                        task2_num++;
            LED3 = !LED3;
                        vTaskDelay(1000);
                        printf("Task2 is runing   %d \r\n",task2_num);//串口打印任务2执行次数
                       
                }
}



用串口验证函数的执行:

2588568c0f751437d5.png

如果要使用静态方法需要将宏 ConfigSUPPORT_STATIC_ALLOCATION 设置为1

1.start_task: 用来创建两个任务

2.task1_task: 普通应用任务,实现LED2闪烁并用串口打印执行次数

3.task2_task: 普通应用任务,实现LED3闪烁并用串口打印执行次数

1.静态内存分配的要求
FreeRTOS 默认使用动态内存分配(从堆中分配任务栈和任务控制块TCB)。当启用 静态内存分配(通过configSUPPORT_STATIC_ALLOCATIO N=1)时,用户需自行提供任务所需的内存空间(栈和TCB),否则内核无法运行。
2.系统任务的特殊性
·空闲任务(IdleTask):FreeRTOS 必须的空闲任务,用于清理已删除的任务和进入低功耗模式。
·定时器任务(TimerTask):如果启用软件定时器(configUSE_TIMERS =1),系统需要一个专用任务处理定时器回调。
这两个任务是FreeRTOS 内核的“基础设施”,用户需为它们显式分配静态内存。

步骤:
1.修改宏 , ConfigSUPPORT_STATIC_ALLOCATION  = 1

有两个函数未定义,给函数定义:

①.vApplicationGetIdleTaskMemory    给空闲任务分配内存                                   ②.vApplicationGetTimerTaskMemory    给定时器任务分配内存

2.编写测试代码    开始任务  框架   

  task1 task2 框架   

  测试

下面是静态创建任务代码:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"


//开始任务
#define START_TASK_SIZE 120//堆栈大小
#define START_TASK_PRIO 1//任务优先级
StackType_t  StartTaskStack[START_TASK_SIZE];//任务堆栈
StaticTask_t StartTask_TCB;//任务控制块
TaskHandle_t StartTask_Handle;//任务句柄
void start_task( void * pvParameters );//开始函数声明

//任务1
#define TASK1_TASK_SIZE 120
#define TASK1_TASK_PRIO 3
StackType_t  Task1TaskStack[TASK1_TASK_SIZE];
StaticTask_t Task1Task_TCB;
TaskHandle_t Task1Task_Handle;
void task1_task( void * pvParameters );

//任务2
#define TASK2_TASK_SIZE 120
#define TASK2_TASK_PRIO 2
StackType_t  Task2TaskStack[TASK2_TASK_SIZE];
StaticTask_t Task2Task_TCB;
TaskHandle_t Task2Task_Handle;
void task2_task( void * pvParameters );

//空闲任务
static StaticTask_t IdleTaskTCB;
static StackType_t  IdleTaskStack[configMINIMAL_STACK_SIZE];

   void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
                                       StackType_t ** ppxIdleTaskStackBuffer,
                                       uint32_t * pulIdleTaskStackSize )
         {
            
              *ppxIdleTaskTCBBuffer = &IdleTaskTCB;
                    *ppxIdleTaskStackBuffer = IdleTaskStack;
                    *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
         
         }

//定时器任务
static StaticTask_t TimerTaskTCB;
static StackType_t  TimerTaskStack[configTIMER_TASK_STACK_DEPTH];
         
void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
                                      StackType_t ** ppxTimerTaskStackBuffer,
                                      uint32_t * pulTimerTaskStackSize )
{

      * ppxTimerTaskTCBBuffer = &TimerTaskTCB;
            * ppxTimerTaskStackBuffer = TimerTaskStack;
      *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;

}

         
         
         
int main(void)
{
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
        delay_init();                                                      
        uart_init(115200);                                       
        LED_Init();                                                         
       
        StartTask_Handle =  xTaskCreateStatic( (TaskFunction_t) start_task,//任务函数
                                  (char * )        "start_task", //函数名
                                  (uint32_t)       START_TASK_SIZE,//堆栈大小
                                  (void *)         NULL,//传递给任务函数的参数
                                  (UBaseType_t)    START_TASK_PRIO,//任务优先级
                                  (StackType_t *)  StartTaskStack,//任务堆栈
                                  (StaticTask_t *) &StartTask_TCB );//任务控制块

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

void start_task( void * pvParameters )
{
   while(1)
         {
                 //任务1
           Task1Task_Handle =  xTaskCreateStatic( (TaskFunction_t) task1_task,
                                  (char * )        "task1_task",
                                  (uint32_t)       TASK1_TASK_SIZE,
                                  (void *)         NULL,
                                  (UBaseType_t)    TASK1_TASK_PRIO,
                                  (StackType_t *)  Task1TaskStack,
                                  (StaticTask_t *) &Task1Task_TCB );
                                                                                                                                       
                //任务2                                                                                       
           Task2Task_Handle =  xTaskCreateStatic( (TaskFunction_t) task2_task,
                                  (char * )        "task2_task",
                                  (uint32_t)       TASK2_TASK_SIZE,
                                  (void *)         NULL,
                                  (UBaseType_t)    TASK2_TASK_PRIO,
                                  (StackType_t *)  Task2TaskStack,
                                  (StaticTask_t *) &Task2Task_TCB );
            
               vTaskDelete(StartTask_Handle);//删除开始函数
         }
       
}
//任务1
void task1_task( void * pvParameters )
{
   char Task1_num = 0;
while(1)
{
   Task1_num++;
   LED2 = !LED2;
   vTaskDelay(1000);
   printf("Task1 is Runing %d \r\n",Task1_num);//打印任务1执行次数

}

}
//任务2
void task2_task( void * pvParameters )
{
        char Task2_num = 0;
while(1)
{
   Task2_num++;
   LED3 = !LED3;
   vTaskDelay(1000);
   printf("Task2 is Runing %d \r\n",Task2_num);//打印任务2执行次数

}


}



串口打印:

8197468c0f73fba75a.png

————————————————
版权声明:本文为CSDN博主「今天阳光明媚吗」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/2502_90478897/article/details/146986776

您需要登录后才可以回帖 登录 | 注册

本版积分规则

78

主题

4323

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部