【FreeRTOS】创建第一个多任务程序

2024-06-13 01:52

本文主要是介绍【FreeRTOS】创建第一个多任务程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

创建第1个多任务程序

韦东山 Freertos学习 第一个多任务程序创建

1. 目标

创建两个任务,任务A运行Led_Test,任务B运行LCD_Test。
硬件平台:DShanMCU-F103开发板

2. 接口函数

创建任务的API函数
不同操作系统有不同的创建API函数
FreeRTOS: xTaskCreate
RT-Thread: rt_thread_create

统一:osThreadNew
在cmsis_os2.c里面定义了

参考《FreeRTOS入门与工程实践(基于DshanMCU-103)》里《9.2.2 创建任务》,关键信息如下:

	BaseType_t xTaskCreate(	TaskFunction_t pxTaskCode,const char * const pcName,		const configSTACK_DEPTH_TYPE usStackDepth,void * const pvParameters,UBaseType_t uxPriority,TaskHandle_t * const pxCreatedTask );
  • ASK_CODE pvTaskCode :是一个指向任务的实现函数的指针,任务只是一个不会退出的子函数,通常我们会写一个死循环来实现;
  • const signed portCHAR * const pcName:任务名,用于辅助调试FreeRTOS并不会使用他;
  • unsigned portSHORT usStackDepth:当任务创建时,内核会分为每个任务分配属于任务自己的唯一状态,该值用于指定分配多大的栈空间,传入的值表示的是栈空间可以保存多少个字(word),而不是多少个字节(byte)。比如说,如果是 32 位宽的栈空间,传入的
  • usStackDepth值为 100,则将会分配 400 字节的栈空间(100 * 4bytes)。栈深度乘以栈宽度的结果千万不能超过一个 size_t 类型变量所能表达的最大值,大部分时间用户赋予较合理的数值即可(小了就调大,大了就调小尽量保证空间的不浪费)
  • void *pvParameters:传入我们任务函数中的值,一般为NULL
  • unsigned portBASE_TYPE uxPriority:指定任务执行的优先级。优先级的取值范围可以从最低优先级 0 到最高优先级(configMAX_PRIORITIES – 1)
  • xTaskHandle *pxCreatedTask:传入任务句柄,如果该任务不会被应用程序用到也可以设置为NULL;
  • 该函数有两个可能的返回值:
    pdTRUE: 表明任务创建成功。
    errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY:由于内存堆空间不足,FreeRTOS 无法分配足够的空间来保存任务结构数据和任务栈,因此无法创建任务

