任务创建和删除的API函数

  • xTaskCreate():使用动态方法创建一个任务
  • xTaskCreateStatic():使用静态方法创建一个任务
  • xTaskCreateRestricated():创建一个使用MPU进行限制的任务,相关内存使用动态内存分配
  • vTaskDelete():删除一个任务

xTaskCreate

使用该函数,configSUPPORT_DYNAMIC_ALLOCATION要设置为1

 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )BaseType_t xTaskCreate(   TaskFunction_t pxTaskCode,const char * const pcName,const uint16_t usStackDepth,void * const pvParameters,UBaseType_t uxPriority,TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
#endif
  • pxTaskCode:函数名,任务执行的函数,我们可以把一个任务当做一个函数,只不过这个函数可以循环执行
  • pcName:任务名字,一般用于追踪和调试,任务名字不能超过configMAX_TASK_NAME_LEN,configMAX_TASK_NAME_LEN在FreeRTOSConfig.h文件中
  • usStackDepth:任务堆栈大小,实际申请到的堆栈是usStackDepth的4倍,其中空闲任务堆栈大小为configMINIMAL_STACK_SIZE,configMINIMAL_STACK_SIZE在FreeRTOSConfig.h文件中定义
  • pvParameters:传递给任务函数的参数
  • uxPriority:任务优先级,范围是0-configMAX_PRIORITIES-1
  • pxCreatedTask:任务句柄,任务创建成功后会返回此任务的任务句柄。

返回值:
pdPASS if the task was successfully created and added to a ready list, otherwise an error code defined in the file projdefs.h

xTaskCreateStatic

使用该函数,configSUPPORT_STATIC_ALLOCATION要等于1

#if( configSUPPORT_STATIC_ALLOCATION == 1 )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 ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
#endif /* configSUPPORT_STATIC_ALLOCATION */

参数的具体函数可以看xTaskCreate,

  • ulStackDepth:需要由用户给出,一般是一个数组,此参数就是这个数组的大小
  • puxStackBuffer:Must point to a StackType_t array that has at least ulStackDepth indexes - the array will then be used as the task’s stack,removing the need for the stack to be allocated dynamically.
  • pxTaskBuffer:任务控制块,pxTaskBuffer Must point to a variable of type StaticTask_t, which will then be used to hold the task’s data structures, removing the need for the memory to be allocated dynamically.

返回值:
If neither pxStackBuffer or pxTaskBuffer are NULL, then the task will be created and pdPASS is returned. If either pxStackBuffer or pxTaskBuffer are NULL then the task will not be created and errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY is returned.

xTaskCreateRestricted

使用该函数,portUSING_MPU_WRAPPERS=1

#if( portUSING_MPU_WRAPPERS == 1 )BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) PRIVILEGED_FUNCTION;
#endif
  • pxTaskDefinition:是一个结构体,描述任务函数、堆栈大小优先级等,在task.h定义
  • pxCreatedTask:任务句柄

vTaskDelete

void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION;
  • xTaskToDelete:要删除任务的任务句柄
    被删除的任务不再存在,对于那些有内核自动分配给任务的内存,该函数会自动释放掉,用户给任务分配的内存需要用户自行释放掉,比如pvPortMalloc()分配了500字节的内存,那么在任务被删除之后,用户需要调用vPortFree函数将这些内存删除,否则会导致内存泄露

设计

一共有三个任务:

  • start_task:用来创建其他两个任务
  • task1_task:次任务运行5次以后,调用vTaskDelete删除任务task2_task,此任务也会控制LED0闪烁,并且周期性刷新LCD指定区域的背景颜色
  • task2_task:此任务普通的应用任务,会控制LED1的闪烁,并且周期性的率先LCD指定区域的背景颜色
动态创建

main函数代码:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"
#include "lcd.h"
#include "sdram.h"//任务优先级
#define START_TASK_PRIO     1
//任务堆栈大小
#define START_STK_SIZE      128
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);//任务优先级
#define TASK1_TASK_PRIO     2
//任务堆栈大小
#define TASK1_STK_SIZE      128
//任务句柄
TaskHandle_t Task1Task_Handler;
//任务函数
void task1_task(void *pvParameters);//任务优先级
#define TASK2_TASK_PRIO     3
//任务堆栈大小
#define TASK2_STK_SIZE      128
//任务句柄
TaskHandle_t Task2Task_Handler;
//任务函数
void task2_task(void *pvParameters);//LCD刷屏时使用的颜色
int lcd_discolor[14] = {WHITE ,BLACK,BLUE,BRED,GRED,GBLUE,RED,MAGENTA,GREEN,CYAN,YELLOW,BROWN,BRRED,GRAY};int main(void)
{HAL_Init();                     //初始化HAL库   Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhzdelay_init(180);                //初始化延时函数LED_Init();                      //LED初始化ACR_BYTE0_ADDRESSuart_init(115200);SDRAM_Init();LCD_Init();     POINT_COLOR = RED;LCD_ShowString(30,10,200,16,16,"Apolo STM32F4/F7");LCD_ShowString(30,30,200,16,16,"FreeeRTOS Examples");LCD_ShowString(30,50,200,16,16,"Task create and delete");LCD_ShowString(30,70,200,16,16,"2021/11/20");xTaskCreate(start_task,            //任务函数"start_task",          //任务名称START_STK_SIZE,        //任务堆栈大小NULL,                  //传递给任务函数的参数START_TASK_PRIO,       //任务优先级&StartTask_Handler);   //任务句柄          vTaskStartScheduler();      //开启任务调度}//开始任务任务函数
void start_task(void *pvParameters)
{taskENTER_CRITICAL();           //进入临界区//创建TASK1任务xTaskCreate(task1_task,             "task1_task",           TASK1_STK_SIZE,        NULL,                  TASK1_TASK_PRIO,        &Task1Task_Handler);   //创建TASK2任务xTaskCreate(task2_task,     "task2_task",   TASK2_STK_SIZE,NULL,TASK2_TASK_PRIO,&Task2Task_Handler); vTaskDelete(StartTask_Handler); //删除开始任务taskEXIT_CRITICAL();            //退出临界区
}
//task1任务函数
void task1_task(void *pvParameters)
{u8 task1_num=0;POINT_COLOR = BLACK;LCD_DrawRectangle(5,110,115,314);     //画一个矩形 LCD_DrawLine(5,130,115,130);        //画线POINT_COLOR = BLUE;LCD_ShowString(6,111,110,16,16,"Task1 Run:000");while(1){task1_num++;   //任务执1行次数加1 注意task1_num1加到255的时候会清零!!LED0=!LED0;//printf("任务1已经执行:%d次\r\n",task1_num);if(task1_num==5) {if(Task2Task_Handler != NULL)        //任务2是否存在?   {vTaskDelete(Task2Task_Handler);    //任务1执行5次删除任务2Task2Task_Handler=NULL;          //任务句柄清零//printf("任务1删除了任务2!\r\n");}}LCD_Fill(6,131,114,313,lcd_discolor[task1_num%14]); //填充区域LCD_ShowxNum(86,111,task1_num,3,16,0x80);  //显示任务执行次数vTaskDelay(1000);                           //延时1s,也就是1000个时钟节拍    }
}//task2任务函数
void task2_task(void *pvParameters)
{u8 task2_num=0;POINT_COLOR = BLACK;LCD_DrawRectangle(125,110,234,314); //画一个矩形   LCD_DrawLine(125,130,234,130);      //画线POINT_COLOR = BLUE;LCD_ShowString(126,111,110,16,16,"Task2 Run:000");while(1){task2_num++; //任务2执行次数加1 注意task1_num2加到255的时候会清零!!LED1=!LED1;//printf("任务2已经执行:%d次\r\n",task2_num);LCD_ShowxNum(206,111,task2_num,3,16,0x80);  //显示任务执行次数LCD_Fill(126,131,233,313,lcd_discolor[13-task2_num%14]); //填充区域vTaskDelay(1000);                           //延时1s,也就是1000个时钟节拍   }
}
静态创建

使用静态创建任务需要在FreeRTOSConfig.h将宏configSUPPORT_STATIC_ALLOCATION设置为1,配置完成之后还需要实现两个函数,vApplicationGetIdleTaskMemory和vApplicationGetTimerTaskMemory,通过这两个来给空闲任务和定时器服务任务的任务堆栈和任务控制块分配内存,这两个函数,我们在main.c里面定义:

//空闲任务任务堆栈
static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];
//空闲任务控制块
static StaticTask_t IdleTaskTCB;//定时器服务任务堆栈
static StackType_t TimerTaskStack[configTIMER_TASK_STACK_DEPTH];
//定时器服务任务控制块
static StaticTask_t TimerTaskTCB;
//获取空闲任务地任务堆栈和任务控制块内存,因为本例程使用的
//静态内存,因此空闲任务的任务堆栈和任务控制块的内存就应该
//有用户来提供,FreeRTOS提供了接口函数vApplicationGetIdleTaskMemory()
//实现此函数即可。
//ppxIdleTaskTCBBuffer:任务控制块内存
//ppxIdleTaskStackBuffer:任务堆栈内存
//pulIdleTaskStackSize:任务堆栈大小
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize)
{*ppxIdleTaskTCBBuffer=&IdleTaskTCB;*ppxIdleTaskStackBuffer=IdleTaskStack;*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;
}
//获取定时器服务任务的任务堆栈和任务控制块内存
//ppxTimerTaskTCBBuffer:任务控制块内存
//ppxTimerTaskStackBuffer:任务堆栈内存
//pulTimerTaskStackSize:任务堆栈大小
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize)
{*ppxTimerTaskTCBBuffer=&TimerTaskTCB;*ppxTimerTaskStackBuffer=TimerTaskStack;*pulTimerTaskStackSize=configTIMER_TASK_STACK_DEPTH;
}

