freertos多任务

news2024/11/26 18:30:53

以前我们都是一个任务,假设现在我们创建三个任务,项目工程在上一节网盘

#include "stm32f10x.h"                  // Device header
#include "freertos.h"
#include "task.h"
#include "usart.h"

TaskHandle_t myTaskHandler1;
TaskHandle_t myTaskHandler2;
TaskHandle_t myTaskHandler3;


void myTask1( void * arg)
{
	while(1)
	{
		printf("myTask1 running\n");
		vTaskDelay(200);
	}

}


void myTask2( void * arg)
{
	while(1)
	{
		printf("myTask2 running\n");
		vTaskDelay(200);
	}

}


void myTask3( void * arg)
{
	while(1)
	{
		printf("myTask3 running\n");
		vTaskDelay(200);
	}

}


int main(void)
  {
	GPIO_InitTypeDef GPIO_Initstruct;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	GPIO_Initstruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Initstruct.GPIO_Pin = GPIO_Pin_13;
	GPIO_Initstruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_Initstruct);
	
	GPIO_ResetBits(GPIOC, GPIO_Pin_13);
	
	  
	USART_Config();
	  
	  
	xTaskCreate(myTask1, "myTask1", 128, NULL, 2, &myTaskHandler1); 
	xTaskCreate(myTask2, "myTask2", 128, NULL, 2, &myTaskHandler2); 
	xTaskCreate(myTask3, "myTask3", 128, NULL, 2, &myTaskHandler3); 
	  
	vTaskStartScheduler();
	
	while(1)
	{
		
	
	}

}

StaticTask_t	IdleTaskTCB;
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;

}

现象如下,这时会发现模拟串口仿真输出的是乱序的
在这里插入图片描述
出现多个线程竞争同一个输出函数,非线程安全,这样我们对临界区实现保护:

#include "stm32f10x.h"                  // Device header
#include "freertos.h"
#include "task.h"
#include "usart.h"

TaskHandle_t myTaskHandler1;
TaskHandle_t myTaskHandler2;
TaskHandle_t myTaskHandler3;


void myTask1( void * arg)
{
	while(1)
	{
		taskENTER_CRITICAL();
		printf("myTask1 running\n");
		taskEXIT_CRITICAL();
		vTaskDelay(200);
	}

}


void myTask2( void * arg)
{
	while(1)
	{
		taskENTER_CRITICAL();
		printf("myTask2 running\n");
		taskEXIT_CRITICAL();
		vTaskDelay(200);
	}

}


void myTask3( void * arg)
{
	while(1)
	{
		taskENTER_CRITICAL();
		printf("myTask3 running\n");
		taskEXIT_CRITICAL();
		vTaskDelay(200);
	}

}


int main(void)
  {
	GPIO_InitTypeDef GPIO_Initstruct;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	GPIO_Initstruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Initstruct.GPIO_Pin = GPIO_Pin_13;
	GPIO_Initstruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_Initstruct);
	
	GPIO_ResetBits(GPIOC, GPIO_Pin_13);
	
	  
	USART_Config();
	  
	  
	xTaskCreate(myTask1, "myTask1", 128, NULL, 2, &myTaskHandler1); 
	xTaskCreate(myTask2, "myTask2", 128, NULL, 2, &myTaskHandler2); 
	xTaskCreate(myTask3, "myTask3", 128, NULL, 2, &myTaskHandler3); 
	  
	vTaskStartScheduler();
	
	while(1)
	{
		
	
	}

}

StaticTask_t	IdleTaskTCB;
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;

}

在这里插入图片描述
然后我们试验一下删除任务在mytask1里实现:


void myTask1( void * arg)
{
	uint8_t i=0;
	while(1)
	{
		taskENTER_CRITICAL();
		printf("myTask1 running\n");
		taskEXIT_CRITICAL();
		vTaskDelay(200);
		i++;
		if(i==2){
			vTaskDelete(myTaskHandler2);
		}else if(i==3){
			vTaskDelete(NULL);
		}else if(i==4){
			vTaskDelete(myTaskHandler3);
		}
			
	}

}

现象如下
在这里插入图片描述
还有一种创建多任务的实现。使用开始任务创建其他任务,感觉为了好看规整点吧…

#include "stm32f10x.h"                  // Device header
#include "freertos.h"
#include "task.h"
#include "usart.h"

TaskHandle_t myTaskHandler1;
TaskHandle_t myTaskHandler2;
TaskHandle_t myTaskHandler3;
TaskHandle_t startTaskHandler;


