恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

FreeRTOS任务通知

  • 首页
  • 资讯中心
  • /
  • FreeRTOS任务通知

相关资讯

缓存与数据库一致性实战:从原理到场景的避坑指南 2026/8/6 6:10:20
Kafka监听模式与主动拉取模式深度对比:选型指南与性能调优实战 2026/8/6 6:05:20
RabbitMQ生产者确认机制原理与实战 2026/8/6 6:05:20

最新资讯

硬件设计入门:VCC、VDD、VSS、GND等电源符号详解与PCB实战
从《植物大战僵尸》拆解游戏开发核心技术:状态机、对象池与碰撞检测
Python实现非线性叙事游戏:分形哲学与交互式故事设计实践
无刷电机驱动IC技术解析:从噪声抑制到高效控制
泡泡玛特鬼灭之刃战斗系列:从IP叙事到场景化收藏的产品设计逻辑
深度优先搜索(DFS)算法详解:从原理到实战应用

今日推荐

电力系统调度中的源荷不确定性建模与优化实践
VGG-T3技术解析:3D重建速度的革命性突破
深度解析旅游网站建设的意义及其对行业发展的深远影响与核心价值体现

本周热门

ncmdumpGUI:一键解锁网易云音乐ncm文件的终极解决方案
分布式配置中心选型实战:Nacos与Consul在创业场景下的对比
MoneyPrinterPlus实战指南:AI视频批量生成与自动化发布完整解决方案

本月精选

如何用DamaiHelper实现演唱会门票的智能自动化抢购:完整技术解决方案指南
第4篇:59 倍性能差距的索引瓶颈定位——一次教科书级的全表扫描调优
终极歌词批量下载神器:5分钟解决离线音乐库歌词同步难题

FreeRTOS任务通知

