13.FreeRTOS任务通知

13. FreeRTOS任务通知

1. 任务通知的简介

  • 简介:

    FreeRTOS内核V8.2.0版本新增了任务通知功能,任务通知也是用于任务间进行同步和通讯的一种机制,但是相对于前面的信号量队列事件标志组等而言,任务通知在内存占用和效率方面都有很大的优势。

    在FreeRTOS中,每一个任务都有两个用于任务通知功能的数组,分别为任务通知数组任务通知状态数组。其中任务通知数组中的每一个元素都是一个32位无符号类型的通知值;而任务通知状态数组中的元素则表示与之对应的任务通知的状态。

    任务通知数组中的32位无符号通知值,用于任务到任务或中断到任务发送通知的“媒介”。当通知值为0时,表示没有任务通知;当通知值不为0时,表示有任务通知,并且通知值就是通知的内容。

    任务通知状态数组中的元素,用于标记任务通知数组中通知的状态,任务通知有三种状态,分别为未等待通知状态等待通知状态等待接收通知状态。其中未等待通知状态为任务通知的复位状态;当任务在没有通知的时候接收通知时,在任务阻塞等待任务通知的这段时间内,任务所等待的任务通知就处于等待通知状态;当有其他任务向任务发送通知,但任务还未接收这一通知的这段期间内,任务通知就处于等待接收通知状态。

    在这里插入图片描述

  • 任务通知的优点和缺点:

    在这里插入图片描述

2. 任务通知值和通知状态

  • 任务通知值:

    在这里插入图片描述

  • 任务通知状态:

    在这里插入图片描述

3. 任务通知相关API函数

任务通知API函数主要有两类:①发送通知 ,②接收通知。发送通知API函数可以用于任务和中断服务函数中;接收通知API函数只能用在任务中。

①发送通知相关API函数:

在这里插入图片描述

在这里插入图片描述

  • xTaskGenericNotify()函数
    在这里插入图片描述
    在这里插入图片描述

②接收通知相关API函数:

在这里插入图片描述

  • ulTaskNotifyTake()函数

    在这里插入图片描述

  • xTaskNotifyWait()函数

    在这里插入图片描述

4. 任务通知模拟信号量实验

  • 创建任务:

    在这里插入图片描述

  • 任务一:发送任务通知值

    /*任务一:发送任务通知值*/
    void task1(void* pvParamter)
    {		
    	while(1)
    	{	
    		switch(key_scan(0))
    		{
    			case KEY0_PRES:
    				printf("任务通知模拟二值信号量释放\r\n");
    				xTaskNotifyGive(task2_task_handler);
    				break;
    			case KEY1_PRES:
    				printf("任务通知模拟计数型信号量释放\r\n");
    				xTaskNotifyGive(task3_task_handler);
    				break;
    			default:
    				break;
    		}
    		vTaskDelay(20);
    	}
    }
    
  • 任务二:接收二值信号量任务通知值

    /*任务二:接收二值信号量任务通知值*/
    void task2(void* pvParamter)
    {	
    	uint32_t rec = 0;
    	
    	while(1)
    	{
    		rec = ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
    		if(rec != 0)
    		{
    			printf("接收任务通知成功,模拟二值信号量!\r\n");
    		}
    	}
    }
    
  • 任务三:接收计数型信号量任务通知值

    void task3(void* pvParamter)
    {	
    	uint32_t rec = 0;
    	
    	while(1)
    	{
    		rec = ulTaskNotifyTake(pdFALSE, portMAX_DELAY);
    		if(rec != 0)
    		{
    			printf("接收任务通知成功,模拟计数型信信号量为%d!\r\n",rec);
    		}
    		vTaskDelay(1000);
    	}
    }
    
  • 实验结果:

    在这里插入图片描述

5. 任务通知模拟消息邮箱和事件标志组实验

  • 创建任务:

    在这里插入图片描述

  • 相关变量定义:

    //定义事件标志组的位0和位1
    #define    EVENTBIT_0    (1 << 0)
    #define    EVENTBIT_1    (1 << 1
    
  • 任务一:发送任务通知值

    void task1(void* pvParamter)
    {
    	uint8_t key = 0;
    	
    	while(1)
    	{
    		key = key_scan(0);
    		if((key == KEY0_PRES || key == KEY1_PRES) && (task2_task_handler != NULL))
    		{
    			printf("任务通知模拟消息邮箱,发送的键值为:%d\r\n",key);
    			xTaskNotify(task2_task_handler, key, eSetValueWithOverwrite);
    		}
    		else if(key == KEY2_PRES)
    		{
    			printf("将bit0位置1\r\n");
    			xTaskNotify(task3_task_handler, EVENTBIT_0, eSetBits);
    		}
    		else if(key == WKUP_PRES)
    		{
    			printf("将bit1位置1\r\n");
    			xTaskNotify(task3_task_handler, EVENTBIT_1, eSetBits);
    		}
    		vTaskDelay(10);
    	}
    }
    
  • 任务二:接收消息邮箱任务通知值:

    void task2(void* pvParamter)
    {	
    	uint32_t noyify_val = 0;
    	
    	while(1)
    	{
    		xTaskNotifyWait(0, 0xFFFFFFFF, &noyify_val, portMAX_DELAY);
    		switch(noyify_val)
    		{
    			case KEY0_PRES:
    			{
    				printf("接收到的通知值为:%d\r\n",noyify_val);
    				break;
    			}
    			case KEY1_PRES:
    			{
    				printf("接收到的通知值为:%d\r\n",noyify_val);
    				break;
    			}
    			default:
    				break;			
    		}
    		vTaskDelay(10);
    	}
    }
    
  • 任务三:接收事件标志组任务通知值:

    void task3(void* pvParamter)
    {	
    	uint32_t noyify_val = 0;
    	uint32_t event_bit = 0;
    	
    	while(1)
    	{
    		xTaskNotifyWait(0, 0xFFFFFFFF, &noyify_val, portMAX_DELAY);
    		
    		if(noyify_val & EVENTBIT_0)
    		{
    			event_bit |= EVENTBIT_0;
    		}
    		if(noyify_val & EVENTBIT_1)
    		{
    			event_bit |= EVENTBIT_1;
    		}
    		if(event_bit == (EVENTBIT_0 | EVENTBIT_1))
    		{
    			printf("任务通知模拟事件标志组接收成功!\r\n");
    			event_bit = 0;
    		}
    		
    		vTaskDelay(10);
    	}
    }
    
  • 实验结果:
    在这里插入图片描述

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值