FreeRTOS任务创建与删除(动态编码)
1.任务创建和删除的API函数任务创建的本质就是调用FreeRTOS的API函数下面是有关描述FreeRTOS提供两种创建任务函数的形式一种是动态创建任务另一种是静态创建任务。动态创建任务任务的任务控制块以及任务的栈空间所需的内存均由 FreeRTOS 从 FreeRTOS 管理的堆中分配。静态创建任务任务的任务控制块以及任务的栈空间所需的内存需用户分配提供。API函数描述xTaskCreate()动态方式创建任务xTaskCreateStatic()静态方式创建任务vTaskDelete()删除任务1.1动态创建任务函数函数说明BaseType_txTaskCreate(TaskFunction_tpxTaskCode,/* 指向任务函数的指针 */constchar*constpcName,/* 任务名字最大长度configMAX_TASK_NAME_LEN */constconfigSTACK_DEPTH_TYPEusStackDepth,/* 任务堆栈大小默认最小128单位4字节*/void*constpvParameters,/* 传递给任务函数的参数 */UBaseType_tuxPriority,/* 任务优先级范围0 ~ configMAX_PRIORITIES - 1 */TaskHandle_t*constpxCreatedTask/* 任务句柄就是任务的任务控制块 */)返回值说明如下pdPASS任务创建成功。errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY任务创建失败。备注pxTaskCode存放的是任务函数名pcName存放的是任务别名一般直接与任务函数名一致usStackDepth和uxPriority分别是任务堆栈大小和任务优先级可以通过宏定义的方式进行方便后续修改参数pxCreatedTask2.实验目标通过 xTaskCreate( ) 和 vTaskDelete( ) 的使用来实现下面功能start_task用来创建其他的三个任务。task1实现LED1每500ms闪烁一次。task2实现LED2每500ms闪烁一次。task3判断按键KEY1是否按下按下则删掉task1。3.实验准备过程在core/Src文件夹下新建一个.c文件用于存放本次任务。同时在core/Inc文件夹下创建一个同名的.h文件。这里我们命名为freertos_demo.c和freertos_demo.h。同时点击品字图标将freertos_demo.c路径进行添加。4.代码编写4.1freertos_demo.c文件代码编写1)任务设置#include freertos_demo.h//FreeRTOS相关的头文件必须的#include stdio.h#include FreeRTOS.h#include task.h//需要用到的其他头文件#include LED.h#include Key.h//启动任务的配置#define START_TASK_STACK 128#define START_TASK_PRIORITY 1TaskHandle_t start_task_handle;void start_task(void * pvParameters);//任务1的配置#define TASK1_STACK 128#define TASK1_PRIORITY 2TaskHandle_t task1_handle;void task1(void * pvParameters);//任务2的配置#define TASK2_STACK 128#define TASK2_PRIORITY 3TaskHandle_t task2_handle;void task2(void * pvParameters);//任务3的配置#define TASK3_STACK 128#define TASK3_PRIORITY 4TaskHandle_t task3_handle;void task3(void * pvParameters);2入口函数//启动FreeRTOSvoid freertos_start(void){/*1.创建一个启动任务*/xTaskCreate((TaskFunction_t) start_task, //任务函数的地址(char *) start_task, //任务名(configSTACK_DEPTH_TYPE) START_TASK_STACK, //任务堆栈大小默认最小128单位4字节(void *) NULL , //传递给任务的参数(UBaseType_t) START_TASK_PRIORITY, //任务优先级(TaskHandle_t *) start_task_handle); //任务句柄的地址/*2.启动调度器:会自动创建空闲任务*/vTaskStartScheduler();}3启动任务函数//启动任务用来创建其他任务void start_task(void * pvParameters){//进入临界区 临界区:保护临界区里面的代码不会被打断taskENTER_CRITICAL();//创建三个任务xTaskCreate((TaskFunction_t) task1, //任务函数的地址(char *) task1, //任务名(configSTACK_DEPTH_TYPE) TASK1_STACK, //任务堆栈大小默认最小128单位4字节(void *) NULL , //传递给任务的参数(UBaseType_t) TASK1_PRIORITY, //任务优先级(TaskHandle_t *) task1_handle); //任务句柄的地址xTaskCreate((TaskFunction_t) task2, //任务函数的地址(char *) task2, //任务名(configSTACK_DEPTH_TYPE) TASK2_STACK, //任务堆栈大小默认最小128单位4字节(void *) NULL , //传递给任务的参数(UBaseType_t) TASK2_PRIORITY, //任务优先级(TaskHandle_t *) task2_handle); //任务句柄的地址xTaskCreate((TaskFunction_t) task3, //任务函数的地址(char *) task3, //任务名(configSTACK_DEPTH_TYPE) TASK3_STACK, //任务堆栈大小默认最小128单位4字节(void *) NULL , //传递给任务的参数(UBaseType_t) TASK3_PRIORITY, //任务优先级(TaskHandle_t *) task3_handle); //任务句柄的地址//退出临界区后再删除启动任务避免屏蔽FreeRTOS时钟节拍taskEXIT_CRITICAL();//启动任务只需要执行一次即可创建完就删除vTaskDelete(NULL);}4)Task任务函数//任务一实现LED1每500ms闪烁一次void task1(void * pvParameters){while(1){printf(task1运行...\r\n);LED_Toggle(LED1_Pin);vTaskDelay(500);}}//任务二实现LED2每500ms闪烁一次void task2(void * pvParameters){while(1){printf(task2运行...\r\n);LED_Toggle(LED2_Pin);vTaskDelay(500);}}//任务三判断按键KEY1是否按下按下则删除task1void task3(void * pvParameters){uint8_t key0;while(1){printf(task3运行...\r\n);keyKey_Detect();if(keyKEY1_PRESS){//判断是否已经删过避免重复删除if(task1_handle !NULL ){printf(执行删除Task1...\r\n);//key1按下了删除task1vTaskDelete(task1_handle);task1_handleNULL;}}vTaskDelay(500);}}下面来解释一下代码实际运行时内部是如何发生变化的。task3优先级4最高task2优先级3task1优先级2启动任务优先级1空闲任务优先级0所以启动任务在临界区创建三个任务时它们的状态是task3就绪态task2就绪态task1就绪态启动任务运行态因为处于临界区task3暂时不能抢占启动任务等到临界区退出后调度过程如下第一步task3由就绪态变成运行态因为task3的优先级最高执行以下代码printf(task3运行...\r\n);key Key_Detect();vTaskDelay(500);第二步调用延时后task3由运行态转变为阻塞态。task2目前优先级最高同时处于就绪态所以执行task2的任务执行以下代码printf(task2运行...\r\n);LED_Toggle(LED2_Pin);vTaskDelay(500);第三步调用延时后task2由运行态转变为阻塞态。task1目前优先级最高同时处于就绪态所以执行task1的任务执行以下代码printf(task1运行...\r\n);LED_Toggle(LED1_Pin);vTaskDelay(500);第四步三个任务都进入阻塞态后启动任务执行vTaskDelete(NULL);删除自身。备注如果task3的500ms延时还没到系统会如何执行如果task3的500ms延时没到那么可能task1已经进入阻塞态同时启动任务也删除了自身FreeRTOS会运行系统自动创建的空闲任务Idle Task优先级0。因此CPU不会停止调度器也没有停止。系统状态是空闲任务运行态task1/2/3阻塞态。空闲任务主要做回收已删除任务的动态内存。维持系统始终至少有一个可运行任务。执行 Idle Hook当前工程已经关闭该 Hook。如果启用低功耗功能可以在空闲阶段进入休眠。当前没有开启 Tickless Idle所以CPU通常会一直执行空闲任务循环。同时每1ms仍然会发生 FreeRTOS SysTick 中断。SysTick不断检查延时任务是否到期。task3的500ms到期时task3阻塞态 → 就绪态。因为它的优先级4高于空闲任务的0所以立即抢占空闲任务空闲任务运行态 → 就绪态task3就绪态 → 运行态。

