当前位置: 首页 > news >正文

FreeRTOS学习笔记(二)

FreeRTOS学习笔记(二)

在STM32F407ZGT6上实现任务创建和删除

前言

  • 为什么要引入操作系统?

在没有操作系统之前,编写程序一直使用大while循环的方式来完成检查,然后使用中断的方式进行异常处理。然而当任务增多时,很难保证高优先级任务(如紧急报警)能够及时响应。

并且随着单片机处理的工作增多,while大循环中的控制逻辑越来越复杂,到了最后连编写程序的本人也无法修改,最后形成了一座shit山。

为了解耦不同功能的程序和保证工作完成的实时性,引入了操作系统,例如freeRTOS。而引入嵌入式操作系统本质上是用“空间换时间”和“用架构换效率”。

  • 操作系统如何工作?

FreeRTOS 作为一个轻量级的实时操作系统(RTOS),其核心工作机制是围绕任务调度和系统时钟节拍展开的。本篇学习笔记主要围绕任务基础(创建和删除)展开。

  • 什么是任务?

简要来说,任务可以理解为一段拥有自己独立执行环境和上下文的程序代码。打个比方来说,如果把 单片机 比作一个厨师,那么“任务”就是厨师手里正在做的一道道菜。厨师同一时间只能炒一道菜(单核),但他可以迅速切换去处理另一道即将出锅的菜(任务切换),在宏观上看起来就像是同时在做很多道菜一样。

​ 开始烧菜时总要先开火,菜出锅总要把装盘。在FreeRTOS 中任务的创建和删除就好比开火和装盘。

  • 用动态内存分配方法创建任务

下面给出一个实例是在之前已经移植了freeRTOS的基础工程上创建两个任务,LED0是每秒闪烁1次;LED1是每秒闪烁2次。LED0闪烁10次后将LED任务删除,让LED1不再闪烁。

具体代码如下:

1.创建任务函数

/* Led0Task 任务 配置 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务 */staticvoidLed0Task(void*pvParameters);/* 任务函数 */staticTaskHandle_t Led0TaskHandle=NULL;/* 任务句柄 */#defineLed0Task_PRIO4/* 任务优先级 */#defineLed0Task_STK_SIZE128/* 任务堆栈大小 *//* Led1Task 任务 配置 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务 */staticvoidLed1Task(void*pvParameters);/* 任务函数 */staticTaskHandle_t Led1TaskHandle=NULL;/* 任务句柄 */#defineLed1Task_PRIO4/* 任务优先级 */#defineLed1Task_STK_SIZE128/* 任务堆栈大小 *//** * @brief Led1Task * @param pvParameters : 传入参数 * @retval 无 */staticvoidLed1Task(void*pvParameters){while(1){LED1_TOGGLE();vTaskDelay(pdMS_TO_TICKS(250));printf("LED1正在以0.5秒周期闪烁\r\n");}}

2.定义任务句柄,用vTaskCreate()创建任务

/** * @brief appStartTask * @param 无 * @retval 无 */voidappStartTask(void){taskENTER_CRITICAL();/*进入临界段,关中断*/xTaskCreate((TaskFunction_t)Led0Task,/* 任务函数 */(constchar*)"Led0Task",/* 任务名称 */(uint16_t)Led0Task_STK_SIZE,/* 任务堆栈大小 */(void*)NULL,/* 传入给任务函数的参数 */(UBaseType_t)Led0Task_PRIO,/* 任务优先级 */(TaskHandle_t*)&Led0TaskHandle);/* 任务句柄 */xTaskCreate((TaskFunction_t)Led1Task,/* 任务函数 */(constchar*)"Led1Task",/* 任务名称 */(uint16_t)Led1Task_STK_SIZE,/* 任务堆栈大小 */(void*)NULL,/* 传入给任务函数的参数 */(UBaseType_t)Led1Task_PRIO,/* 任务优先级 */(TaskHandle_t*)&Led1TaskHandle);/* 任务句柄 */taskEXIT_CRITICAL();/*退出临界段,开中断*/vTaskStartScheduler();/*开启任务调度器*/}

