从v8.2.0版本开始,FreeRTOS新增了任务通知这个功能,可以使用任务通知来代替信号量、消息队列、事件标志组等这些东西,使用任务通知的话效率会更高。
任务通知在FreeRTOS是一个可选的选项,要使用任务通知的话就需要将宏configUSE_TASK_NOTIFICATIONS定义为1 。FreeRTOS的每个任务都有一个32位的通知值,任务控制块中的成员变量ulNotifiedValue就是这个通知值。任务通知是一个事件,可以提高速度,减少RAM的使用,但是任务通知也是有限的,FreeRTOS的任务通知只能有一个接收任务,接收任务可以因为任务通知而进入阻塞态,但是发送任务不会因为任务通知发送失败而阻塞。

0x01 发送任务通知

任务通知函数有6个

  1. xTaskNotify
BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );
  • TaskHandle_t xTaskToNotify: 任务句柄,指定任务通知是发送给那个任务的
  • uint32_t ulValue:任务通知值
  • eNotifyAction eAction:任务通知更新的方法,是一个枚举类型
typedef enum
{eNoAction = 0,                /* Notify the task without updating its notify value. */eSetBits,                   /* Set bits in the task's notification value.更新指定的bit */eIncrement,                    /* Increment the task's notification value.通知值加1 */eSetValueWithOverwrite,     /* Set the task's notification value to a specific value even if the previous value has not yet been read by the task. 覆写的方式更新通知值*/eSetValueWithoutOverwrite   /* Set the task's notification value if the previous value has been read by the task.不覆写通知值 */
} eNotifyAction;
  1. xTaskNotifyFromISR
BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken );
  • BaseType_t *pxHigherPriorityTaskWoken:退出此函数是否要进行任务切换
  1. xTaskNotifyGive
BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );
  • TaskHandle_t xTaskToNotify:指定通知是发送给那个任务的
  1. vTaskNotifyGiveFromISR
void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken );
  1. xTaskNotifyAndQuery
xTaskNotifyAndQuery( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t*pulPreviousNotificationValue);
  • TaskHandle_t xTaskToNotify:任务句柄,指定任务通知是发送给那个任务的
  • uint32_t ulValue:任务通知值
  • eNotifyAction eAction:任务通知更新方法
  • uint32_t* pulPreviousNotificationValue:用来保存更新前的任务通知值
  1. xTaskNotifyAndQueryFromISR
xTaskNotifyAndQueryFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t*pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken);

0x02 获取任务通知

获取任务通知的函数有两个

  • ulTaskNotifyTake():获取任务通知,可以设置在退出此函数的时候将任务通知值清理或者减1.当任务通知用作二值信号量或者计数信号量的时候使用此函数来获取信号量。
  • xTaskNotifyWait():等待任务通知,比ulTaskNotifyTake更为强大,全功能版任务通知获取函数
uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait )
  • BaseType_t xClearCountOnExit:为pdFALSE的话,在退出函数的时候,任务通知值减1,类似计数型信号量,当为pdTRUE的话,在退出函数的时候任务通知清零,类似二值信号量
  • TickType_t xTicksToWait:阻塞时间

返回值:任务通知值减少值或者清零之前的值

BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait )
  • uint32_t ulBitsToClearOnEntry:当没有接收到任务通知的时候,将任务通知与此参数的取反值进行按位与运算,当此参数为0xffffffff或者ULONG_MAX的时候就会将任务通知值清零
  • uint32_t ulBitsToClearOnExit:如果接收到了任务通知,在做完相应的处理退出函数之前将任务通知与此参数的取反值进行按位与运算,当此参数为0xffffffff或者ULONG_MAX的时候就会将任务通知值清零
  • uint32_t *pulNotificationValue:此参数来保存任务通知值
  • TickType_t xTicksToWait :阻塞时间

返回值:
pdTRUE:获取了任务通知
pdFALSE:任务通知获取失败

实验 任务通知模拟二值信号量

获取任务通知值,如果获取到的话,则进行逻辑处理

