908-FreeRTOS202212‐xTaskNotifyWait() 与 xTaskNotifyWaitIndexed()

cpp 复制代码
#define xTaskNotifyWait( ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait ) \
    	xTaskGenericNotifyWait( tskDEFAULT_INDEX_TO_NOTIFY, ( ulBitsToClearOnEntry ), ( ulBitsToClearOnExit ), ( pulNotificationValue ), ( xTicksToWait ) )

#define xTaskNotifyWaitIndexed( uxIndexToWaitOn, ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait ) \
    	xTaskGenericNotifyWait( ( uxIndexToWaitOn ), ( ulBitsToClearOnEntry ), ( ulBitsToClearOnExit ), ( pulNotificationValue ), ( xTicksToWait ) )


/*-----------------------------------------------------------*/

#if ( configUSE_TASK_NOTIFICATIONS == 1 )
	/* 返回值  pdTRUE:等待任务通知成功  pdFALSE:等待任务通知失败  */
	BaseType_t xTaskGenericNotifyWait(	UBaseType_t 	uxIndexToWait,		/* 任务通知数组的索引值(任务通知相关数组下标) */	
                                      	uint32_t 	ulBitsToClearOnEntry,	/* 等待前指定清零的任务通知通知值比特位 */
                                       	uint32_t 	ulBitsToClearOnExit,		/* 成功等待后指定清零的任务通知通知值比特位 */
                                       	uint32_t *	pulNotificationValue,	/* 要获取的通知值(队列消息或者事件组) */
                                       	TickType_t 	xTicksToWait )		/* 阻塞状态下等待接收通知的最长时间 */
    	{
		BaseType_t xReturn;
		
		/* 数组越界检测 */
        	configASSERT( uxIndexToWait < configTASK_NOTIFICATION_ARRAY_ENTRIES );

        	taskENTER_CRITICAL();
        	{
            		/* Only block if a notification is not already pending. */  	/*仅当通知尚未挂起时阻止*/
			/* 若不为等待接收通知状态,说明其他任务没有发送通知给该任务. 如果设置了超时时间,则任务需要进入阻塞态 */
            		if( pxCurrentTCB->ucNotifyState[ uxIndexToWait ] != taskNOTIFICATION_RECEIVED )
            		{
                		/* Clear bits in the task's notification value as bits may get set  by the notifying task or interrupt.  
					This can be used to clear the value to zero. */
				/* 等待通知前清除任务通知值中的位,因为通知任务或中断可能会设置位。 这可用于将值清除为零。 */
                		pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] &= ~ulBitsToClearOnEntry;

                		/* Mark this task as waiting for a notification. */
				/* 设置任务通知的状态为等待通知状态 */
                		pxCurrentTCB->ucNotifyState[ uxIndexToWait ] = taskWAITING_NOTIFICATION;

				/* 如果允许阻塞 */
                		if( xTicksToWait > ( TickType_t ) 0 )
                		{
					/* 设置任务通知的状态为等待通知状态 */
                    			prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE );
                    			traceTASK_NOTIFY_WAIT_BLOCK( uxIndexToWait );

                    			/* All ports are written to allow a yield in a critical section (some will yield immediately, others wait until the critical section exits) - but it is not something that application code should ever do. */
					/*所有端口都被编写为允许在临界段中进行屈服(有些端口将立即屈服,另一些端口则等待关键部分退出),但这不是应用程序代码应该做的事情*/
					/* 悬起 PendSv中断,准备进行任务切换*/
                    			portYIELD_WITHIN_API();
                		}
                		else
                		{
                    			mtCOVERAGE_TEST_MARKER();
                		}
            		}
            		else
            		{
                		mtCOVERAGE_TEST_MARKER();
            		}
        	}
        	taskEXIT_CRITICAL();
		
		/* 如果该任务被阻塞了,解除阻塞后继续从这往下执行 */
        	taskENTER_CRITICAL();
        	{
            		traceTASK_NOTIFY_WAIT( uxIndexToWait );
			/* 当代码执行到这里可能是以下三种情况:
               		1.前面的判断不成立,一进来就有通知  任务不需要进入阻塞 
               		2.前面的判断成立,任务进入阻塞,但是有其他任务向该任务发送通知并将该任务唤醒 
               		3.前面的判断成立,任务进入阻塞,但是阻塞超时任务被迫唤醒 */

            		if( pulNotificationValue != NULL )
            		{
                		/* Output the current notification value, which may or may not have changed. */
				/* 输出当前通知值,该值可能已更改,也可能未更改. 
					未更改说明是任务是超时被唤醒的此时虽然能获取通知值, 但是通知值是上次的,其实是获取通知值失败的 */
                		*pulNotificationValue = pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ];
            		}

            		/* If ucNotifyValue is set then either the task never entered the blocked state (because a notification was already pending) or the task unblocked because of a notification.  
				Otherwise the task unblocked because of a timeout. */
			/*如果设置了ucNotifyValue,则任务从未进入阻止状态(因为通知已挂起),或者由于通知到达而取消任务阻塞。
				否则,由于超时,任务被取消阻止*/   
            		/* 如果任务通知的状态还不等于等待接收通知状态的话, 说明任务还是没有接收到通知任务只不过是超时被唤醒*/
            		if( pxCurrentTCB->ucNotifyState[ uxIndexToWait ] != taskNOTIFICATION_RECEIVED )
            		{
                		/* A notification was not received. */	/*未收到通知*/
                		xReturn = pdFALSE;
            		}
            		else
            		{
                		/* A notification was already pending or a notification was received while the task was waiting. */
				/*通知已挂起,或者在任务等待时收到通知*/
				/* 在成功接收到通知后将通知值的指定比特位清零 */
                		pxCurrentTCB->ulNotifiedValue[ uxIndexToWait ] &= ~ulBitsToClearOnExit;
                		xReturn = pdTRUE;
            		}
			/* 不论接收通知成功或者失败都将任务通知的状态标记为未等待通知状态*/
            		pxCurrentTCB->ucNotifyState[ uxIndexToWait ] = taskNOT_WAITING_NOTIFICATION;
        	}
        	taskEXIT_CRITICAL();

        	return xReturn;
    	}

