freertos多任务

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

#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.hqwc.cn/news/162614.html

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

相关文章

Codeforces Round 906 (Div. 2--ABC)

A.Doremys Paint 3 题目 一个元素全为整数的数组,如果满足相邻两个元素和相同,我们就认定此数组is good。给定一个长度为n的数组a,可以任意改变元素顺序,判定数组a是否is good。 输入 首行t测试数据数量, 每组数据…

新一代构建工具Vite-xyphf

一、什么vite? vite:是一款思维比较前卫而且先进的构建工具,他解决了一些webpack解决不了的问题——在开发环境下可以实现按需编译,加快了开发速度。而在生产环境下,它使用Rollup进行打包,提供更好的tree-shaking、代码压缩和性能优化&…

【GEE】基于GEE-Landsat8数据集地表温度反演(LST热度计算)

老样子,最近在做生态方面的项目,然后需要分析城市的热岛效应,想了想还是用GEE计算比较简单,直接下载影像太麻烦了。所以在网上看看了资料,踩了踩坑终于是将代码写出来了。秉承着取之于民、用之于民的想法,今…

windows10编译高版本openssl

参考文章 参考文章中的windows编译为低版本,在高版本的openssl编译中已经没有:“ms\do_ms.bat”这个脚本了,现记录下编译过程 1、准备工作 安装ActivePerl,安装后会自动写入环境变量,参照参考文章测试安装成功与否&a…

【监控指标】监控系统-prometheus、grafana。容器化部署。go语言 gin框架、gRPC框架的集成

文章目录 一、监控有哪些指标二、prometheus、grafana架构Prometheus 组件Grafana 组件架构优点 三、安装prometheus和node-exporter1. docker pull镜像2. 启动node-exporter3. 启动prometheus 四、promql基本语法五、grafana的安装和使用1. 新建空文件夹grafana-storage&#…

mediasoup webrtc音视频会议搭建

环境ubuntu22.10 nvm --version 0.33.11 node -v v16.20.2 npm -v 8.19.4 node-gyp -v v10.0.1 python3 --version Python 3.10.7 python with pip: sudo apt install python3-pip gcc&g version 12.2.0 (Ubuntu 12.2.0-3ubuntu1) Make 4.2.1 npm install mediasoup3 sudo …

听GPT 讲Rust源代码--library/std(16)

题图来自 EVALUATION OF RUST USAGE IN SPACE APPLICATIONS BY DEVELOPING BSP AND RTOS TARGETING SAMV71[1] File: rust/library/std/src/sync/mpmc/select.rs 在Rust标准库中,rust/library/std/src/sync/mpmc/select.rs文件的作用是实现一个多生产者多消费者的选…

C++笔记之动态数组的申请和手动实现一个简单的vector

C笔记之动态数组的申请和手动实现一个简单的vector code review! 文章目录 C笔记之动态数组的申请和手动实现一个简单的vector1.C语言中动态数组的申请与使用1.动态数组的申请使用new和delete使用std::vector 1.std::vector的底层实现2.手动实现一个简单的vector:使用一个指向…

项目上线前发现严重Bug怎么办?

今天分享一个面试问题,现在有一个面试场景: 项目计划明天发布,但是在今天你作为测试人员发现了一个严重的bug,市场相关人员又在催发布的事情,这个时候你应该怎么办? 这是测试工程师不管是在面试&#xff0…

力扣 138. 随机链表的复制

题目描述: 给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的…

前端框架Vue学习 ——(三)Vue生命周期

生命周期:指一个对象从创建到销毁的整个过程。 生命周期的八个阶段:每触发一个生命周期事件,会自动执行一个生命周期方法(钩子) mounted:挂载完成,Vue 初始化成功,HTML 页面渲染成功…

京东商品详情API接口(PC端和APP端),京东详情页,商品属性接口,商品信息查询

京东开放平台提供了API接口来访问京东商品详情。通过这个接口,您可以获取到商品的详细信息,如商品名称、价格、库存量、描述等。 以下是使用京东商品详情API接口的一般步骤: 注册并获取API权限:您需要在京东开放平台上注册并获取…