903-FreeRTOS202212‐xTaskNotify() 与 xTaskNotifyIndexed()函数

 高清图片可查看附件PDF

903-FreeRTOS202212‐xTaskNotify() 与 xTaskNotifyIndexed()函数_第1张图片

#define xTaskNotify( xTaskToNotify, ulValue, eAction ) \
    	xTaskGenericNotify( ( xTaskToNotify ), ( tskDEFAULT_INDEX_TO_NOTIFY ), ( ulValue ), ( eAction ), NULL )

#define xTaskNotifyIndexed( xTaskToNotify, uxIndexToNotify, ulValue, eAction ) \
    	xTaskGenericNotify( ( xTaskToNotify ), ( uxIndexToNotify ), ( ulValue ), ( eAction ), NULL )

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

#if ( configUSE_TASK_NOTIFICATIONS == 1 )

	BaseType_t xTaskGenericNotify( 	TaskHandle_t 	xTaskToNotify,			/* 要通知的任务的句柄 */
                                   	UBaseType_t 	uxIndexToNotify,			/* 任务通知数组的索引值(任务通知相关数组下标,默认为0,使用通知数组第一个元素) */			
                                   	uint32_t 	ulValue,				/* 要传递的通知值 */
                                   	eNotifyAction eAction,				/* 指定通知的动作 */
                                   	uint32_t * 	pulPreviousNotificationValue )	/* 指向存储上一个通知值的变量的指针,如果不需要回传上一个通知值,则可以传递NULL */
    	{
        	TCB_t * pxTCB;
        	BaseType_t xReturn = pdPASS;
        	uint8_t ucOriginalNotifyState;

        	configASSERT( uxIndexToNotify < configTASK_NOTIFICATION_ARRAY_ENTRIES );
        	configASSERT( xTaskToNotify );
        	pxTCB = xTaskToNotify;

        	taskENTER_CRITICAL();
        	{
			/* 判断是否需要通知前的通知值 */
            		if( pulPreviousNotificationValue != NULL )
            		{
				/* 获取发送通知前的通知值 */
                		*pulPreviousNotificationValue = pxTCB->ulNotifiedValue[ uxIndexToNotify ];
            		}

			/* 记录发送通知前的任务通知状态 */
            		ucOriginalNotifyState = pxTCB->ucNotifyState[ uxIndexToNotify ];

			/* 将负责接收直达任务通知的 TCB(任务控制块)中 的任务通知状态 设置为 已收到任务通知态 */
            		pxTCB->ucNotifyState[ uxIndexToNotify ] = taskNOTIFICATION_RECEIVED;

            		switch( eAction )
            		{
				/* 模拟事件组:将通知值的某些位置 1 */
                		case eSetBits:
                    			pxTCB->ulNotifiedValue[ uxIndexToNotify ] |= ulValue;
                    		break;

				/* 模拟计数型信号量:将通知值 + 1 */
                		case eIncrement:
                    			( pxTCB->ulNotifiedValue[ uxIndexToNotify ] )++;
                    		break;

				/* 模拟队列:覆写通知值 */
                		case eSetValueWithOverwrite:
                    			pxTCB->ulNotifiedValue[ uxIndexToNotify ] = ulValue;
                    		break;

				/* 模拟队列:(不覆盖)写通知值 */
                		case eSetValueWithoutOverwrite:
					/* 如果不处于收到任务通知状态,说明通知值已被读走,可以写入*/
                    			if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED )
                    			{
                        			pxTCB->ulNotifiedValue[ uxIndexToNotify ] = ulValue;
                    			}
                    			else
                    			{
                        			/* The value could not be written to the task. */
						/*无法将值写入任务*/
                        			xReturn = pdFAIL;	/* 通知值未被读走,不能覆写 */
                    			}

                    		break;
					
				/* 只将任务标记为等待接收通知状态, 并不修改通知值 */
                		case eNoAction:	

                    			/* The task is being notified without its notify value being updated. */
					/*正在通知任务,但未更新其通知值*/
                    		break;

                		default:

                    			/* Should not get here if all enums are handled. Artificially force an assert by testing a value the compiler can't assume is const. */
					/*如果处理了所有枚举,则不应到达此处。通过测试编译器不能假定为常量的值来人为地强制断言*/
                    			configASSERT( xTickCount == ( TickType_t ) 0 );

                    		break;
            		}

            		traceTASK_NOTIFY( uxIndexToNotify );

            		/* If the task is in the blocked state specifically to wait for a notification then unblock it now. */
			/*如果任务处于阻止状态,专门用于等待通知,则立即取消阻止*/
            		if( ucOriginalNotifyState == taskWAITING_NOTIFICATION )		 /* 如果在此之前,任务因等待任务通知而被阻塞(该任务为等待通知状态),则现在解除阻塞 */
            		{
				/* 将任务从所在任务状态链表(延时/挂起链表)中移出 */
                		listREMOVE_ITEM( &( pxTCB->xStateListItem ) );

				/* 将任务添加到就绪任务链表中 */
                		prvAddTaskToReadyList( pxTCB );

                		/* The task should not have been on an event list. */
				/*该任务不应出现在事件链表中*/
                		configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL );

                		#if ( configUSE_TICKLESS_IDLE != 0 )
                		{
                    			/* If a task is blocked waiting for a notification then xNextTaskUnblockTime might be set to the blocked task's time out time.  
						If the task is unblocked for a reason other than a timeout xNextTaskUnblockTime is normally left unchanged, because it will automatically get reset to a new value when the tick count equals xNextTaskUnblockTime.  
						However if tickless idling is used it might be more important to enter sleep mode at the earliest possible time - so reset xNextTaskUnblockTime here to ensure it is updated at the earliest possible time. */
					/*如果任务被阻止等待通知,则xNextTaskUnblockTime可能会设置为被阻止任务的超时时间。
						如果由于超时以外的原因取消阻止任务,xNextTaskUnblockTime通常保持不变,因为当勾号计数等于xNextTTaskUnblocktime时,它将自动重置为新值。
						然而,如果使用了无障碍空转,那么尽早进入睡眠模式可能更重要——因此,请在此处重置xNextTaskUnblockTime,以确保它在尽早更新*/
                    			prvResetNextTaskUnblockTime();	/* 更新下一个解除阻塞的任务 */
                		}
                		#endif

				/* 有任务解除阻塞后,就应该判断是否需要进行任务切换 */
                		if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )
                		{
                    			/* The notified task has a priority above the currently executing task so a yield is required. */
					/*通知的任务的优先级高于当前执行的任务,因此需要切换*/
                    			taskYIELD_IF_USING_PREEMPTION();	/* 悬起 PendSV中断,准备进行任务切换 */
                		}
                		else
                		{
                    			mtCOVERAGE_TEST_MARKER();
                		}
            		}
            		else
            		{
                		mtCOVERAGE_TEST_MARKER();
            		}
        	}
        	taskEXIT_CRITICAL();

        	return xReturn;
    	}

你可能感兴趣的:(FreeRTOS,学习手记,09,-,直达任务通知,c语言,数据结构)