FreeRTOS任务通知

从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);//如果需要的话进行一次任务切换}
} 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/379720.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kinect在openni下也能玩抠出人物换背景

之前想了个很拉风的名字《用kinect玩穿越》,但是现在功能还不是很完善,细节处理也不是很好,脸皮没有足够的厚,所以呢还是叫换背景吧。 这里面包含两个技术要点: 一、抠出活动人物 在微软的SDK里深度图像的前3位即0-2位…

Emit学习-基础篇-基本概念介绍

之前的Hello World例子应该已经让我们对Emit有了一个模糊的了解,那么Emit到底是什么样一个东西,他又能实现些什么功能呢?昨天查了点资料,大致总结了下,由于才开始学习肯定有不完善的地方,希望大家能够批评指…

The FreeRTOS Distribution(介绍、移植、类型定义)

1 Understand the FreeRTOS Distribution 1.1 Definition :FreeRTOS Port FreeRTOS目前可以在20种不同的编译器构建,并且可以在30多种不同的处理器架构上运行,每个受支持的编译器和处理器组合被认为是一个单独的FreeRTOS Port。 1.2 Build…

Eclipse项目左上角出现大红色感叹号怎么办?

出现大红色感叹号是因为环境不匹配 解决方法: 右击出现大红色感叹号的项目 点击 Libraries,将有叉号的给Remove掉 然后再点击 Add Library —> JRE System Library —> Next 勾选第二个即可 之后,就不会出现大红色感叹号了。

PCB---STM32最小系统制作过程

PCB 制作过程STM32核心模块连接外部电源晶振OSC_IN(8MHz)OSC32_IN(32.768MHz)复位下载口BOOT模式电源模块添加功能UARTWKUPSTM32核心模块 这里我们以STM32F103C8T6为列,先将芯片的原理图放到原理图中 对于STM32,有几个模块是核心&#xff0…

FreeRTOS---堆内存管理(一)

FreeRTOS的堆内存管理简介动态内存分配及其与 FreeRTOS 的相关性动态内存分配选项内存分配方案Heap_1heap_2Heap_3Heap_4设置heap_4的起始地址Heap_5vPortDefineHeapRegions()堆相关的函数xPortGetFreeHeapSizexPortGetMinimumEverFreeHeapSizeMalloc调用失败的Hook函数这篇文章…

FreeRTOS--堆内存管理(二)

堆内存管理代码具体实现heap_1内存申请函数内存释放函数heap_2内存块内存堆初始化函数内存块插入函数内存申请函数判断是不是第一次申请内存开始分配内存内存释放函数heap_3heap_4内存堆初始化函数内存块插入函数heap_5上一篇文章说了FreeRTOS实现堆内存的原理,这一…

css中的node.js_在Node App中使用基本HTML,CSS和JavaScript

css中的node.jsYou may think this is not important, but it is!. As a beginner in node.js, most coding exercises are always server sided. 您可能认为这并不重要,但确实如此! 作为node.js的初学者,大多数编码练习始终都是服务器端的。…

Binary String Matching(C++)

题目描述: Given two strings A and B, whose alphabet consist only ‘0’ and ‘1’. Your task is only to tell how many times does A appear as a substring of B? For example, the text string B is ‘1001110110’ while the pattern string A is ‘11’, you should…

VisualStudio2019配置OpenCV

VisualStudio2019配置OpenCV配置0x01 准备0x02 配置系统环境0x03 复制文件0x04 配置VisualStudio2019测试配置 0x01 准备 下载opencv,官网地址:https://opencv.org/releases/# 下载之后,自行安装 0x02 配置系统环境 找到高级系统设置 …

Visual Studio进行linux远程开发

目录准备工作创建一个项目配置远程项目准备工作 查看linux IP地址 安装了工具 sudo apt-get install openssh-server g gdb make ninja-build rsync zip开启ssh服务: sudo service ssh startVS2019按装了linux功能,如果没有,找到Visual S…

在给定总和K的二叉树中找到级别

Description: 描述: The article describes how to find the level in a binary tree with given sum K? This is an interview coding problem came in Samsung, Microsoft. 本文介绍了如何在给定总和K下在二叉树中找到级别 ? 这是一个面试编码问题&a…

++i与i++的根本性区别(两个代码对比搞定)

首先来看i 代码如下&#xff1a; #include <stdio.h> #include <stdlib.h> int main() {int i0;int ai;printf("%d\n",a);printf("%d\n\n\n",i);return 0; }输出结果如下&#xff1a; 解释&#xff1a;i其实是两行代码的简写形式&#xff0c…

Python | 使用matplotlib.pyplot创建线图

Problem statement: Write a program in python (using matplotlib.pyplot) to create a line plot. 问题陈述&#xff1a;用python编写程序(使用matplotlib.pyplot)以创建线图。 Program: 程序&#xff1a; import matplotlib.pyplot as pltx [1,2,3,4,5,6,7,8,9,10]y [3,…

linux内核设计与实现---从内核出发

获取、编译、安装内核1 获取内核源码安装内核源代码何处安装源码使用补丁2 内核源码树3 编译内核减少编译的垃圾信息衍生多个编译作业安装内核启用指定内核作为引导4 内核开发的特点没有libc库头文件没有内存保护机制容积小而固定的栈1 获取内核源码 在linux内核官方网站http:…

linux内核设计与实现---进程管理

进程管理1 进程描述符及任务结构分配进程描述符进程描述符的存放进程状态设置当前进程状态进程上下文进程家族树2 进程创建写时拷贝fork()vfork()3 线程在Linux中的实现内核线程4 进程终结删除进程描述符孤儿进程造成的进退微谷5 小结进程的另一个名字叫做任务&#xff08;task…

生日蜡烛(蓝桥杯)

某君从某年开始每年都举办一次生日party&#xff0c;并且每次都要吹熄与年龄相同根数的蜡烛。 现在算起来&#xff0c;他一共吹熄了236根蜡烛。 请问&#xff0c;他从多少岁开始过生日party的&#xff1f; 请填写他开始过生日party的年龄数。 注意&#xff1a;你提交的应该是…

Linux内核设计与实现---进程调度

进程调度1 策略I/O消耗型和处理器消耗型的进程进程优先级时间片进程抢占2 Linux调度算法可执行队列优先级数组重新计算时间片schedule()计算优先级和时间片睡眠和唤醒负载平衡程序3 抢占和上下文切换用户抢占内核抢占4 实时5 与调度相关的系统调用与调度策略和优先级相关的系统…

ServletContext(核心内容)

什么是ServletContext对象 ServletContext代表是一个web应用的环境&#xff08;上下文&#xff09;对象&#xff0c;ServletContext对象 内部封装是该web应用的信息&#xff0c;ServletContext对象一个web应用只有一个 一个web应用有多个servlet对象 ServletContext对象的生…

【转载】[TC]飞船动画例子--《C高级实用程序设计》

【声明和备注】本例子属于转载来源于《C高级实用程序设计》&#xff08;王士元&#xff0c;清华大学出版社&#xff09;第11章&#xff0c;菜单设计与动画技术&#xff0c;第11.5节&#xff0c;一个动画例子。 本例讲解的是在一个繁星背景下&#xff0c;一个由经纬线组成的蓝色…