3.用vTaskDelete函数释放内存

/** * @brief Led0Task * @param pvParameters : 传入参数 * @retval 无 */staticvoidLed0Task(void*pvParameters){uint16_tcnt=0;while(1){LED0_TOGGLE();vTaskDelay(pdMS_TO_TICKS(500));printf("LED0正在以1.0秒周期闪烁\r\n");if(++cnt>=10){if(eTaskGetState(Led1TaskHandle)!=eDeleted)/*如果没有被删除*/{vTaskDelete(Led1TaskHandle);/*删除LED1闪烁任务*/printf("LED1任务已经被删除\r\n");}}}vTaskDelete(NULL);}

main函数

/* USER CODE BEGIN Includes */#include"led.h"#include"freertos.h"#include"task.h"#include<stdio.h>#include"freertos_demo.h"/* USER CODE END Includes */***@brief The application entry point.*@retvalint*/intmain(void){/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */led_init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */appStartTask();/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while(1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */}

运行结果

/* Infinite loop/
/
USER CODE BEGIN WHILE/
while (1)
{
/
USER CODE END WHILE */

/* USER CODE BEGIN 3 */

}
/* USER CODE END 3 */
}

运行结果 ![任务创建和删除](https://i-blog.csdnimg.cn/direct/18849ae17f874ba99b5b909ea701772c.jpeg#pic_center)
http://www.gsyq.cn/news/1611689.html

相关文章:

  • 四川大学《微积分I-1》期末试卷及答案2016-2025学年PDF
  • 【车载 AOSP 16 蓝牙(bluedroid)服务】【qcom 平台双蓝牙】【13.耳机如何协商采样率:从 AVDTP 到 AAC 44100 的一条路】
  • YOLO目标检测论文实战指南:从模型改进到实验写作全流程
  • BetterJoy完整指南:让Switch手柄在PC游戏上完美运行
  • 告别泰拉瑞亚原版限制:tModLoader模组开发实战手册
  • Opencv延迟优化
  • 项目包含项目源码、项目文档、数据库脚本、软件工具等资料;
  • 欧姆龙NJ系列EtherCAT总线通信常用系统状态字
  • 【GitHub】 fastText:当“快“成为核心竞争力——从源码拆解 Facebook 的 10 亿词级 NLP 利器
  • 新版通达信多空主力拉升1主图2副1选股指标套装工具
  • 从厨房秤到智能称重:用STM32F103和HX711打造你的第一个物联网传感器节点
  • 别把RAG当架构:Ontology(本体)才是Agent的业务世界
  • 数组名的隐式转换规则
  • FPGA加速数字孪生:GRU算法与硬件优化实践
  • 2026 照片恢复教程|5 种零基础恢复技巧汇总,最后一个90%人不知道!
  • MFile:不止是Minio的“管理中介”
  • Keil MDK vs ARM-GCC(arm-none-eabi-gcc)完整区别
  • 关于ISACA第五届数字信任大会两大权威文件
  • 2026年AI写长篇小说工具终极测评:5款热门工具横评,长篇选手到底选哪个
  • 专访零数科技林乐:他为何坚信“数据利用”比“数据流通”更接近数字经济的本质?
  • 关于 Vaadin:专为企业级应用打造的 Java Web UI 框架
  • 批量处理远程共享目录中的特定类型文件(如 .hex、.csv 等)。
  • 北斗赋能海洋精准定位
  • 【JAVA毕设源码分享】基于springboot大学生社交平台的设计与实现(程序+文档+代码讲解+一条龙定制)
  • 快速部署:三步搞定前后端启动
  • VisualCppRedist AIO:Windows运行库一体化管理的工程化解决方案
  • 计算机视觉实战指南:目标检测、图像分割与识别从入门到部署
  • 国家中小学智慧教育平台电子课本下载工具:解决教师学生离线学习难题
  • 【Ambari Plus】04.HDFS 安装
  • 大模型技术之深度学习