main函数里面内容为:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"
#include "lcd.h"
#include "sdram.h"//空闲任务任务堆栈
static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];
//空闲任务控制块
static StaticTask_t IdleTaskTCB;//定时器服务任务堆栈
static StackType_t TimerTaskStack[configTIMER_TASK_STACK_DEPTH];
//定时器服务任务控制块
static StaticTask_t TimerTaskTCB;//任务优先级
#define START_TASK_PRIO     1
//任务堆栈大小
#define START_STK_SIZE      128
//任务堆栈
StackType_t StartTaskStack[START_STK_SIZE];
//任务控制块
StaticTask_t StartTaskTCB;
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);//任务优先级
#define TASK1_TASK_PRIO     2
//任务堆栈大小
#define TASK1_STK_SIZE      128
//任务堆栈
StackType_t Task1TaskStack[TASK1_STK_SIZE];
//任务控制块
StaticTask_t Task1TaskTCB;
//任务句柄
TaskHandle_t Task1Task_Handler;
//任务函数
void task1_task(void *pvParameters);//任务优先级
#define TASK2_TASK_PRIO     3
//任务堆栈大小
#define TASK2_STK_SIZE      128
//任务堆栈
StackType_t Task2TaskStack[TASK2_STK_SIZE];
//任务控制块
StaticTask_t Task2TaskTCB;
//任务句柄
TaskHandle_t Task2Task_Handler;
//任务函数
void task2_task(void *pvParameters);//获取空闲任务地任务堆栈和任务控制块内存,因为本例程使用的
//静态内存,因此空闲任务的任务堆栈和任务控制块的内存就应该
//有用户来提供,FreeRTOS提供了接口函数vApplicationGetIdleTaskMemory()
//实现此函数即可。
//ppxIdleTaskTCBBuffer:任务控制块内存
//ppxIdleTaskStackBuffer:任务堆栈内存
//pulIdleTaskStackSize:任务堆栈大小
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize)
{*ppxIdleTaskTCBBuffer=&IdleTaskTCB;*ppxIdleTaskStackBuffer=IdleTaskStack;*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;
}
//获取定时器服务任务的任务堆栈和任务控制块内存
//ppxTimerTaskTCBBuffer:任务控制块内存
//ppxTimerTaskStackBuffer:任务堆栈内存
//pulTimerTaskStackSize:任务堆栈大小
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize)
{*ppxTimerTaskTCBBuffer=&TimerTaskTCB;*ppxTimerTaskStackBuffer=TimerTaskStack;*pulTimerTaskStackSize=configTIMER_TASK_STACK_DEPTH;
}//LCD刷屏时使用的颜色
int lcd_discolor[14] = {WHITE ,BLACK,BLUE,BRED,GRED,GBLUE,RED,MAGENTA,GREEN,CYAN,YELLOW,BROWN,BRRED,GRAY};int main(void)
{HAL_Init();                     //初始化HAL库   Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhzdelay_init(180);                //初始化延时函数LED_Init();                      //LED初始化ACR_BYTE0_ADDRESSuart_init(115200);SDRAM_Init();LCD_Init();     POINT_COLOR = RED;LCD_ShowString(30,10,200,16,16,"Apolo STM32F4/F7");LCD_ShowString(30,30,200,16,16,"FreeeRTOS Examples");LCD_ShowString(30,50,200,16,16,"Task create and delete");LCD_ShowString(30,70,200,16,16,"2021/11/20");StartTask_Handler= xTaskCreateStatic(start_task,"start_task",START_STK_SIZE,NULL, START_TASK_PRIO,StartTaskStack,&Task1TaskTCB);    vTaskStartScheduler();      //开启任务调度}//开始任务任务函数
void start_task(void *pvParameters)
{taskENTER_CRITICAL();           //进入临界区//创建TASK1任务Task1Task_Handler=xTaskCreateStatic((TaskFunction_t )task1_task,        (const char*    )"task1_task",        (uint32_t       )TASK1_STK_SIZE,    (void*          )NULL,              (UBaseType_t    )TASK1_TASK_PRIO,   (StackType_t*   )Task1TaskStack,    (StaticTask_t*  )&Task1TaskTCB);       //创建TASK2任务Task2Task_Handler=xTaskCreateStatic(task2_task,     "task2_task",   TASK2_STK_SIZE,NULL,TASK2_TASK_PRIO,Task2TaskStack,&Task2TaskTCB); vTaskDelete(StartTask_Handler); //删除开始任务taskEXIT_CRITICAL();            //退出临界区
}
//task1任务函数
void task1_task(void *pvParameters)
{u8 task1_num=0;POINT_COLOR = BLACK;LCD_DrawRectangle(5,110,115,314);     //画一个矩形 LCD_DrawLine(5,130,115,130);        //画线POINT_COLOR = BLUE;LCD_ShowString(6,111,110,16,16,"Task1 Run:000");while(1){task1_num++;   //任务执1行次数加1 注意task1_num1加到255的时候会清零!!LED0=!LED0;//printf("任务1已经执行:%d次\r\n",task1_num);if(task1_num==5) {if(Task2Task_Handler != NULL)        //任务2是否存在?   {vTaskDelete(Task2Task_Handler);    //任务1执行5次删除任务2Task2Task_Handler=NULL;          //任务句柄清零//printf("任务1删除了任务2!\r\n");}}LCD_Fill(6,131,114,313,lcd_discolor[task1_num%14]); //填充区域LCD_ShowxNum(86,111,task1_num,3,16,0x80);  //显示任务执行次数vTaskDelay(1000);                           //延时1s,也就是1000个时钟节拍    }
}//task2任务函数
void task2_task(void *pvParameters)
{u8 task2_num=0;POINT_COLOR = BLACK;LCD_DrawRectangle(125,110,234,314); //画一个矩形   LCD_DrawLine(125,130,234,130);      //画线POINT_COLOR = BLUE;LCD_ShowString(126,111,110,16,16,"Task2 Run:000");while(1){task2_num++; //任务2执行次数加1 注意task1_num2加到255的时候会清零!!LED1=!LED1;//printf("任务2已经执行:%d次\r\n",task2_num);LCD_ShowxNum(206,111,task2_num,3,16,0x80);  //显示任务执行次数LCD_Fill(126,131,233,313,lcd_discolor[13-task2_num%14]); //填充区域vTaskDelay(1000);                           //延时1s,也就是1000个时钟节拍   }
}

编译即可

FreeRTOS任务创建和删除相关推荐

  1. 【STM32】FreeRTOS创建和删除任务示例(静态方法)(了解)

    00. 目录 文章目录 00. 目录 01. 概述 02. 功能描述 03. 任务设计 04. 程序设计 05. 结果验证 06. 附录 07. 参考 01. 概述 FreeRTOS中创建和删除任务A ...

  2. 【STM32】FreeRTOS创建和删除任务示例(动态方法)

    00. 目录 文章目录 00. 目录 01. 概述 02. 功能描述 03. 任务设计 04. 程序设计 05. 结果验证 06. 附录 07. 参考 01. 概述 FreeRTOS中创建和删除任务A ...

  3. 合肥工业大学—SQL Server数据库实验五:创建和删除索引

    创建和删除索引 1. 用SQL语句建立索引 2. 用SQL语句删除索引Stuspno 1. 用SQL语句建立索引 (1)应用场景:在教务管理系统中,经常需要通过学生的姓名查询学生的基本信息,学生人数大 ...

  4. 合肥工业大学—SQL Server数据库实验三:SQL语句创建和删除基本表

    SQL语句创建和删除基本表 1. 编写6个基本表 2. 修改基本表结构,完整性约束条件 3. 用Drop table 语句删除基本表 1. 编写6个基本表 设有简单教学管理的6个关系模式如下: 系(系 ...

  5. 合肥工业大学—SQL Server数据库实验一:数据库的创建和删除

    数据库的创建和删除 1. 创建数据库EDUC 2. 创建数据库TestDB 3. 删除数据库TestDB 4. 设置当前数据库为EDUC 1. 创建数据库EDUC 数据库名称:EDUC 数据库存储路径 ...

  6. SQL基础学习总结:2(表的创建、删除、更新和名称修改)

    表的创建.删除.更新和名称修改 登录MySQL(mysql -u root -p语句) 步骤: 1.首先得先使用mysql -u root -p语句登录数据库: 2.在"Enter pass ...

  7. 功能演示:戴尔PowerConnect 8024交换机VLAN的创建与删除

    戴尔PowerConnect 8024是一款带24个10 Gb以太网10GBASE-T端口的高密度10 Gb以太网交换机,专为具有高吞吐量和高可用性需求的数据中心.聚合和统一结构部署而设计. 这些高密 ...

  8. java 遍历file_JAVA File类(文件的遍历,创建,删除)

    File类构造函数 File f1=new File("H://asc//");//传入文件/目录的路径 File f2=new File(f1,"test.txt&qu ...

  9. WPF 中动态创建和删除控件

    WPF 中动态创建和删除控件 原文:WPF 中动态创建和删除控件 动态创建控件 1.容器控件.RegisterName("Name",要注册的控件)   //注册控件 2.容器控件 ...

最新文章

  1. 使用Combox控件的一个问题
  2. 在注意力中重新思考Softmax:分解非线性,这个线性transformer变体实现多项SOTA
  3. android 代码获取图片信息吗,Android 通过网络获取图片的代码
  4. python知乎-知乎大佬李启方道出肺腑之言:为什么我不建议你学Python?
  5. async function_掌握 Async/Await
  6. 用VisualVM和JConsole监控tomcat性能
  7. 移动端Web开发小记
  8. JSP调用request方法获取请求相关信息
  9. 程序员的进阶课-架构师之路(3)-线性表
  10. 用python画大白圣诞快乐呦
  11. 百度编辑器Ueditor 多图上传出现部分照片尺寸不压缩的问题解决
  12. 计算机中英文打字文章,中英文打字练习文章.docx
  13. 黑苹果HIDPI开启问题
  14. mysql主从配置修改重启无效
  15. 【老生谈算法】matlab实现Kmeans算法源码——Kmeans算法
  16. (XWZ)的Python学习笔记Ⅴ——I/O编程
  17. 评论:中国网络游戏虚拟物品交易的前景
  18. 取值范围的计算 以及为何16位int类型范围是- 32768 ~ 32767 8位类型取值范围为什么是-128~127
  19. 安装protobuf可能遇到的问题
  20. c语言 eval,分享:自己写的eval函数

热门文章

  1. css实现左(右)侧固定宽度,右(左)侧宽度自适应 ---清除浮动
  2. 小谈React、React Native、React Web
  3. 撸个微信小程序的省市区选择器
  4. react脚手架搭建项目目录介绍
  5. FFT实现高精度乘法
  6. js根据ip自动获取地址(省市区)
  7. html适配Anroid手机
  8. 关于 SENDKEYS 的代码
  9. c#a服务器上传文件b服务器,C#_c#批量上传图片到服务器示例分享,客户端代码: 复制代码 代码 - phpStudy...
  10. r 保留之前曲线_生存曲线居然能够批量绘制了