FreeRTOS 创建任务

news2024/9/26 9:40:40

例子:创建一个任务,并在任务里面翻转LED 灯

在这里插入图片描述

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 ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */

“ lint !e971 Unqualified char types are allowed for strings and single characters only” 告诉编译器在编译的时候不要报警告,这里把char类型和字符串类型混用了,编译器你不要报警告

1.1 参数1: pxTaskCode,创建的任务函数名,类似中断服务服务函数入口,函数的入口地址

1.2 参数2:pcName,也是创建的任务函数名称,只不过这个是没有实际意义的,只是方便记住创建的函数叫什么名字,FreeRTOS不会调用这个东东的,名称可随意写,长度有限制, configMAX_TASK_NAME_LEN 定义了名称的长度,包括 \0 字符,超过会自动截断

FreeRTOSConfig.h

#define configMAX_TASK_NAME_LEN    (16)

1.3 参数3:usStackDepth,栈大小,每创建一个任务,系统就会为该任务分配一块内存(堆栈),单位是字(word),而不是字节(Byte),在32位机中 (STM32xx), 1 word = 4Byte,分配的空间就是stackSize = usStackDepth * 4,默认最小栈大小 configMINIMAL_STACK_SIZE

FreeRTOSConfig.h

#define configMINIMAL_STACK_SIZE    ((unsigned short)130)

具体大小需要自己调试

1.4 pvParameters,创建的任务的实参,创建任务的时候,给他传进来的参数,万能指针 void *

1.5 uxPriority,任务的优先级

FreeRTOSConfig.h

#define configMAX_PRIORITIES    (32)

优先级必须比这个宏要小,数字越小,优先级越高
configMAX_PRIORITIES 宏大小可随意,但最好使用实际需要的最小数值以避免内存浪费
如果优先级设置的比configMAX_PRIORITIES 大,会将优先级自动设置为最大优先级configMAX_PRIORITIES

1.6 pxCreatedTask 创建的任务的句柄,跟第一个参数类似,操作这个句柄就相当于操作这个任务,可以通过句柄改变任务的优先级、删除任务等,如果不需要使用句柄,就设为NULL

1.7 返回值

1.7.1 pdPASS,创建任务成功

1.7.2 errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY, 内存堆空间不够,创建任务失败,也有可能是堆内存碎片化导致创建失败

2. 创建任务

// create task2
void vTask2( void *pvParameters ) 
{ 
	// each task must be a endless loop
	for( ;; ) 
	{	 
		printf("task2 say: hello world");
	} 
}

// create task1
void vTask1( void *pvParameters ) 
{ 
	// each task must be a endless loop, otherwise, the program will crash
	for (;;) 
	{ 
		printf("task1 say: hello world1");
	} 
} 

int main( void ) 
{ 
	// create task1
	xTaskCreate(vTask1, // create task1
			    "Task 1", // task name
				128, // stack size
				NULL, // the task has no parameter
				1, // task priority
				NULL ); // task handle 

	// creat task2
	xTaskCreate(vTask2, // create task2
	            "Task 2", // task name
	            128, // stack size
	            NULL,// the task has no parameter
	            2, // task priority, the task priority can not be same as other task priority
	            NULL ); 

	// The system start to scheduler
	vTaskStartScheduler(); 
	// the program will not run  here if there are no issues with the program, but if executed here, it is likely the memory heap space is insufficient resulting in idle
	for (;;)
	{
	}
}

3. 两个任务按照时间片轮转方式运行,系统调度,轮流来,一人一口饭,你一口,我一口

在这里插入图片描述

3. 在任务里面创建任务,创建任务1,然后在任务1 里面创建任务2

// create task2
void vTask2( void *pvParameters ) 
{ 
	// each task must be a endless loop
	for( ;; ) 
	{	 
		printf("task2 say: hello world");
	} 
}

// create task1
void vTask1( void *pvParameters ) 
{ 
	// creat task2
	xTaskCreate(vTask2, // create task2
	            "Task 2", // task name
	            128, // stack size
	            NULL,// the task has no parameter
	            2, // task priority, the task priority can not be same as other task priority
	            NULL ); 
	// each task must be a endless loop, otherwise, the program will crash
	for (;;) 
	{ 
		printf("task1 say: hello world1");
	} 
} 

int main( void ) 
{ 
	// create task1
	xTaskCreate(vTask1, // create task1
			    "Task 1", // task name
				128, // stack size
				NULL, // the task has no parameter
				1, // task priority
				NULL ); // task handle 
	
	// The system start to scheduler
	vTaskStartScheduler(); 
	// the program will not run  here if there are no issues with the program, but if executed here, it is likely the memory heap space is insufficient resulting in idle
	for (;;)
	{
	}
}

