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 */
/*-----------------------------------------------------------*/
相关推荐
sadandbad18 分钟前
[vulhub靶机通关]DC-2(rbash绕过_git提权)
网络·sql·web安全·网络安全
GTgiantech34 分钟前
科普SFP 封装光模块教程
服务器·网络·数据库
0和1的舞者2 小时前
网络通信的奥秘:HTTP详解 (七)
服务器·网络·网络协议·http·okhttp·软件工程·1024程序员节
Ashlee_code2 小时前
BSS供应商:电信与金融领域的幕后支撑者
大数据·网络·金融·系统架构·跨境·金融机构·场外期权
节点小宝2 小时前
节点小宝免费版流量机制解析:点对点直连技术与备用流量设计
网络·网络协议·p2p
创业之路&下一个五年4 小时前
按照ip的转换为二进制的方式理解a\b\c类地址的边界
服务器·网络·tcp/ip
陌路204 小时前
Linux29初识网络:核心概念与分层逻辑
网络
Acrelhuang5 小时前
覆盖全场景需求:Acrel-1000 变电站综合自动化系统的技术亮点与应用
大数据·网络·人工智能·笔记·物联网
阿猿收手吧!5 小时前
【Linux网络】shutdown()与close()的区别
linux·网络
AuroraDPY8 小时前
计算机网络:基于TCP协议的自定义协议实现网络计算器功能
网络·tcp/ip·计算机网络