相关新闻

蓝桥杯单片机客观题深度解析:从定时器到I2C的实战原理与应用

蓝桥杯单片机客观题深度解析:从定时器到I2C的实战原理与应用

1. 从“背答案”到“懂原理”:蓝桥杯单片机客观题的真正价值如果你正在准备蓝桥杯单片机竞赛,或者对单片机学习感到迷茫,那么“客观题”这三个字,对你来说可能意味着题库、答案和死记硬背。我见过太多学生,把历届客观题…

2026/10/24 23:12:24 阅读更多 →
科学RAG的检索与重排:计算感知的工程化实践指南

科学RAG的检索与重排:计算感知的工程化实践指南

最近两年做 RAG 的团队越来越多,但有一个现象很普遍:在通用知识库、客服问答、内部 Wiki 这些场景里,RAG 管线跑得很稳定,一旦把同样一套流程迁移到科研论文、技术报告、专利文档上,检索结果就开始“飘”。明明文档切了…

2026/10/29 10:07:14 阅读更多 →
C语言字符串函数深度解析:从内存模型到安全编程实战

C语言字符串函数深度解析:从内存模型到安全编程实战

1. 项目概述:为什么C语言字符串函数值得深挖?干了这么多年嵌入式开发和底层系统编程,C语言就像我的老伙计,而字符串处理,绝对是和这位老伙计打交道时最常遇到的“日常任务”。新手觉得strcpy、strcat用起来简单&#x…

2026/10/25 3:43:35 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/6 15:21:35 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/6 9:29:27 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/5 12:28:01 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/5 12:28:02 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/6 8:08:42 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/5 19:38:59 阅读更多 →

日新闻

周新闻

月新闻