4. 使用任务参数,创建任务的同时传递一个参数进任务里面 vTaskFunction

// create task2
void vTask2(void *pvParameters) 
{ 
	char *pcTaskName;
	
	// (void *) forced conversion to string (char *)
	pcTaskName = (char *)pvParameters;
	
	// each task must be a endless loop
	for( ;; ) 
	{	 
		printf("task2, %s", pcTaskName );
	} 
}

// create task1
void vTask1( void *pvParameters ) 
{ 
	char *pcTaskName;
	
	pcTaskName = (char *)pvParameters;
	
	// each task must be a endless loop, otherwise, the program will crash
	for (;;) 
	{ 
		printf("task1, %s", pcTaskName );
	} 
} 

int main( void ) 
{ 
	// create task1
	xTaskCreate(vTaskFunction, // create task1
			    "Task 1", // task name
				128, // stack size
				“hello world”, // pass parameters to task1
				1, // task priority
				NULL); // task handle 

	// creat task2
	xTaskCreate(vTaskFunction, // create task2
	            "Task 2", // task name
	            128, // stack size
	            “hello world”, // pass parameters to task2
	            2, // task priority, the task priority can not be same as other task priority
	            NULL); 

	// The system start to scheduler
	vTaskStartScheduler(); 
	// the program will not run  here if there are no issues with the program, but if executed here, it is likely the memory heap space is insufficient resulting in idle
	for (;;)
	{
	}
}

与上面的第 2 步类似,只是在创建任务的同时传了一个字符串进任务里面了,然后在任务里面接收这个字符串,并打印出来
看起来写了一堆,很复杂,其实很简单,就一个函数调用,会使用就行了,调用函数的时候知道每个参数怎么填,怎么根据返回值判断创建结果就可以了

5. 在main 函数里面创建第一个任务

在这里插入图片描述

6. 在任务里面创建任务,理论上可以创建无数个,具体看系统,用的哪个操作系统,用的什么硬件平台,硬件资源够不够,内存够不够等等

在这里插入图片描述

7. 在任务的死循环里面执行任务操作,这个任务需要干些啥事都放在死循环里面写,死循环里面执行任务需要干的事,死循环前面基本都是一些初始化操作,STM32xx

在这里插入图片描述

8. 在死循环里面翻转LED灯,执行一遍该任务,LED1就会翻转一次,亮到灭到亮,反复亮灭

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32的定时器详解(嵌入式学习)

STM32的定时器详解 0. 前言1. Systick定时器概念工作原理时钟基准Systick练习 2. HAL_Delay函数分析3. 定时器基本概念定时器分类定时器组成计数器自动重装寄存器预分频器 定时器计数原理定时器练习 4. 软件定时器概念设计思想代码 0. 前言 想要了解STM32的时钟系统 点击这里跳…

【数据分享】1929-2022年全球站点的逐日平均风速数据(Shp\Excel\12000个站点)

气象数据是在各项研究中都经常使用的数据,气象指标包括气温、风速、降水、能见度等指标,说到气象数据,最详细的气象数据是具体到气象监测站点的数据! 对于具体到监测站点的气象数据,之前我们分享过1929-2022年全球气象…

考上了!成为图技术大师的第一步!

好消息!! 自创邻科技GBCA课程开设以来 截至6月20日 已有近20名学员通过考试 获得GBCA认证证书! 距离成为图技术认证专家 跨出关键一步! 前不久,创邻科技为了让更多图技术爱好者能够快速了解、上手图数据库&#xff0c…

【一些随笔】艰难存折,恨不睡觉:大话年轻人的钱包囧境与梦想退休

一些随笔 1️⃣ 存钱难吗?难!它难在哪?2️⃣ 关于年轻人如何攒钱理财的一点建议3️⃣ 关于裸辞的一些经验及看法4️⃣ 谁又不想攒够钱了提前退休呢?但要存够多少呢? 1️⃣ 存钱难吗?难!它难在哪…

【HISI IC萌新虚拟项目】ppu模块基于spyglass的lint清理环境搭建与lint清理

关于整个虚拟项目,请参考: 【HISI IC萌新虚拟项目】Package Process Unit项目全流程目录_尼德兰的喵的博客-CSDN博客 前言 RTL代码在交付给验证同时进行功能验证时,可以同步进行lint的清理工作。一般而言影响编译和仿真的问题会在vcs的error和warning中被修正,因此清理lin…

[RocketMQ] Broker启动流程源码解析 (二)

文章目录 1.Brocker介绍2.BrokerStartup启动入口3.createBrokerController创建BrokerController3.1 创建各种配置类3.2 创建broker控制器3.3 初始化broker控制器3.3.1 加载配置文件3.3.2 创建消息存储对象MessageStore3.3.3 Load加载恢复消息文件3.3.4 初始化Broker通信层3.3.5…

