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 ); }效果
企业数字化 ERP 产品动态
相关推荐
EIP低代码平台介绍 EIP低代码平台
🔥 自研可视化表单引擎 拖拽流程引擎双核心,基于.NET 10 Vue2 Redis MySQL 分层模块化架构,完整 RBAC 权限、多渠道消息推送、全链路运维监控、企业微信 / 钉钉原生集成,开箱即用企业级私有化后台解决方案 开源… · 2026/9/21 9:04:53
北京四合院的味道,怎么“搬”进墓园? 北京桃峰园“京韵华章” 做了一件很“北京”的事:把四合院、门扣、花窗、印玺、玉璧等京韵文化元素,深度萃取进墓园设计。
项目总占地2600㎡,遵循“五进礼序”空间格局,规划了京安苑、京禅苑、京福苑、京和苑、京华苑五大主题苑区… · 2026/9/20 15:22:33
Moneta亿汇:技术架构与流程清晰度如何影响体验,给出一套框架 外汇相关平台的价值,体现在长期一致性与信息呈现的细致程度上。对多数外汇相关用户来说,判断平台并不需要复杂术语,关键在于信息能否被快速理解、关键提示是否容易找到、服务体验是否稳定一致。以Moneta亿汇为例,这里聚焦这些更贴… · 2026/9/17 10:39:23
深圳营销型网站定制从零搭建避坑指南 深圳营销型网站定制从零搭建避坑指南 改个需求建站公司拖一周,这种憋屈事儿深圳的老板们太熟了。别怪你脾气不好,谁的钱都不是大风刮来的,时间更是命脉。很多人以为找个大厂就能高枕无忧,结果发现从需求沟通到上线,中间全是坑。其实,想要搞定深圳营销型… · 2026/9/27 17:42:33
自己做黑彩网站源码下载避坑:3天搞定部署不踩雷 自己做黑彩网站源码下载避坑:3天搞定部署不踩雷 改个需求建站公司拖一周,这种憋屈感谁懂? 想自己动手,网上搜【自己做黑彩网站】,满屏都是诱导下载的陷阱。 别急着去搞那些来路不明的 源码下载 ,先看清楚这背后的法律红线和技术逻辑。… · 2026/9/27 17:42:21
epoll 详解:从 select 瓶颈到 TaoToken 统一 Key 通道的配置骨架 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 17:42:21
Cursor实战案例:用DBHub MCP打通MySQL,TaoToken统一Key让AI直接对话数据库 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 17:42:15
图解步骤拆解网站的push运营怎么做告别域名服务器焦虑 图解步骤拆解网站的push运营怎么做告别域名服务器焦虑 很多刚入行的朋友一听到“网站的push运营怎么做”就头大,尤其是看着后台那些密密麻麻的域名解析、服务器配置选项,瞬间觉得自己像个文盲。别慌,这种对 域名服务器搞不懂… · 2026/9/27 17:42:09
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现 简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01
汕头网站建设制作厂家避坑指南:5大注意事项救急 汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习 简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现 简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01
汕头网站建设制作厂家避坑指南:5大注意事项救急 汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习 简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01