FreeRTOS应用(参数,优先级,延时,钩子,任务,删除函数)

发布时间:2026/9/28 12:43:54

FreeRTOS应用(参数,优先级,延时,钩子,任务,删除函数)
1.任务参数使用2.任务的优先级3.相对延时函数4.绝对延时函数5.空闲钩子函数6.任务句柄7.删除任务函数一.任务参数使用1.void指针可以指向任意类型的数据既可以用任意类型的指针对void指针赋值。例如int *a; void *p; pa;如果将void指针p赋给其它类型的指针则需要强制转换例如a(int*)p2.在不同的标准中ANSI c标准中void不能进行算数运算因为void是无类型每次算数运算就不知道该操作几个字节。而在GNU中可以因为GNU认为void*和char*一样。sizeof(void*)sizeof(char*);3.应用①CubeMX的配置代码在FreeRTOS.c与main.c中加#include user_app.huser_app.h #ifndef __USER_APP_H__ #define __USER_APP_H__ #include usart.h #include stdio.h #include FreeRTOS.h #include task.h #include main.h #include cmsis_os2.h #include string.h void vTaskFunction(void *pvParameters); void vprintfString(const char *pcString); #endifuser_app.c #include user_app.h #define mainDELAY_LOOP_COUNT 0xffffff int fputc(int ch, FILE *f) { HAL_UART_Transmit (huart1 ,(uint8_t*)ch,1,0xffff); return ch; } void vprintfString(const char *pcString) { //临近保护 taskENTER_CRITICAL(); { printf(%s,pcString); } taskEXIT_CRITICAL(); } void vTaskFunction(void *pvParameters) { char *pcTaskName; volatile uint32_t ul; pcTaskName(char*)pvParameters; for(;;) { vprintfString(pcTaskName); for(ul0;ulmainDELAY_LOOP_COUNT ;ul) { //延时 } char cSectionStr1[]task1; char *pcRetPtrstrstr(pcTaskName,cSectionStr1); //对比pcTaskName与cSectionStr1是否一样 if(pcRetPtr !NULL) { HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin); } else { HAL_GPIO_TogglePin(LED4_GPIO_Port, LED4_Pin); } } }二.任务的优先级1.优先级的介绍①调度器始终确保可以运行的最高优先级任务是被选中进入运行状态的任务。具有相同优先级的任务会依次进入和退出运行状态。② 用于创建任务的 xTaskCreate() API函数的uxPriority 参数为任务分配其初始优先级。vTaskPrioritySet() API函数在任务创建后改变其优先级。③ 最大优先级数量由FreeRTOSConfig.h 中定义的configMAX_PRIORITIES 编译时配置常量设置。较低的数值优先级表示低优先级任务其中优先级0是最低优先级。可以使用的优先级范围是从0到(configMAX_PRIORITIES – 1)。【建议configMAX_PRIORITIES的值保持在最小值减少RAM的开销和减少执行时间】扩展若将FreeRTOSConfig.h中的configUSE_PORT_OPTIMISED_TASK_SELECTION设置为 0 。如果没有定义configUSE_PORT_OPTIMISED_TASK_SELECTION 或者通用方法是为正在使用的FreeRTOS移植提供的唯一方法就会使用通用方法。在FreeRTOSConfig.h中将configUSE_PORT_OPTIMISED_TASK_SELECTION设置为1时就会使用架构优化的方法。注意并非所有的FreeRTOS移植都提供了架构优化方法。2.测量与滴答中断3.应用CubeMX的配置略代码在FreeRTOS.c与main.c中加#include user_app.huser_app.h #ifndef __USER_APP_H__ #define __USER_APP_H__ #include usart.h #include stdio.h #include FreeRTOS.h #include task.h #include main.h #include cmsis_os2.h #include string.h void vTaskFunction(void *pvParameters); void vprintfString(const char *pcString); #endifuser_app.c #include user_app.h #define mainDELAY_LOOP_COUNT 0xffffff int fputc(int ch, FILE *f) { HAL_UART_Transmit (huart1 ,(uint8_t*)ch,1,0xffff); return ch; } void vprintfString(const char *pcString) { //临近保护 taskENTER_CRITICAL(); { printf(%s,pcString); } taskEXIT_CRITICAL(); } void vTaskFunction(void *pvParameters) { char *pcTaskName; volatile uint32_t ul; pcTaskName(char*)pvParameters; for(;;) { vprintfString(pcTaskName); for(ul0;ulmainDELAY_LOOP_COUNT ;ul) { } char cSectionStr1[]task1; char *pcRetPtrstrstr(pcTaskName,cSectionStr1); if(pcRetPtr !NULL) { HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin); } else { HAL_GPIO_TogglePin(LED4_GPIO_Port, LED4_Pin); } } }效果三.相对延时函数1.事件驱动型任务到目前为止创建的任务总是需要执行处理操作并且从未需要等待任何东西因此总是能够进入运行状态。 “连续处理”类型的任务用途有限任务只能在最低优先级下创建。如果这些任务以其他优先级运行就会阻止优先级更低的任务运行。必须将任务重新编写成事件驱动型的任务。事件驱动型的任务具有的不同优先级只有在触发事件发生后才有工作要执行在事件发生前不会进入运行状态。调度器始终选择可以运行的最高优先级任务。如果无法选择高优先级任务例如正在等待某个事件则调度器必须选择可以运行的优先级较低的任务。2.任务的阻塞状态正在等待事件的任务称为处于“阻塞”状态这是“非运行”状态的一个子状态。任务可以进入阻塞状态以等待两种不同类型的事件• 时间性事件这些事件发生在延迟期到期或达到绝对时间时。例如任务可能会进入阻塞状态以等待10毫秒过去。• 同步事件这些事件来自另一个任务或中断。例如任务可能会进入阻塞状态等待队列中的数据到达。同步事件涵盖了广泛的事件类型。队列、二进制/计数信号量、互斥量、递归互斥量、事件组、流缓冲区、消息缓冲区和直接任务通知都可以创建同步事件。任务也可以在同步事件上设置超时从而有效地同时阻塞两种类型的事件。3.挂起和就绪状态①挂起状态挂起状态也是非运行状态的一个子状态。处于挂起状态的任务对调度器不可用。进入挂起状态的唯一方法是调用vTaskSuspend() API函数。退出挂起状态的唯一方法是调用vTaskResume()或xTaskResumeFromISR() API函数。大多数应用程序不使用挂起状态。②就绪状态处于非运行状态且未阻塞或挂起的任务被称为处于就绪状态。它们可以运行因此准备运行但当前不在运行状态。4.vTaskDelay()函数5.应用CubeMX配置代码在FreeRTOS.c与main.c中加#include user_app.huser_app.h #ifndef __USER_APP_H__ #define __USER_APP_H__ #include usart.h #include stdio.h #include FreeRTOS.h #include task.h #include main.h #include cmsis_os2.h #include string.h void vTaskFunction(void *pvParameters); void vprintfString(const char *pcString); #endifuser_app.c #include user_app.h #define mainDELAY_LOOP_COUNT 0xffffff int fputc(int ch, FILE *f) { HAL_UART_Transmit (huart1 ,(uint8_t*)ch,1,0xffff); return ch; } void vprintfString(const char *pcString) { //临近保护 taskENTER_CRITICAL(); { printf(%s,pcString); } taskEXIT_CRITICAL(); } void vTaskFunction(void *pvParameters) { char *pcTaskName; const TickType_t xDelay250mspdMS_TO_TICKS (250); //注意把250ms转换为滴答数 pcTaskName(char*)pvParameters; for(;;) { vprintfString(pcTaskName); vTaskDelay (xDelay250ms ); char cSectionStr1[]task1; char *pcRetPtrstrstr(pcTaskName,cSectionStr1); if(pcRetPtr !NULL) { HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin); } else { HAL_GPIO_TogglePin(LED4_GPIO_Port, LED4_Pin); } } }效果四.绝对延时函数CubeMX配置略代码在FreeRTOS.c与main.c中加#include user_app.h在FreeRTOS.c中user_app.h #ifndef __USER_APP_H__ #define __USER_APP_H__ #include usart.h #include stdio.h #include FreeRTOS.h #include task.h #include main.h #include cmsis_os2.h #include string.h void vContinuousProcessingTask(void *pvParameters); void vprintfString(const char *pcString); void vPeriodicTask(void* pvParameters); #endifuser_app.c #include user_app.h #define mainDELAY_LOOP_COUNT 0xfffff int fputc(int ch, FILE *f) { HAL_UART_Transmit (huart1 ,(uint8_t*)ch,1,0xffff); return ch; } void vprintfString(const char *pcString) { //临近保护 taskENTER_CRITICAL(); { printf(%s,pcString); } taskEXIT_CRITICAL(); } void vContinuousProcessingTask(void *pvParameters) { char *pcTaskName; volatile uint32_t ul; pcTaskName(char*)pvParameters ; for(;;) { vprintfString(pcTaskName); for(ul0;ulmainDELAY_LOOP_COUNT;ul) { } char*pcRetPtrstrstr(pcTaskName ,task1); if(pcRetPtr !NULL) { HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin); } else { HAL_GPIO_TogglePin(LED4_GPIO_Port, LED4_Pin); } } } void vPeriodicTask(void* pvParameters) { TickType_t xLastWakeTime; const TickType_t xDelay250mspdMS_TO_TICKS (250UL); const char *a(char*) pvParameters; xLastWakeTime xTaskGetTickCount (); for(;;) { vprintfString(a); vTaskDelayUntil (xLastWakeTime ,xDelay250ms ); } }效果五.空闲钩子函数应用CubeMX的配置代码在FreeRTOS.c与main.c中加#include user_app.h在FreeRTOS中user_app.h #ifndef __USER_APP_H__ #define __USER_APP_H__ #include usart.h #include stdio.h #include FreeRTOS.h #include task.h #include main.h #include cmsis_os2.h #include string.h void vContinuousProcessingTask(void *pvParameters); void vprintfString(const char *pcString,uint32_t ulValue); #endifuser_app.c #include user_app.h #define mainDELAY_LOOP_COUNT 0xfffff uint32_t ulIdleCycleCount0; int fputc(int ch, FILE *f) { HAL_UART_Transmit (huart1 ,(uint8_t*)ch,1,0xffff); return ch; } void vprintfString(const char *pcString,uint32_t ulValue) { //临近保护 taskENTER_CRITICAL(); { printf(%s,pcString); printf(ulIdleCycleCount%d\n\r,ulValue); } taskEXIT_CRITICAL(); } void vContinuousProcessingTask(void *pvParameters) { char *pcTaskName; //volatile uint32_t ul; pcTaskName(char*)pvParameters ; const TickType_t xDelay250mspdMS_TO_TICKS (250); for(;;) { vprintfString(pcTaskName,ulIdleCycleCount); vTaskDelay (xDelay250ms ); char*pcRetPtrstrstr(pcTaskName ,task1); if(pcRetPtr !NULL) { HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin); } else { HAL_GPIO_TogglePin(LED4_GPIO_Port, LED4_Pin); } } }效果六.任务句柄应用CubeMX的配置略代码在FreeRTOS.c与main.c中加#include user_app.huser_app.h #ifndef __USER_APP_H__ #define __USER_APP_H__ #include usart.h #include stdio.h #include FreeRTOS.h #include task.h #include main.h #include cmsis_os2.h #include string.h void vTask1(void *pvParameters); void vprintfString(const char *pcString); void vTask2(void* pvParameters); #endifuser_app.c #include user_app.h #define mainDELAY_LOOP_COUNT 0xfffff extern osThreadId_t Task1Handle; extern osThreadId_t Task2Handle; int fputc(int ch, FILE *f) { HAL_UART_Transmit (huart1 ,(uint8_t*)ch,1,0xffff); return ch; } void vprintfString(const char *pcString) { //临近保护 taskENTER_CRITICAL(); { printf(%s,pcString); // printf(ulIdleCycleCount%d\n\r,ulValue); } taskEXIT_CRITICAL(); } void vTask1(void *pvParameters) { UBaseType_t uxPriorityuxTaskPriorityGet(NULL); for(;;) { vprintfString(Task1 is Running\n\r); vprintfString (About to raise the Task2 priority\n\r); vTaskPrioritySet (Task2Handle,(uxPriority1)); //注意 HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin); } } void vTask2(void* pvParameters) { UBaseType_t uxPriorityuxTaskPriorityGet(NULL); for(;;) { vprintfString(Task2 is Running\n\r); vprintfString (About to lower the Task2 priority\n\r); vTaskPrioritySet(NULL,(uxPriority -2)); //注意 HAL_GPIO_TogglePin(LED4_GPIO_Port, LED4_Pin); } }效果七.删除任务函数应用在FreeRTOS.c与main.c中加#include user_app.huser_app.h #ifndef __USER_APP_H__ #define __USER_APP_H__ #include usart.h #include stdio.h #include FreeRTOS.h #include task.h #include main.h #include cmsis_os2.h #include string.h void vTask1(void *pvParameters); void vprintfString(const char *pcString); void vTask2(void* pvParameters); #endifuser_app.c #include user_app.h TaskHandle_t xTask2Handle; extern osThreadId_t Task1Handle; extern osThreadId_t Task2Handle; int fputc(int ch, FILE *f) { HAL_UART_Transmit (huart1 ,(uint8_t*)ch,1,0xffff); return ch; } void vprintfString(const char *pcString) { //临近保护 taskENTER_CRITICAL(); { printf(%s,pcString); } taskEXIT_CRITICAL(); } void vTask1(void *pvParameters) { const TickType_t xDelay100mspdMS_TO_TICKS (100UL); for(;;) { vprintfString(Task1 is Running\n\r); xTaskCreate(vTask2,Task 2,1000,NULL,osPriorityLow1,xTask2Handle); } } void vTask2(void* pvParameters) { HAL_GPIO_TogglePin(LED4_GPIO_Port, LED4_Pin); vprintfString (Task2 is running and abut to delete itself\n\r); vTaskDelete (xTask2Handle ); }效果