//DataProcess_task函数
void DataProcess_task(void *pvParameters)
{u8 len=0;u8 CommandValue=COMMANDERR;u32 NotifyValue;u8 *CommandStr;POINT_COLOR=BLUE;while(1){NotifyValue=ulTaskNotifyTake(pdTRUE,portMAX_DELAY);   //获取任务通知if(NotifyValue==1)                                    //清零之前的任务通知值为1,说明任务通知有效{len=USART_RX_STA&0x3fff;                        //得到此次接收到的数据长度CommandStr=mymalloc(SRAMIN,len+1);              //申请内存sprintf((char*)CommandStr,"%s",USART_RX_BUF);CommandStr[len]='\0';                           //加上字符串结尾符号LowerToCap(CommandStr,len);                      //将字符串转换为大写     CommandValue=CommandProcess(CommandStr);       //命令解析if(CommandValue!=COMMANDERR){LCD_Fill(10,90,210,110,WHITE);              //清除显示区域LCD_ShowString(10,90,200,16,16,CommandStr); //在LCD上显示命令printf("命令为:%s\r\n",CommandStr);switch(CommandValue)                       //处理命令{case LED1ON: LED1=0;break;case LED1OFF:LED1=1;break;case BEEPON:BEEP=0;break;case BEEPOFF:BEEP=1;break;}}else{printf("无效的命令,请重新输入!!\r\n");}USART_RX_STA=0;memset(USART_RX_BUF,0,USART_REC_LEN);            //串口接收缓冲区清零myfree(SRAMIN,CommandStr);                       //释放内存}else {vTaskDelay(10);      //延时10ms,也就是10个时钟节拍    }}
}

接收到了数据,发送任务通知,vTaskNotifyGiveFromISR的第一个参数是DataProcess_task任务的任务句柄DataProcess_Handler

//串口1中断服务程序
void USART1_IRQHandler(void)
{ u32 timeout=0;u32 maxDelay=0x1FFFF;BaseType_t xHigherPriorityTaskWoken;HAL_UART_IRQHandler(&UART1_Handler); //调用HAL库中断处理公用函数timeout=0;while (HAL_UART_GetState(&UART1_Handler) != HAL_UART_STATE_READY)//等待就绪{timeout++;超时处理if(timeout>maxDelay) break;      }timeout=0;while(HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)//一次处理完成之后,重新开启中断并设置RxXferCount为1{timeout++; //超时处理if(timeout>maxDelay) break;  }//发送任务通知if((USART_RX_STA&0x8000)&&(DataProcess_Handler!=NULL))//接收到数据,并且接收任务通知的任务有效{vTaskNotifyGiveFromISR(DataProcess_Handler,&xHigherPriorityTaskWoken);//发送任务通知portYIELD_FROM_ISR(xHigherPriorityTaskWoken);//如果需要的话进行一次任务切换}
}

FreeRTOS任务通知相关推荐

  1. 34 freertos任务通知--代替消息队列(任务邮箱)覆盖和非覆盖

    三十四. freertos任务通知–代替消息队列(任务邮箱)覆盖和非覆盖 /** *********************************************************** ...

  2. 35 freertos任务通知-代替二值信号量

    三十五. freertos任务通知-代替二值信号量 /** ********************************************************************** ...

  3. 37 freertos任务通知-代替事件组

    三十七. freertos任务通知-代替事件组 /** ************************************************************************ ...

  4. 32 freertos任务通知-代替消息队列(任务邮箱)

    三十二.freertos任务通知-代替消息队列(任务邮箱) /** ****************************************************************** ...

  5. FreeRTOS任务通知 基于STM32

    文章目录 一.任务通知简介 二.任务通知的运作机制 三.任务通知的函数接口讲解 1. xTaskGenericNotify() 2.xTaskNotifyGive() 3.vTaskNotifyGiv ...

  6. freeRtos学习笔记 (8) 任务通知

    freeRtos学习笔记 freeRtos任务通知 任务通知的优缺点 freeRtos任务控制块中包含两个32位的变量,用于任务通知,在一些情况下,任务通知可以替代信号量和事件组,并且比信号量和事件组 ...

  7. FreeRTOS记录(七、FreeRTOS信号量、事件标志组、邮箱和消息队列、任务通知的关系)

    我们在前面单独介绍过FreeRTOS的任务通知和消息队列, 但是在FreeRTOS中任务间的通讯还有信号量,邮箱,事件组标志等可以使用 这篇文章就这些成员与消息队列和任务通知的关系进行说明分析 ..增 ...

  8. 1、野火freertos学习笔记

    野火freertos学习笔记 1.任务 1.1 栈 1.2 任务的切换 taskYIELD(); 1.3 临界段 2.空闲任务 3.任务优先级 4.任务延时的表现 5.时间片 5.1抢占式.协做式 6 ...

  9. FreeRTOS——静态与动态内存分配

    FreeRTOS 基础系列文章  基本对象   FreeRTOS--任务   FreeRTOS--队列   FreeRTOS--信号量   FreeRTOS--互斥量   FreeRTOS--任务通知 ...

最新文章

  1. Scrapy项目 - 数据简析 - 实现腾讯网站社会招聘信息爬取的爬虫设计
  2. [导入]C#向Sql Server中插入记录时单引号的处理
  3. mysql浅拷贝_深入理解浅拷贝和深拷贝
  4. Django之web框架的本质
  5. LeetCode 697. 数组的度
  6. python旋转排序数组_LeetCode(力扣)——Search in Rotated Sorted Array 搜索旋转排序数组 python实现...
  7. Linux sgid功能
  8. python docx 表格复制粘贴_python Word 表格转 Excel
  9. Microsoft Dynamics 365咨询服务研究报告-Microsoft Dynamics 365咨询服务生产基地、总部、竞争对手及市场地位
  10. 碎片化NFT研究报告:COSONFT提高NFT流动性的探索和实践
  11. kotlin开发Android入门篇八Kotlin开发Android的基本使用
  12. c语言图形学画扇形代码,利用CSS绘制任意角度的扇形示例代码
  13. intellij idea 合并分支到主分支,主分支代码同步到某一分支
  14. 自然语言处理NLP(10)——语义分析
  15. PHP--根据手机号-淘宝平台获取归属地运营商信息
  16. springboot_游戏虚拟物品交易平台
  17. 微信支付V3 小程序支付API Java版
  18. 语言模型和词向量的发展史及其原理
  19. maven的pom文件报错: must be pom but is jar
  20. 【Kay】SQL窗口函数学习

热门文章

  1. java mysql nullpointerexception_无法从Java连接到MySQL:MySQL驱动程序连接逻辑中的NullPointerException...
  2. 15个创意示例教您如何自定义 404 错误页面
  3. 实用技巧:使用 Google Analytics 跟踪 JS 错误
  4. CSS 小结笔记之em
  5. 起点海外版 Hybrid App-内嵌页优化实践
  6. hdu 1251 统计难题(求前缀出现了多少次)
  7. 信息系统开发平台OpenExpressApp - 应用模型ApplicationModel
  8. Linux学习笔记006-启动流程
  9. HttpService远程校验
  10. mac vs 返回上一步_mac电脑打不开应用程序的解决方法