任务通知发送函数xTaskGenericNotify详解

#if( configUSE_TASK_NOTIFICATIONS == 1 )
    //给任务发送任务通知
    //参数为: xTaskToNotify:任务句柄 ulValue:任务通知值 eAction:任务通知更新方式 *pulPreviousNotificationValue:保存更新前的任务通知值
	BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue )
	{
		TCB_t * pxTCB;
		BaseType_t xReturn = pdPASS;
		uint8_t ucOriginalNotifyState;

		configASSERT( xTaskToNotify );
		pxTCB = ( TCB_t * ) xTaskToNotify;

		taskENTER_CRITICAL();  //进入临界区
		{
			if( pulPreviousNotificationValue != NULL )  //如果pulPreviousNotificationValue有效,说明需要保存更新前的任务通知值
			{
				*pulPreviousNotificationValue = pxTCB->ulNotifiedValue;  //保存更新前的任务通知值
			}

			ucOriginalNotifyState = pxTCB->ucNotifyState; //保存任务通知状态到ucOriginalNotifyState中,后面要用到

			pxTCB->ucNotifyState = taskNOTIFICATION_RECEIVED; //修改目前任务通知状态为taskNOTIFICATION_RECEIVED

			switch( eAction )  //eAction为任务通知更新方式
			{
				case eSetBits	:  //如果为eSetBits的话:更新接受任务通知值的一个或多个bit
					pxTCB->ulNotifiedValue |= ulValue;
					break;

				case eIncrement	:  //如果是eIncrement的话:就将任务通知值加一
					( pxTCB->ulNotifiedValue )++;
					break;

				case eSetValueWithOverwrite	:  //如果是eSetValueWithOverwrite的话:覆盖原来的任务通知值
					pxTCB->ulNotifiedValue = ulValue;
					break;

				case eSetValueWithoutOverwrite : //如果是eSetValueWithoutOverwrite的话:判断原来的任务通知值是否被处理,如果已经被处理了就更新为任务通知值
					                             //如果此前的任务通知值话没有被处理的话就标记xRenturn为pdFAIL

					if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED ) //ucOriginalNotifyState为原先的任务通知状态不等于taskNOTIFICATION_RECEIVED表示已经被处理了
					{
						pxTCB->ulNotifiedValue = 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;
			}

			traceTASK_NOTIFY(); //退出临界区

			/* If the task is in the blocked state specifically to wait for a
			notification then unblock it now. */
			if( ucOriginalNotifyState == taskWAITING_NOTIFICATION ) //根据保存的任务通知状态来判断此任务是不是因为等待而阻塞
			{
				( void ) uxListRemove( &( 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. */
					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();  //进行任务切换
				}
				else
				{
					mtCOVERAGE_TEST_MARKER();
				}
			}
			else  //如果此任务并没有阻塞就继续
			{
				mtCOVERAGE_TEST_MARKER();
			}
		}
		taskEXIT_CRITICAL(); //退出临界区

		return xReturn;
	}

#endif /* configUSE_TASK_NOTIFICATIONS */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值