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 */
/*-----------------------------------------------------------*/
相关推荐
dog2503 分钟前
从 Kelly-NUM 到时延感知 AIMD 拥塞控制算法
网络
网络小江20 分钟前
组网第27课:ARP 的能与不能——免费 ARP、代理 ARP 与 ARP 欺骗
服务器·网络·网络安全·负载均衡·免费arp
FY@-@39 分钟前
VMware ESXi 7.0 实验全记录:嵌套安装 → 网络配置 → 存储 → Windows 10 虚拟机部署
运维·网络·windows·云计算
ynchyong1 小时前
IPv4 时代的地址冲突检测
网络·ipv4·冲突检测·免费arp·无敌apr·announcemnet
ONLYOFFICE1 小时前
ONLYOFFICE 10.0:深入了解最新的 40 项安全修复
网络·安全
上海云盾-高防顾问1 小时前
边缘验签是什么
运维·服务器·网络
CH_Qing2 小时前
lspci 常见debug 命令
网络
天南散修2 小时前
《802.11-2024》第08讲 · 聚合与块确认:把「一次一帧」变成「一次一批」
linux·网络·wifi·802.11
企业解惑小能手-域智盾系统2 小时前
终端安全管理软件怎么选?终端安全管理不是“装个客户端”:从底层逻辑看企业怎么选
服务器·网络·安全·域智盾软件
济南凡维2 小时前
智能相机 VS 工业相机:机器视觉选型一次讲透
网络·数码相机·视觉检测