发布时间:2026/8/6 6:10:20
FreeRTOS任务通知 1.任务通知什么是任务通知任务通知就是直接的通信不需要中间量通信对象比如队列信号量事件组...可以让任务与任务中断服务程序进行同步注意中断服务程序可以直接发给任务但任务不可以直接发给中断服务程序。configUSE_TASK_NOTIFICATIONS被设置1时每一个任务至少有一个“通知状态”可以是“待定”或“未定”以及一个32位无符号整数的“通知值”。当一个任务接收到通知时其通知状态被设置为待定当一个任务读取通知值时其通知状态被设置为未定。2.任务通知的使用任务通知具有非常强大的功能通常可以用来替代二进制信号量、计数信号量、事件组有时甚至是代替队列。通过使用xTaskNotify() API 函数发送任务通知以及使用xTaskNotifyWait() API 函数接收任务通知可以适应广泛的使用场景。然而在大多数情况下不需要xTaskNotify()和xTaskNotifyWait() API 函数提供的全部灵活性功能更简单的函数就足够了。因此提供了xTaskNotifyGive() API 函数作为xTaskNotify()函数的更简单但灵活性较小的替代函数并提供了ulTaskNotifyTake() API 函数作为xTaskNotifyWait()函数的更简单但灵活性较小的替代函数。任务通知系统不仅仅限于单个通知事件。configTASK_NOTIFICATION_ARRAY_ENTRIES的参数默认设置为1。如果将其设置为大于1的值则会在每个任务内部创建一个通知数组。这允许通过索引来管理通知。每个任务通知的API函数都有一个带索引的版本。使用非索引版本将访问notification[0]数组中的第一个。每个API函数的indexed版本通过后缀Indexed进行标识因此xTaskNotify()函数名变为xTaskNotifyIndexed。为了简单起见教程中仅使用任务通知函数的非索引版本。3.函数/* 由 main() 创建的两个任务的原型。 */ static void prvTask1( void *pvParameters ); static void prvTask2( void *pvParameters ); /* 由 main() 创建的任务的句柄。 */ static TaskHandle_t xTask1 NULL, xTask2 NULL; /* 创建两个任务这两个任务相互发送通知然后启动RTOS调度器。*/ void main( void ) { xTaskCreate( prvTask1, Task1, 200, NULL, tskIDLE_PRIORITY, xTask1 ); xTaskCreate( prvTask2, Task2, 200, NULL, tskIDLE_PRIORITY, xTask2 ); vTaskStartScheduler(); } /*-----------------------------------------------------------*/ /* prvTask1() 使用 indexed 版本的 API。*/ static void prvTask1( void *pvParameters ) { for( ;; ) { /* 向 prvTask2() 发送通知使其从阻塞状态变为就绪状态。 */ xTaskNotifyGiveIndexed( xTask2, 0 ); /* 阻塞等待 prvTask2() 向此任务发送通知。*/ ulTaskNotifyTakeIndexed( 0, pdTRUE, portMAX_DELAY ); } } /*-----------------------------------------------------------*/ /* prvTask2() 使用 API 的原始版本不带 Indexed。*/ static void prvTask2( void *pvParameters ) { for( ;; ) { /* 阻塞等待 prvTask1() 向此任务发送通知。 */ ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); /* 向 prvTask1() 发送一个通知将其从阻塞状态中转出。*/ xTaskNotifyGive( xTask1 ); } }4.实验1CubeMX的配置代码main.c /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ extern void ulExampleInterruptHandler(void); /* USER CODE END PV */ /* USER CODE BEGIN 4 */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { UNUSED (GPIO_Pin); if(HAL_GPIO_ReadPin (KEY4_GPIO_Port,KEY4_Pin)GPIO_PIN_SET) { ulExampleInterruptHandler(); } } /* USER CODE END 4 */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 #include Timers.h #include semphr.h #include stdlib.h #include event_groups.h void vHandlerTask(void* pvParameters); void vPeriodicTask(void * pvParameters); void ulExampleInterruptHandler(void); void vprintfStringAndNumber(const char *pcString,uint32_t ulValue); void vprintfString(const char *pcString); #endifuser_app.c #include user_app.h #include queue.h extern osThreadId_t Task1Handle; static const TickType_t xInterruptFrequencypdMS_TO_TICKS (500); void vprintfStringAndNumber(const char *pcString,uint32_t ulValue) { //临近保护 taskENTER_CRITICAL(); { printf(%s%d\n\r,pcString,ulValue); } taskEXIT_CRITICAL(); } void vprintfString(const char *pcString) { taskENTER_CRITICAL(); { printf(%s,pcString); } taskEXIT_CRITICAL(); } int fputc(int ch, FILE *f) { HAL_UART_Transmit (huart1 ,(uint8_t*)ch,1,0xffff); return ch; } void vHandlerTask(void* pvParameters) { const TickType_t xMaxExpectedBlockTimexInterruptFrequency pdMS_TO_TICKS (10); uint32_t ulEventsToProcess; for(;;) { //收 ulEventsToProcess ulTaskNotifyTake (pdTRUE,xMaxExpectedBlockTime ); if(ulEventsToProcess !0) { while(ulEventsToProcess !0) { vprintfString (Handler task - processing event.\n\r); ulEventsToProcess--; } } else { /* 如果函数执行到这一部分则表示在预期时间内没有接收到中断并且在真实的 应用中可能需要执行一些错误恢复操作。 */ } } } void vPeriodicTask(void * pvParameters) { const TickType_t Delay500mspdMS_TO_TICKS (500UL); for(;;) { vTaskDelay (xInterruptFrequency ); vprintfString (Periodic task - About to generate an interrupt\n\r); __HAL_GPIO_EXTI_GENERATE_SWIT (KEY4_Pin); //软触发 vprintfString (Periodic task _ Interruptgenerated.\n\r\n\r\n\r); } } void ulExampleInterruptHandler(void) { BaseType_t xHigherPriorityTaskWoken; xHigherPriorityTaskWoken pdFALSE; //给 vTaskNotifyGiveFromISR (Task1Handle , //正在发送通知的任务的句柄这个句柄是在任务创建时保存的。 xHigherPriorityTaskWoken //使用的方法与其他的相似 ); vTaskNotifyGiveFromISR (Task1Handle ,xHigherPriorityTaskWoken ); vTaskNotifyGiveFromISR (Task1Handle ,xHigherPriorityTaskWoken ); portYIELD_FROM_ISR (xHigherPriorityTaskWoken ); }效果

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号