void myTask1( void * arg)
{
	uint8_t i=0;
	while(1)
	{
		taskENTER_CRITICAL();
		printf("myTask1 running\n");
		taskEXIT_CRITICAL();
		i++;
		if(i==1){
			vTaskDelete(myTaskHandler3);
		}else if(i==2){
			vTaskDelete(NULL);
		}
		vTaskDelay(200);
			
	}

}


void myTask2( void * arg)
{
	while(1)
	{
		taskENTER_CRITICAL();
		printf("myTask2 running\n");
		taskEXIT_CRITICAL();
		vTaskDelay(200);
	}

}


void myTask3( void * arg)
{
	while(1)
	{
		taskENTER_CRITICAL();
		printf("myTask3 running\n");
		taskEXIT_CRITICAL();
		vTaskDelay(200);
	}

}

void startTask(void* arg){
	taskENTER_CRITICAL();
	printf("start running\n");
	taskEXIT_CRITICAL();
	xTaskCreate(myTask1, "myTask1", 128, NULL, 2, &myTaskHandler1); 
	xTaskCreate(myTask2, "myTask2", 128, NULL, 2, &myTaskHandler2); 
	xTaskCreate(myTask3, "myTask3", 128, NULL, 2, &myTaskHandler3); 
	vTaskDelete(NULL);
}
int main(void)
  {
	GPIO_InitTypeDef GPIO_Initstruct;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	GPIO_Initstruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Initstruct.GPIO_Pin = GPIO_Pin_13;
	GPIO_Initstruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_Initstruct);
	
	GPIO_ResetBits(GPIOC, GPIO_Pin_13);
	
	  
	USART_Config();
	  
	  
	
	xTaskCreate(startTask,"startTask",128,NULL,2,&startTaskHandler);
	vTaskStartScheduler();
	
	while(1)
	{
		
	
	}

}

StaticTask_t	IdleTaskTCB;
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;

}

不过这样创建的任务在相同优先级下会按照创建的顺序执行

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

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

相关文章

什么是商业?什么是企业?什么又是竞争呢?

博主从商了,读了一些关于商业企业跟竞争的关系的书跟文章,突然就有点感受想分享一下,请诸位佬讨论一下,听取一下各位佬的意见,学习一下各位的宝贵经验。 百度百科是这样解释商业企业跟竞争的 商业是以买卖方式使商品流…

Java中的垃圾回收机制

Java中的垃圾回收机制 一、Java垃圾回收机制面试题二、哪些对象应该被回收三、什么时候进行垃圾回收四、怎么清除垃圾对象4.1 标记-清除算法4.2 复制算法4.3 整理算法4.4 分代收集算法(主流)4.4.1 新生代4.4.2 老年代4.4.3 永久代 五、垃圾收集器六、注意…

zotero跨Windows设备数据同步(利用OneDrive、百度云同步空间等云服务)

zotero跨Windows设备数据同步(利用OneDrive、百度云同步空间等云服务) 特别注意 不能在多个设备同步使用zotero,否则会导致同步出现异常。 基本原理 同步zotero的数据,即同步全部的文献和笔记、高亮标记信息。而这两类数据分别…

JPCC:燃料电池中用于高效氧还原阴极的拓扑铋(1ī0)面