相关新闻

EIP低代码平台介绍

EIP低代码平台介绍

2026/9/5 22:50:01

EIP低代码平台 🔥 自研可视化表单引擎 拖拽流程引擎双核心,基于.NET 10 Vue2 Redis MySQL 分层模块化架构,完整 RBAC 权限、多渠道消息推送、全链路运维监控、企业微信 / 钉钉原生集成,开箱即用企业级私有化后台解决方案 开源…

北京四合院的味道,怎么“搬”进墓园?

北京四合院的味道,怎么“搬”进墓园?

2026/8/23 4:14:55

北京桃峰园“京韵华章” 做了一件很“北京”的事:把四合院、门扣、花窗、印玺、玉璧等京韵文化元素,深度萃取进墓园设计。 项目总占地2600㎡,遵循“五进礼序”空间格局,规划了京安苑、京禅苑、京福苑、京和苑、京华苑五大主题苑区…

生物医学大模型技术解析与应用实践

生物医学大模型技术解析与应用实践

2026/8/23 4:14:55

1. 生物医学大模型的现状与突破过去三年里,生物医学领域正在经历一场由大模型引发的技术革命。2023年Nature Medicine的一篇综述显示,全球已有超过47个专门针对生物医学领域训练的大模型,参数量从亿级到千亿级不等。这些模型正在改变从基础研…

CANN/GE ACL数据集缓冲区添加函数

CANN/GE ACL数据集缓冲区添加函数

2026/9/28 4:08:17

aclmdlAddDatasetBuffer 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、Te…

用ffmpeg高效批量调整图片尺寸的实战指南

用ffmpeg高效批量调整图片尺寸的实战指南

2026/9/27 1:30:29

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

2026/9/28 2:15:29

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱 【免费下载链接】transformers 🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and mu…

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

2026/9/28 3:14:54

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system sup…

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

2026/9/28 3:58:00

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

2026/9/28 3:47:14

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system supporting mi…

远程协作的工作台整理

远程协作的工作台整理

2026/9/26 14:29:04

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/28 5:05:21

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/26 23:35:16

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…