知道了,去卷后端 →「Nest.js 入门及实践」:)

为什么学习 Nest ? 前端已 🙈,去卷后端 🐒 → 广度和深度的问题,不可代替性仅前端开发的应用没有记忆,不能互联 🤔 → 学习后端,为应用赋能同为 JS 语言,学习成本较小&a…

EALLOW和EDIS指令的使用

1.EALLOW与EDIS 汇编指令 #define EALLOW __asm("EALLOW") #define EDIS __asm("EDIS") #define ESTOP0 __asm("ESTOP0")EALLOW(Edit allow):防止cpu错误地写保护,ST1状态寄存器的EALLOW位显示是否允许写,0…

手机蓝牙功能测试点大全,都帮你总结好了

蓝牙是现在智能设备上一个必不可少的模块,支持大容量的近距离无线通信,典型的传输距离是10米左右,通过增加发射功率可达到100米,支持多链接,安全性高。 蓝牙工作在2.4GHZ的 ISM频段上,采用跳频扩谱技术避免…

微信小程序开发公司,小程序接单

小程序开发接单,公司开发,售后有保障,专属售后群对接,1对1 服务,下面是一些常见的小程序,全行业小程序都可开发 1.商城小程序 商城小程序是一种集购物、支付、订单管理等多种功能于一体的应用程序。为了使…

【使用OpenFeign在微服务中进行服务间通信】—— 每天一点小知识

💧 使用 O p e n F e i g n 在微服务中进行服务间通信 \color{#FF1493}{使用OpenFeign在微服务中进行服务间通信} 使用OpenFeign在微服务中进行服务间通信💧 🌷 仰望天空,妳我亦是行人.✨ 🦄 个人主页——微…

Python | cx_Oracle | DPI-1047报错处理(Win\Mac\Linux)

文章目录 Python | cx_Oracle | DPI-1047报错处理(Win\Mac\Linux)测试代码报错信息解决步骤 Python | cx_Oracle | DPI-1047报错处理(Win\Mac\Linux) 测试代码 import cx_Oracle# 建立与 Oracle 数据库的连接 connection cx_Oracle.connect("{lo…

【Redux】redux的使用详解

Redux的使用详解 Redux的核心思想 理解纯函数 1. 为什么要使用redux JavaScript开发的应用程序,已经变得越来越复杂了: JavaScript需要 管理的状态越来越多,越来越复杂;这些状态包括:服务器返回的数据、缓存数据、用户…

精细运营、数据赋能、生态联动…银行大零售数字化转型攻略

当前我国银行业的内外部环境正在发生深刻的变化,数字化转型已经成为行业的普遍共识。尤其在银行大零售数字化转型的过程中,各家银行差异性较大,虽然都开始突破传统零售模式,但仍面临一些共性的挑战,比如缺乏科学的顶层…

Java设计模式——装饰者模式

装饰者模式 一、概述 装饰者模式(装饰器模式)是一种结构型模式 定义: 在不改变现有对象结构的情况下,动态地给该对象增加一些额外职责(功能)的模式。 装饰者(Decorator)模式中的…

8年测试老鸟整理,接口自动化测试mock总结,这些你会多少?

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 Mock原理/实现机制…

【youcans动手学模型】MobileNet 模型-CIFAR10图像分类

欢迎关注『youcans动手学模型』系列 本专栏内容和资源同步到 GitHub/youcans 【youcans动手学模型】MobileNet 模型-CIFAR10图像分类 1. MobileNet 卷积神经网络模型1.1 模型简介1.2 论文介绍 2. 在 PyTorch 中定义 MobileNet V1 模型类2.1 深度可分离卷积(DSC&…

前端vue入门(纯代码)11

【11.全局事件总线(Global Event Bus)】 全局事件总线:实现任意组件间通信 【原理图】 结合上图,假若C组件想要传递数据给A组件,那么,就通过全局事件总线在A组件中绑定【$on】一个自定义事件demo,并界定一个参数来接…

如果我们20年后仍然在讨论Kubernetes,那将是技术上悲哀的时刻

这里是weihubeats,觉得文章不错可以关注公众号小奏技术,文章首发。拒绝营销号,拒绝标题党 Kelsey Hightower Google Cloud首席开发者 引子 在 Kubecon 上,Kelsey Hightower 曾经遇到过一个带有 Kubernetes 纹身的人,这让他开始…

工业相机的镜头如何选择?

相机的镜头如何计算,如果看公式的话,需要知道相机sensor的尺寸,相元的尺寸,计算起来数据也比较复杂,下面教大家一个简单的方法,就是如何借助镜头计算工具来使用。 巴斯勒相机的镜头选型地址 工业镜头选型…