#endif /* configUSE_TASK_NOTIFICATIONS */
/*-----------------------------------------------------------*/
相关推荐
猫头虎3 小时前
如何在浏览器里体验 Windows在线模拟器:2026最新在线windows模拟器资源合集与技术揭秘
运维·网络·windows·系统架构·开源·运维开发·开源软件
古城小栈5 小时前
Rust 网络请求库:reqwest
开发语言·网络·rust
qq_316837759 小时前
IP网段冲突 配置指定ip使用指定的网络接口发送,而不经过默认网关
服务器·网络·tcp/ip
布史9 小时前
Tailscale虚拟私有网络指南
linux·网络
枷锁—sha10 小时前
彻底解决 Google Gemini 报错:异常流量与 IP 地址冲突排查指南
网络·网络协议·tcp/ip
Xの哲學10 小时前
深入剖析Linux文件系统数据结构实现机制
linux·运维·网络·数据结构·算法
-To be number.wan10 小时前
经典真题精讲|2010年408统考第34题:文件传输最少需要多久?
网络·计算机网络
知乎的哥廷根数学学派11 小时前
基于多尺度注意力机制融合连续小波变换与原型网络的滚动轴承小样本故障诊断方法(Pytorch)
网络·人工智能·pytorch·python·深度学习·算法·机器学习
好多渔鱼好多12 小时前
【流媒体协议】RTSP / RTP / RTCP 协议全景介绍
网络·网络协议·rtp·rtsp·rtcp·ipc摄像头
映秀小子12 小时前
Wireshark加减显示列
网络·测试工具·wireshark