这篇文章在于 详细解释 FreeRTOS 中任务的创建过程,包括任务创建的本质过程、API 详解、两种创建方式(动态/静态)、任务函数规范、常见错误及实践建议。

这里参照:RTOS官方文档:https://www.freertos.org/zh-cn-cmn-s/Documentation/02-Kernel/04-API-references/01-Task-creation/01-xTaskCreate

FreeRTOS 的“任务”

在 FreeRTOS 中,每个任务(Task)就是一个可以独立运行的“线程”或“执行单元”,具有:

自己的函数入口(任务函数)
独立的堆栈空间
独立的上下文(CPU 寄存器、程序计数器)

FreeRTOS 通过任务调度器(Scheduler)来在这些任务之间切换执行权,实现 “多任务并发”。

创建任务的方式

动态创建任务(最常用)(上述官网链接)

xTaskCreate() 是 FreeRTOS 中最常用的任务创建函数,适合一般嵌入式系统中动态创建任务,使用时需合理配置堆大小和任务优先级,确保系统资源充足。

使用 API 函数:xTaskCreate()

BaseType_t xTaskCreate(TaskFunction_t pvTaskCode,const char * const pcName,const configSTACK_DEPTH_TYPE uxStackDepth,void *pvParameters,UBaseType_t uxPriority,TaskHandle_t *pxCreatedTask
);
参数说明:
pvTaskCode			任务入口函数(必须是 void func(void *pvParameters) 形式)
pcName				任务名(调试用途)
uxStackDepth		堆栈大小(单位是“字”,不是字节) STM32 上 1 word = 4 字节
pvParameters		创建任务时传入的参数指针
uxPriority			任务优先级(0 ~ configMAX_PRIORITIES - 1)
pxCreatedTask		任务句柄的地址(可为 NULL)返回值:
pdPASS:创建成功
errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY:内存不足,任务创建失败

由于官方文档里的链接内容过于理论化,不易理解,这里用大白话翻译一下:

xTaskCreate() 函数详解:

功能说明:
用于创建一个新的任务并将其加入到就绪列表中。
必须启用 FreeRTOSConfig.h 中的宏:

#define configSUPPORT_DYNAMIC_ALLOCATION 1

使用动态内存分配方式从 FreeRTOS 的堆中分配 任务堆栈任务控制块。

使用注意事项:
  1. 堆栈大小单位是“字”(word)
    • 在 Cortex-M3/M4 中,1 word = 4 字节
      所以 128 表示 512 字节堆栈空间
  2. 任务函数不能 return
    • 必须是一个无限循环 for(;;)while(1){}
    • 若任务要结束,需使用 vTaskDelete(NULL)
  3. pvParameters 传参要小心生命周期
    • 不要传局部变量地址
    • 可以传入静态变量或常量值
  4. 优先级不能超过 configMAX_PRIORITIES - 1
    • 否则调度器行为不确定
    • 建议使用 tskIDLE_PRIORITY + x 这种写法