质子交换膜燃料电池的性能在很大程度上取决于电化学氧还原反应(ORR)的效率。在这里,宾夕法尼亚大学Andrew M. Rappe等人报道了二维(4单层,ML)和三维Bi(16ML)(1ī0&#x…

从零开始搭建React+TypeScript+webpack开发环境-使用iconfont构建图标库

创建iconfont项目 进入iconfont官网,完成注册流程,即可创建项目。 无法访问iconfont可尝试将电脑dns改为阿里云镜像223.5.5.5和223.6.6.6 添加图标 在图标库里选择图标,加入购物车 将图标添加到之前创建的项目中 生成代码 将代码配置到项目…

noip模拟赛多校第八场 T3 遥控机器人 (最短路 + 技巧拆点)

题面 简要题意: 给你一个 n n n 个点 m m m 条边的图。边 i i i 有颜色 c i c_i ci​。你可以选择一些边改变它们的颜色成为区间 [ 1 , m ] [1, m] [1,m] 中的任意颜色,改变一条边 i i i 一次的代价是 w i w_i wi​。询问你能否在一些改变…

使用SSH ,让windows和linux互通

简介 SSH 是一种安全网络协议,旨在让客户端和服务器之间进行安全的数据传输。SSH 的核心思想是利用公钥加密技术和共享密钥加密技术相结合的方式,使客户端和服务器之间建立起安全的连接。 当客户端发起连接请求时,服务器会对客户端进行身份验…

python的format函数的用法及实例

目录 1.format函数的语法及用法 (1)语法:{}.format() (2)用法:用于格式化字符串。可以接受无限个参数,可以指定顺序。返回结果为字符串。 2.实例 (1)不设置位置&…

RK3568平台开发系列讲解(音视频篇)RTMP 推流

🚀返回专栏总目录 文章目录 一、RTMP 的工作原理二、RTMP 流媒体服务框架2.1、Nginx 流媒体服务器2.2、FFmpeg 推流沉淀、分享、成长,让自己和他人都能有所收获!😄 📢目前常见的视频监控和视频直播都是使用了 RTMP、RTSP、HLS、MPEG-DASH、 WebRTC流媒体传输协议等。 R…

学习Opencv(蝴蝶书/C++)相关——2.用clang++或g++命令行编译程序

文章目录 1. c/cpp程序的执行1.1 cpp程序的编译过程1.2 预处理指令1.3 编译过程的细节2. macOS下使用Clang看cpp程序的编译过程2.1 示例2.1.1 第一步 预处理器-preprocessor2.1.2 第二步 编译器-compiler2.1.3 第三步 汇编器-assembler2.1.4 第四步 链接器-linker2.1.5 链接其他…

git commit规范提交

Git每次提交代码时,都要写Commit Message(提交说明),通常情况下,Commit Message应该清晰明了,说明本次提交的目的和具体操作等。然而笔者工作多年来发现,有些公司对Commit Message没有明确的要求…

10 索引优化与查询优化

文章目录 索引失效案例关联查询优化对于左外连接对于内连接JOIN语句原理简单嵌套循环连接SNLJ索引嵌套循环连接INLJ块嵌套循环连接BNLJHash Join 子查询优化排序优化filesort算法:双路排序和单路排序 分组优化分页优化优先考虑覆盖索引索引下推ICP使用条件 其他查询…

[移动通讯]【Carrier Aggregation-13】【Carrier Aggregation】

前言: 前面分享过不同note CA 技术文档 这里主要参考 4G|ShareTechnote 《Carrier Aggregation》 CA SCell 添加的小区的流程: SCell addition and removal: 1 The carrier aggregation additional SCells cannot be activated immediately…

Firefox 119 正式发布

Firefox 119 已正式发布。新版本除了修复 Bug 之外,还增强了 Firefox View 功能、支持在 PDF 文档中插入图片,以及引入 Encrypted Client Hello (ECH) 以增强隐私保护等。 主要变化 改进 Firefox View:用户可以在该页面查看所有窗口打开的标…

uniapp 微信小程序 uni-file-picker上传图片报错 chooseAndUploadFile

这个问题真的很搞, 原因是微信开发者工具更新了,导致图片上传问题。 解决方法: 将微信开发者工具的基础库改为2.33.0一下即可。 在微信开发者工具详情 - 本地设置中(记得点击‘推送’按钮):

20.8 OpenSSL 套接字SSL传输文件

有了上面的基础那么传输文件的实现就变得简单了,在传输时通常我们需要打开文件,并每次读入1024个字节的数据包,通过SSL加密传输即可,此处的文件传输功能在原生套接字章节中也进行过详细讲解,此处我们还是使用原来的密钥…

Spark 基础知识点

Spark 基础 本文来自 B站 黑马程序员 - Spark教程 :原地址 什么是Spark 什么是Spark 1.1 定义:Apache Spark是用于大规模数据(large-scala data)处理的统一(unified)分析引擎 Spark最早源于一篇论文 Re…

Linux 学习(CentOS 7)

CentOS 7 学习 Linux系统内核作者: Linux内核版本 内核(kernel)是系统的心脏,是运行程序和管理像磁盘和打印机等硬件设备的核心程序,它提供了一个在裸设备与应用程序间的抽象层。 Linux内核版本又分为稳定版和开发版,两种版本是相互关联&am…

深度优先遍历与连通分量

深度优先遍历(Depth First Search)的主要思想是首先以一个未被访问过的顶点作为起始顶点,沿当前顶点的边走到未访问过的顶点。当没有未访问过的顶点时,则回到上一个顶点,继续试探别的顶点,直至所有的顶点都被访问过。 下图示例的…

设置Linux时间格式

一、事因 不知道什么时候我在输入ls -l 命令时候的显示变成了。 -rw-r--r-- 1 bossftp ftp 6796376499 915 05:31 rac_full_20230915.gz -rw-r--r-- 1 bossftp ftp 6804104515 104 05:25 rac_full_20231024.gz -rw-r--r-- 1 bossftp ftp 6804365525 105 05:29 rac_full_202…