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 分钟前
玩转Java网络编程:基于Socket的服务器和客户端开发!
java·服务器·网络
徐子元竟然被占了!!1 小时前
实验-基本ACL
网络
ftpeak2 小时前
从零开始使用 axum-server 构建 HTTP/HTTPS 服务
网络·http·https·rust·web·web app
LabVIEW开发3 小时前
LabVIEW气体污染无线监测
网络·labview·labview知识·labview功能·labview程序
error:(3 小时前
【从零到公网】本地电脑部署服务并实现公网访问(IPv4/IPv6/DDNS 全攻略)
网络·智能路由器
酷飞飞3 小时前
Python网络与多任务编程:TCP/UDP实战指南
网络·python·tcp/ip
风中的微尘4 小时前
39.网络流入门
开发语言·网络·c++·算法
hsjkdhs5 小时前
网络编程之UDP广播与粘包问题
网络·网络协议·udp
yzx9910137 小时前
接口协议全解析:从HTTP到gRPC,如何选择适合你的通信方案?
网络·人工智能·网络协议·flask·pygame
程思扬8 小时前
利用JSONCrack与cpolar提升数据可视化及跨团队协作效率
网络·人工智能·经验分享·docker·信息可视化·容器·架构