当我们创建完成一个任务,我们的任务状态还是处于就绪状态,还未开启任务调度器,也没创建空闲任务与定时器任务任务调度器只启动一次,之后就不会再次执行了,FreeRTOS 中启动任务调度器的函数是 vTaskStartScheduler(),并且启动任务调度器的时候就不会返回,从此任务管理都由 FreeRTOS管理,如果这里我们卸载vTaskStartScheduler后面的语句执行了也就说明我们的任务启动失败这时候我们需要根据情况特殊处理(这里需要注意在实时操作系统中我们的任务看似是可以共同执行,但实际过程中他们也是有一个切换过程的,在任何时刻只可能有一个任务处于运行态。所以一个任务进入运行态后(切入)另一个任务就会进入非运行态(切出),更多理论上的就不多赘述了网上有很多大神写过,或者查看官方文档了解freertos的任务调度算法;
————————————————

                        版权声明:本文为博主原创文章,遵循 CC 4.0 BY 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/qq_43581670/article/details/127655121

3. 编程

FreeRTOS原生代码创建任务
先写一个自己的函数MyTask, 在这个任务里执行Led_Test();函数

void MyTask(void *argumment) // 自己创建的任务的函数
{while (1){Led_Test();}
}

创建这个任务
freertos的所有任务都是一个while循环

void MX_FREERTOS_Init(void)
{/* USER CODE BEGIN Init *//* USER CODE END Init *//* USER CODE BEGIN RTOS_MUTEX *//* add mutexes, ... *//* USER CODE END RTOS_MUTEX *//* USER CODE BEGIN RTOS_SEMAPHORES *//* add semaphores, ... *//* USER CODE END RTOS_SEMAPHORES *//* USER CODE BEGIN RTOS_TIMERS *//* start timers, add new ones, ... *//* USER CODE END RTOS_TIMERS *//* USER CODE BEGIN RTOS_QUEUES *//* add queues, ... *//* USER CODE END RTOS_QUEUES *//* Create the thread(s) *//* creation of defaultTask */defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);/* USER CODE BEGIN RTOS_THREADS *//* add threads, ... */xTaskCreate(MyTask,             //用MyTask函数来创建一个任务"MyFirstTask",      //任务的名字:我的第一个任务MyFirstTask128,                //栈的深度 128NULL,               //不需要什么参数 NULLosPriorityNormal,   //优先级 osPriorityNormalNULL);              //最后一个参数先不用 NULL/* USER CODE END RTOS_THREADS *//* USER CODE BEGIN RTOS_EVENTS *//* add events, ... *//* USER CODE END RTOS_EVENTS */
}

CubeMX创建的默认任务,执行LCD_Test();函数

/*** @brief  Function implementing the defaultTask thread.* @param  argument: Not used* @retval None*/
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{/* USER CODE BEGIN StartDefaultTask *//* Infinite loop */LCD_Init();LCD_Clear();for (;;){// Led_Test();LCD_Test();// MPU6050_Test();// DS18B20_Test();// DHT11_Test();// ActiveBuzzer_Test();// PassiveBuzzer_Test();// ColorLED_Test();// IRReceiver_Test();// IRSender_Test();// LightSensor_Test();// IRObstacle_Test();// SR04_Test();// W25Q64_Test();// RotaryEncoder_Test();// Motor_Test();// Key_Test();// UART_Test();}/* USER CODE END StartDefaultTask */
}

修改LCD_Test();的内容,LCD_Test();函数里是OLED_Test(); 只修改OLED_Test函数即可

void OLED_Test(void)
{int OLED_Count = 0;OLED_Init();// 清屏OLED_Clear();while (1){// 在(0, 0)打印'A'OLED_PutChar(0, 0, 'A');// 在(1, 0)打印'Y'OLED_PutChar(1, 0, 'Y');// 在第0列第2页打印一个字符串"Hello World!"OLED_PrintString(0, 2, "Hello World!");OLED_PrintSignedVal(6, 4, OLED_Count++);}
}

4. 测试

编译程序,下载测试~

在这里插入图片描述

开发板使用

1. 硬件接线

DshanMCU-103上有4个插针,它们分别是GND、SWCLK、SWDIO、3.3V。ST-Link上有10个插针,它们的功能在外壳上有标注。接线方法如下图所示:
在这里插入图片描述
连接好的实物图如下(ST-Link的USB口要插到电脑上):
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/3ead43300b704f8e8ea90feefcee09bc.png## 2. 打开工程

解压如下程序,放入无中文字符的目录里:

在这里插入图片描述

使用Keil打开工程。

3. 修改代码

在这里插入图片描述

4. 注意事项

有些模块的引脚是共用的,所以它们要么不能同时接,要么不能同时使用。

打开底板原理图,里面有说明:

在这里插入图片描述

列表如下:

模块1模块2备注
M2(DS18B20)M10(DHT11温湿度模块)不能同时接
M4(红外发射模块)M9(蜂鸣器)不能同时接
M6(超声波模块)M12(Flash模块)可以同时接,但是要互斥访问

在这里插入图片描述

参考文章:

http://t.csdnimg.cn/a6WMU
http://t.csdnimg.cn/nuOz1
http://t.csdnimg.cn/yr2Ms
http://t.csdnimg.cn/SO6iz

在这里插入图片描述

我们下文再见~

这篇关于【FreeRTOS】创建第一个多任务程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1055959

相关文章

IntelliJ IDEA2025创建SpringBoot项目的实现步骤

《IntelliJIDEA2025创建SpringBoot项目的实现步骤》本文主要介绍了IntelliJIDEA2025创建SpringBoot项目的实现步骤,文中通过示例代码介绍的非常详细,对大家... 目录一、创建 Spring Boot 项目1. 新建项目2. 基础配置3. 选择依赖4. 生成项目5.

Linux线程之线程的创建、属性、回收、退出、取消方式

《Linux线程之线程的创建、属性、回收、退出、取消方式》文章总结了线程管理核心知识:线程号唯一、创建方式、属性设置(如分离状态与栈大小)、回收机制(join/detach)、退出方法(返回/pthr... 目录1. 线程号2. 线程的创建3. 线程属性4. 线程的回收5. 线程的退出6. 线程的取消7.

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

创建Java keystore文件的完整指南及详细步骤

《创建Javakeystore文件的完整指南及详细步骤》本文详解Java中keystore的创建与配置,涵盖私钥管理、自签名与CA证书生成、SSL/TLS应用,强调安全存储及验证机制,确保通信加密和... 目录1. 秘密键(私钥)的理解与管理私钥的定义与重要性私钥的管理策略私钥的生成与存储2. 证书的创建与

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker

python如何创建等差数列

《python如何创建等差数列》:本文主要介绍python如何创建等差数列的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录python创建等差数列例题运行代码回车输出结果总结python创建等差数列import numpy as np x=int(in

怎么用idea创建一个SpringBoot项目

《怎么用idea创建一个SpringBoot项目》本文介绍了在IDEA中创建SpringBoot项目的步骤,包括环境准备(JDK1.8+、Maven3.2.5+)、使用SpringInitializr... 目录如何在idea中创建一个SpringBoot项目环境准备1.1打开IDEA,点击New新建一个项

如何使用Maven创建web目录结构

《如何使用Maven创建web目录结构》:本文主要介绍如何使用Maven创建web目录结构的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录创建web工程第一步第二步第三步第四步第五步第六步第七步总结创建web工程第一步js通过Maven骨架创pytho

MySQL 用户创建与授权最佳实践

《MySQL用户创建与授权最佳实践》在MySQL中,用户管理和权限控制是数据库安全的重要组成部分,下面详细介绍如何在MySQL中创建用户并授予适当的权限,感兴趣的朋友跟随小编一起看看吧... 目录mysql 用户创建与授权详解一、MySQL用户管理基础1. 用户账户组成2. 查看现有用户二、创建用户1. 基

Python中使用uv创建环境及原理举例详解

《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可