908-FreeRTOS202212‐xTaskNotifyWait() 与 xTaskNotifyWaitIndexed()

908-FreeRTOS202212‐xTaskNotifyWait() 与 xTaskNotifyWaitIndexed()_第1张图片



#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 */
/*-----------------------------------------------------------*/

你可能感兴趣的:(FreeRTOS,学习手记,09,-,直达任务通知,网络)