完整的任务创建示例
/********************************************************************************* @file    Project/STM32F10x_StdPeriph_Template/main.c * @author  MCD Application Team* @version V3.5.0* @date    08-April-2011* @brief   Main program body******************************************************************************* @attention** THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.** <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>*******************************************************************************/  /* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h" 
#include <stdio.h>
#include "FreeRTOS.h"
#include "task.h"
#include "usart.h"	
#include "gpio.h"//------------------------- start_task --------------------------------------------//
void 			start_task(void *pvParameters);			//任务函数入口
TaskHandle_t StartTask_Handler;							//任务句柄	_任务身份证_每个任务都有独立的任务
#define 	START_STK_SIZE  64							//任务堆栈大小
#define 	START_TASK_PRO	1							//任务优先级
//-----------------------------------------------------------------------//在主函数中创建任务	
void Start()
{
//------------------------- start_task --------------------------------------------////初始化函数xTaskCreate((TaskFunction_t) 	start_task,							//任务函数入口(const char *	 )  "start_task",			//任务函数名称(uint16_t      ) 	START_STK_SIZE,			//任务堆栈大小(void *    	   )  NULL,						//任务参数入口(UBaseType_t 	 )  START_TASK_PRO,			//任务优先级(TaskHandle_t *) 	StartTask_Handler );    //任务句柄vTaskStartScheduler(); 	//开启任务调度器
}int main(void)
{NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );		//RTOS需要将中断优先级分组分配到第四组usart_init(115200);MX_GPIO_Init();printf("Create Task! \r\n");Start();while(1)		// 不会执行到这里{}}//任务函数(必须是无限循环)
void start_task(void *pvParameters) 			//任务函数入口
{printf("start Task Run! \r\n");while(1){GPIO_WriteBit(GPIOC, GPIO_Pin_7, Bit_RESET);  //绿灯闪烁vTaskDelay(500);GPIO_WriteBit(GPIOC, GPIO_Pin_7, Bit_SET); 	  //绿灯关闭vTaskDelay(500);vTaskDelay(10);}
}/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

FreeRTOS 中,任务是最基本的执行单元。你可以通过 xTaskCreate()xTaskCreateStatic() 创建任务,并通过调度器进行任务切换,从而实现多任务并发执行。任务函数必须是无限循环,并适当使用延时函数避免占用 CPU。


静态创建任务(更可控) (不详细介绍,较少使用)

使用 API 函数:xTaskCreateStatic()

TaskHandle_t xTaskCreateStatic(TaskFunction_t pvTaskCode,const char * const pcName,const uint32_t ulStackDepth,void *pvParameters,UBaseType_t uxPriority,StackType_t *puxStackBuffer,StaticTask_t *pxTaskBuffer
);

用户自己提供堆栈数组 + TCB 缓存
更适合内存受限嵌入式场景
不依赖 FreeRTOS 的堆(heap_4.c

动态 vs 静态任务创建对比:

项目动态创建 xTaskCreate静态创建 xTaskCreateStatic
内存分配使用 FreeRTOS 堆用户手动提供
灵活性稍低
控制性
适合场景一般应用内存受限、认证项目

最后,解释一下任务句柄的用途:任务句柄 类似于每个任务的身份证,每个任务都有独立的任务句柄标识。

创建任务时可以返回任务句柄(TaskHandle_t),用于:

  • 删除任务:vTaskDelete(xHandle);
  • 挂起任务:vTaskSuspend(xHandle);
  • 恢复任务:vTaskResume(xHandle);
  • 获取任务状态:eTaskGetState(xHandle);

以上,便是 FreeRTOS 任务的创建。

以上,欢迎有从事同行业的电子信息工程、互联网通信、嵌入式开发的朋友共同探讨与提问,我可以提供实战演示或模板库。希望内容能够对你产生帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/90368.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/90368.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/90368.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软考 系统架构设计师系列知识点之面向服务架构设计理论与实践(9)

接前一篇文章:软考 系统架构设计师系列知识点之面向服务架构设计理论与实践(8) 所属章节: 第15章. 面向服务架构设计理论与实践 第3节 SOA的参考架构 15.3 SOA的参考架构 IBM的Websphere业务集成参考架构(如图15-2所示,以下简称参考架构)是典型的以服务为中心的企业集…

分区域材料设计:主承重区 / 次承重区 / 足弓区的弹性参数与刺激强度匹配

你是否总在为足部酸痛、膝盖不适或腰背僵硬烦恼&#xff1f;穿了昂贵的缓震跑鞋&#xff0c;用了定制矫形器&#xff0c;问题却反复出现&#xff1f;今天&#xff0c;我们要颠覆一个流传百年的“常识”——脚不是脆弱的“需要被保护的对象”&#xff0c;而是被错误的设计“惯坏…

使用Qt下QAudioOutput播放声音

导读本项目目的是使用QAudioOutput播放声音 &#xff0c;音频数据来源为ffmpeg解码后的音频数据。Qt音频播放类说明 QAudioFormatQAudioFormat是Qt多媒体框架中用于定义音频格式的核心类&#xff0c;用于设置音频数据的参数&#xff0c;确保与硬件设备兼容。其主要功能和参数如…

日语学习-日语知识点小记-构建基础-JLPT-N3阶段(9):ようなN

日语学习-日语知识点小记-构建基础-JLPT-N3阶段&#xff08;9&#xff09;&#xff1a;ようなN 1、前言&#xff08;1&#xff09;情况说明&#xff08;2&#xff09;工程师的信仰2、知识点&#xff08;&#xff11;&#xff09;复习&#xff08;&#xff12;&#xff09;复习&…

洛谷P1512 伊甸园日历游戏

一开始&#xff0c;我发现有“必胜策略”&#xff0c;就知道是博弈论&#xff0c;然后看了两种操作&#xff08;月份1和天数1&#xff09;&#xff0c;于是想到用记忆化搜索找出所有的可能性 &#xff0c;但不知道怎么判断当前是否为先手必胜/必败态&#xff0c;使用了TJ方法后…

Kafka——消费者组到底是什么?

引言在分布式系统中&#xff0c;消息中间件的核心价值在于高效地连接生产者与消费者&#xff0c;实现数据的可靠传递。然而&#xff0c;传统消息引擎面临一个两难困境&#xff1a;如何在“消息不重复消费”与“系统可扩展性”之间找到平衡&#xff1f;点对点模型&#xff08;如…

新mac电脑软件安装指南(前端开发用)

1. 下载git 未下载git直接下载homebrew也会提示你下载git 2. 下载homebrew 介绍&#xff1a; Homebrew 是 macOS 和 Linux 系统的开源包管理器‌&#xff0c;通过命令行实现软件的快速安装、更新和管理&#xff0c;极大简化了开发者及普通用户的工作流程。 命令&#xff1a;…

【HarmonyOS】ArkUI 布局与容器组件

目录前言一、线性布局(Column/Row)1.先布局后内容2.元素在主轴上的排列方式3.元素在交叉轴上的排列方式二、层叠布局(Stack)1.开发布局2.对齐方式三、弹性布局(Flex)四、创建列表(List)五、创建轮播(Swiper)1.基本用法2.常用属性3.样式自定义六、选项卡Tabs1.基本用法2.常用属性…

MCNN-BiLSTM-Attention分类预测模型等!

MCNN-BiLSTM-Attention分类预测模型基于多尺度卷积神经网络(MCNN)双向长短期记忆网络(BiLSTM)注意力机制(Attention)的分类预测模型&#xff0c;matlab代码&#xff0c;直接运行使用&#xff01;1、模型介绍&#xff1a;针对传统方法在噪声环境下诊断精度低的问题&#xff0c;提…

【Luogu】每日一题——Day12. P3149 排序 (树状数组 + 逆序对)

链接&#xff1a;P3149 排序 - 洛谷 题目&#xff1a; 思路&#xff1a; 经典搭配了 首先我们来分析以下操作的作用&#xff0c;如果我们选了 a[k]&#xff0c;那么对逆序对有什么影响呢&#xff1f; ①.对于 x y&#xff0c;且 x > a[k]&#xff0c;y < a[k] 由于 x…

电商项目_秒杀_架构升级

1. 秒杀当前架构设计nginx节点和订单服务都可以方便的扩容&#xff08;增加机器&#xff09;redis扩容需则需要考虑架构设计当前架构面临的痛点&#xff1a;秒杀系统redis是单节点&#xff08;主从&#xff09;部署&#xff0c;读redis时并发量会成为瓶颈。所以考虑将增加redis…

CodeBuddy IDE发布:编程新时代的颠覆者?

开场&#xff1a;编程界的 “新风暴” 来袭 你能想象&#xff0c;不用敲一行代码就能开发软件吗&#xff1f;这个曾经只存在于科幻电影里的场景&#xff0c;如今已经成为现实&#xff01;就在最近&#xff0c;编程界迎来了一场 “新风暴”——CodeBuddy IDE 重磅发布&#xff…

深度分析Java类加载机制

Java 的类加载机制是其实现平台无关性、安全性和动态性的核心基石。它不仅仅是简单地将 .class 文件加载到内存中&#xff0c;而是一个精巧、可扩展、遵循特定规则的生命周期管理过程。以下是对其深度分析&#xff1a; 一、核心概念与生命周期 一个类型&#xff08;Class 或 In…

神经网络实战案例:用户情感分析模型

在当今数字化时代&#xff0c;用户评论和反馈成为企业了解产品满意度的重要渠道。本项目将通过神经网络构建一个情感分析模型&#xff0c;自动识别用户评论中的情感倾向。我们将使用真实的产品评论数据&#xff0c;从数据预处理到模型部署&#xff0c;完整展示神经网络在NLP领域…

now能减少mysql的压力吗

是否用数据库的 NOW() 能减少 MySQL 的压力&#xff1f;​答案是否定的——使用 NOW() 不仅不会降低压力&#xff0c;反而可能略微增加 MySQL 的负载。以下是详细分析&#xff1a;&#x1f50d; 性能对比&#xff1a;NOW() vs. Java 传参​指标​​Java 传参 (e.g., new Date()…

数据结构01:链表

数据结构 链表 链表和数组的区别 1. 存储方式 数组&#xff1a; 元素在内存中连续存储&#xff0c;占用一块连续的内存空间元素的地址可以通过索引计算&#xff08;基地址 索引 元素大小&#xff09;大小固定&#xff0c;在创建时需要指定容量 链表&#xff1a; 元素&#xf…

【Java学习|黑马笔记|Day21】IO流|缓冲流,转换流,序列化流,反序列化流,打印流,解压缩流,常用工具包相关用法及练习

标题【Java学习|黑马笔记|Day20】 今天看的是黑马程序员的《Java从入门到起飞》下部的95-118节&#xff0c;笔记包含IO流中的字节、字符缓冲流&#xff0c;转换流&#xff0c;序列化流反序列化流&#xff0c;打印流&#xff0c;解压缩流&#xff0c;常用工具包相关用法及练习 …

API网关原理与使用场景详解

一、API网关核心原理 1. 架构定位 #mermaid-svg-hpDCWfqoiLcVvTzq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-hpDCWfqoiLcVvTzq .error-icon{fill:#552222;}#mermaid-svg-hpDCWfqoiLcVvTzq .error-text{fill:#5…

OSPF路由协议——上

OSPF路由协议 RIP的不足 以跳数评估的路由并非最优路径如果RTA选择s0/0传输&#xff0c;传输需时会大大缩短为3s 最大跳数为16跳&#xff0c;导致网络尺度小RIP协议限制网络直径不能超过16跳&#xff0c;并且16跳为不可达。 收敛速度慢 RIP 定期路由更新 更新计时器&#xff1a…

(LeetCode 面试经典 150 题) 219. 存在重复元素 II (哈希表)

题目&#xff1a;219. 存在重复元素 II 思路&#xff1a;哈希表&#xff0c;时间复杂度0(n)。 哈希表记录每个数最新的下标&#xff0c;遇到符合要求的返回true即可。 C版本&#xff1a; class Solution { public:bool containsNearbyDuplicate(vector<int>& nums,…