• STM32H750之FreeRTOS学习--------(二)任务的创建和删除


    FreeRTOS

    二、任务的创建和删除

    任务创建

    动态方式创建任务
    BaseType_t xTaskCreate
    ( 
        TaskFunction_t 					pxTaskCode,		/* 指向任务函数的指针 */					
        const char * const 				pcName, 		/* 任务名字,最大长度configMAX_TASK_NAME_LEN */
    	const 	configSTACK_DEPTH_TYPE 	usStackDepth, 	/* 任务堆栈大小,注意字为单位 */
    	void * const 					pvParameters,	/* 传递给任务函数的参数 */
    	UBaseType_t 					uxPriority,		/* 任务优先级,范围:0 ~ configMAX_PRIORITIES - 1 */
    	TaskHandle_t * const 			pxCreatedTask 	/* 任务句柄,就是任务的任务控制块 */
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    返回值

    • pdPASS 任务创建成功
    • errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY 任务创建失败

    创建流程

    1. 将宏configSUPPORT_DYNAMIC_ALLOCATION 配置为 1
    2. 定义函数入口参数
    3. 编写任务函数
    • 函数创建任务后会立刻进入就绪态、后由任务调度器运行下面步骤
    1. 申请堆栈内存&任务控制块内存
    2. TCB结构体成员赋值
    3. 添加新任务到就绪列表中

    任务控制块结构体

    typedef struct tskTaskControlBlock       
    {
        	volatile StackType_t 		* pxTopOfStack; 		/* 任务栈栈顶,必须为TCB的第一个成员*/
       		ListItem_t 			xStateListItem;           		/* 任务状态列表项 */      
    		ListItem_t 			xEventListItem;					/* 任务事件列表项 */     
        	UBaseType_t 			uxPriority;                	/* 任务优先级,数值越大,优先级越大 */
        	StackType_t 			* pxStack;					/* 任务栈起始地址 */
        	char 				pcTaskName[ configMAX_TASK_NAME_LEN ]; 	/* 任务名字 */		
    	…
    	省略很多条件编译的成员
    } tskTCB;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    静态创建任务
    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	/* 任务控制块指针,由用户分配 */
    ); 	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    返回值

    • NULL 用户没有提供相应的内存,任务创建失败

    • 其他值 任务句柄,任务创建成功

    创建流程

    1. 需将宏configSUPPORT_STATIC_ALLOCATION 配置为 1
    2. 定义空闲任务&定时器任务的任务堆栈及TCB
    3. 实现两个接口函数 vApplicationGetIdleTaskMemory( ) vApplicationGetTimerTaskMemory ( )
    4. 定义函数入口参数
    5. 编写任务函数
    • 函数创建的任务会立刻进入就绪态,由任务调度器调度运行
    1. TCB结构体成员赋值
    2. 添加新任务到就绪列表中

    在FreeRTOS中,vApplicationGetIdleTaskMemory()vApplicationGetTimerTaskMemory()是两个与静态内存分配相关的函数。

    1. vApplicationGetIdleTaskMemory(): 此函数在静态内存分配(configSUPPORT_STATIC_ALLOCATION设置为1)的情况下被调用,用于为闲置任务提供内存。在静态内存分配模式下,闲置任务将以静态方式分配,开发者需要使用vApplicationGetIdleTaskMemory()函数为其提供内存。函数原型如下:

      void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, ... );
      
      • 1

      其中,ppxIdleTaskTCBBuffer参数是一个指向闲置任务的任务控制块(TCB)的指针的指针

    2. vApplicationGetTimerTaskMemory(): 类似地,此函数在静态内存分配模式下被调用,用于为定时器服务任务提供内存。函数原型如下:

      void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize );
      
      • 1

      其中,ppxTimerTaskTCBBuffer参数是一个指向定时器任务的任务控制块(TCB)的指针的指针,ppxTimerTaskStackBuffer是一个指向定时器任务堆栈的指针的指针,而pulTimerTaskStackSize是一个指向定时器任务堆栈大小的指针

    这两个函数是在使用静态内存分配时由FreeRTOS调用,而非由用户直接调用,但用户需要为这两个函数提供实现,以分配适当的内存给闲置任务和定时器服务任务。在实际应用中,configTIMER_TASK_STACK_DEPTH常量由应用程序编写者提供,不是内核实现的一部分,不同的示例可能会使用不同的类型,因为不同的架构可能具有不同的字长。示例应用程序不是内核实现的一部分,所以如果在示例应用程序或实际代码中的定义不正确,可以在FreeRTOSConfig.h文件中进行编辑,而不必更改内核实现5.

    任务删除

    删除任务
    void vTaskDelete(TaskHandle_t xTaskToDelete);
    
    • 1
    • xTaskToDelete 待删除任务的任务句柄

    用于删除已被创建的任务

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

    • 当传入的参数为NULL,则代表删除任务自身(当前正在运行的任务)
    • 空闲任务会负责释放被删除任务中由系统分配的内存,但是由用户在任务删除前申请的内存, 则需要由用户在任务被删除前提前释放,否则将导致内存泄露

    删除任务流程

    1. 使用删除任务函数,需将宏INCLUDE_vTaskDelete 配置为 1
    2. 入口参数输入需要删除的任务句柄(NULL代表删除本身)
    • 删除任务函数内部
    1. 获取所要删除任务的控制块
    2. 将被删除任务,移除所在列表
    3. 判断所需要删除的任务
      在任务被删除前提前释放,否则将导致内存泄露

    删除任务流程

    1. 使用删除任务函数,需将宏INCLUDE_vTaskDelete 配置为 1
    2. 入口参数输入需要删除的任务句柄(NULL代表删除本身)
    • 删除任务函数内部
    1. 获取所要删除任务的控制块
    2. 将被删除任务,移除所在列表
    3. 判断所需要删除的任务
    4. 更新下个任务的阻塞时间
  • 相关阅读:
    QLineEdit 类(行编辑器)
    day33-线程基础03
    Microsoft Visual Studio—常用快捷键
    【甄选靶场】Vulnhub百个项目渗透——项目十三:SickOs 1.2(防火墙绕过,计划任务写入)
    暴力递归转动态规划(九)
    科层制是单向流动,违背DevOps三步法,是浪费和低效的根源
    【配置环境】SQLite数据库安装和编译以及VS下C++访问SQLite数据库
    Pytorch D2L Subplots方法对画图、图片处理
    HTTP 协议的定义,工作原理,Fiddler的原理和使用,请求的内容
    【前后缀 + 推公式整理】 Codeforces Round #813 (Div. 2) D. Empty Graph
  • 原文地址:https://blog.csdn.net/Johnor/article/details/134084710