vTaskPrioritySet和uxTaskPriorityGet源码分析

25 篇文章 0 订阅
15 篇文章 1 订阅

URL: http://patonwang.blog.163.com/blog/static/1228953120128160496850/

/*-----------------------------------------------------------
 *pxTask:被修改优先级的任务句柄(即目标任务)——参考xTaskCreate() API
 *函数的参数pxCreatedTask 以了解如何得到任务句柄方面的信息。
 *任务可以通过传入NULL 值来修改自己的优先级。
 *uxNewPriority:目标任务将被设置到哪个优先级上。如果设置的值超过了最大可用优
 *先级(configMAX_PRIORITIES – 1),则会被自动封顶为最大值。常
 *量configMAX_PRIORITIES 是在FreeRTOSConfig.h 头文件中设置
 *的一个编译时选项。
 void vTaskPrioritySet( 
       xTaskHandle pxTask, --需要设置优先级的任务。当传递NULL,将设置调用任务的优先级 
       unsigned portBASE_TYPE uxNewPriority );--任务需要设置的优先级
    例子: 
 void vAFunction( void )
 {
 xTaskHandle xHandle;
     // 创建任务,准备处理
     xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
     // 使用其句柄来提高创建任务的优先级
     vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );
     // 使用NULL处理,来提高优先级到同一个值
     vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
 }
注:设置INCLUDE_vTaskPrioritySet为1,才能使用此函数*/
#if ( INCLUDE_vTaskPrioritySet == 1 )

    void vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority )
    { 
/*改变任务优先级*/
    tskTCB *pxTCB;
    unsigned portBASE_TYPE uxCurrentPriority;
    portBASE_TYPE xYieldRequired = pdFALSE;

        configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) );

        /* Ensure the new priority is valid. 保证新设置的优先级是有效的*/
        if( uxNewPriority >= configMAX_PRIORITIES )
        {
            uxNewPriority = configMAX_PRIORITIES - ( unsigned portBASE_TYPE ) 1U;
        }

        taskENTER_CRITICAL(); /*不能有中断打断*/ 
        {
            if( pxTask == pxCurrentTCB )
            {
                pxTask = NULL;
            }

            /* If null is passed in here then we are changing the priority of the calling function. 如果传入的是NULL值,则改变正在调用此函数的优先级*/
            pxTCB = prvGetTCBFromHandle( pxTask );

            traceTASK_PRIORITY_SET( pxTCB, uxNewPriority );

            #if ( configUSE_MUTEXES == 1 ) /*得到最原始的优先级*/ 
            {
                uxCurrentPriority = pxTCB->uxBasePriority;
            }
            #else
            {
                uxCurrentPriority = pxTCB->uxPriority;
            }
            #endif

            if( uxCurrentPriority != uxNewPriority )
            {
                /* The priority change may have readied a task of higher
                priority than the calling task. */
                if( uxNewPriority > uxCurrentPriority ) /*如果优先级大于目前的优先级,则需要重新调度*/ 
                {
                    if( pxTask != NULL )
                    {
                        /* The priority of another task is being raised.  If we
                        were raising the priority of the currently running task
                        there would be no need to switch as it must have already
                        been the highest priority task. */
                        xYieldRequired = pdTRUE;
                    }
                }
                else if( pxTask == NULL ) /*如果是当前任务,也需要重新调度*/ 
                {
                    /* Setting our own priority down means there may now be another
                    task of higher priority that is ready to execute. */
                    xYieldRequired = pdTRUE;
                }

 

                #if ( configUSE_MUTEXES == 1 )
                {
                    /* Only change the priority being used if the task is not
                    currently using an inherited priority. 如果任务使用的是继承
     优先级而不是当前的base优先级,那么需要改变任务现行的优先级
     以及任务的base优先级*/
                    if( pxTCB->uxBasePriority == pxTCB->uxPriority )
                    {
                        pxTCB->uxPriority = uxNewPriority;
                    }

                    /* The base priority gets set whatever. base优先级也要改变*/
                    pxTCB->uxBasePriority = uxNewPriority;
                }
                #else
                {
                    pxTCB->uxPriority = uxNewPriority; /*否则只改变运行时用的优先级即可*/ 
                }
                #endif

    /*重新设置任务在事件链表里面的等待时间,根据优先级的高低设置itemValue值*/ 
                listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( configMAX_PRIORITIES - ( portTickType ) uxNewPriority ) );

                /* If the task is in the blocked or suspended list we need do
                nothing more than change it's priority variable. However, if
                the task is in a ready list it needs to be removed and placed
                in the queue appropriate to its new priority. 如果任务被阻塞或者被
    挂起,我们仅仅改变它们的优先级就可以了,但是如果任务是在就绪表里,
    那么我们需要从目前对应的优先级链表里面移除,而添加进想应的就绪链表*/
                if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxCurrentPriority ] ), &( pxTCB->xGenericListItem ) ) )
                {
                    /* The task is currently in its ready list - remove before adding
                    it to it's new ready list.  As we are in a critical section we
                    can do this even if the scheduler is suspended. */
                    vListRemove( &( pxTCB->xGenericListItem ) );
                    prvAddTaskToReadyQueue( pxTCB );
                }
    /*改变优先级后,如果优先级高或者改变的是当前任务优先级,都需要进行任务切换*/ 
                if( xYieldRequired == pdTRUE )
                {
                    portYIELD_WITHIN_API();
                }
            }
        }
        taskEXIT_CRITICAL();
    }

#endif

/******************************************************************************************/

/*查询一个任务的优先级,这里的任务可能是当前运行的任务,也可能是其它的任务,而参数就是指向任务控制块TCB的一个指针*/

#if ( INCLUDE_uxTaskPriorityGet == 1 )

    unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask )
    { 

    tskTCB *pxTCB;
    unsigned portBASE_TYPE uxReturn;

        taskENTER_CRITICAL(); /*进入临界区,关中断*/
        {
            /* If null is passed in here then we are changing the
            priority of the calling function. 如果传递的参数是NULL就表示是查询当前任务的优先级*/
            pxTCB = prvGetTCBFromHandle( pxTask ); /*是一个宏定义,判断是当前任务,还是其它任务*/
            uxReturn = pxTCB->uxPriority;
        }
        taskEXIT_CRITICAL(); 
/*退出临界区,开启中断*/

        return uxReturn;
    }

#endif

/****************************************************************/

#define prvGetTCBFromHandle( pxHandle )

    ( ( ( pxHandle ) == NULL ) ? ( tskTCB * ) pxCurrentTCB : ( tskTCB * ) ( pxHandle ) )

/*如果用if else来写,pxTCB = prvGetTCBFromHandle( pxTask );就如下面*/

/*

if  ( ( pxHandle ) == NULL )

{

      pxTCB =  ( tskTCB * ) pxCurrentTCB ;

}

else

{

      pxTCB =  ( tskTCB * ) ( pxHandle ) ;

}

*/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值