当前位置: 首页 > news >正文

freeRTOS 互斥量优先级继承机制函数实现xQueueGenericReceive()

  一 接收到互斥量时,将互斥量的任务持有者赋值为当前任务

以下为xQueueGenericReceive()函数接收互斥量,互斥量不为空(未被别的任务持有),去除互斥量,并且将互斥量的持有者赋值为当前任务,紫色字体部分

if( uxMessagesWaiting > ( UBaseType_t ) 0 )
            {
                /* Remember the read position in case the queue is only being
                peeked. */
                pcOriginalReadPosition = pxQueue->u.pcReadFrom;

                prvCopyDataFromQueue( pxQueue, pvBuffer );

                if( xJustPeeking == pdFALSE )
                {
                    traceQUEUE_RECEIVE( pxQueue );

                    /* Actually removing data, not just peeking. */
                    pxQueue->uxMessagesWaiting = uxMessagesWaiting - 1;

                    #if ( configUSE_MUTEXES == 1 )
                    {
                        if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
                        {
                            /* Record the information required to implement
                            priority inheritance should it become necessary. */
           pxQueue->pxMutexHolder = ( int8_t * ) pvTaskIncrementMutexHeldCount(); /*lint !e961 Cast is not redundant as TaskHandle_t is a typedef. */
                        }
                        else
                        {
                            mtCOVERAGE_TEST_MARKER();
                        }
                    }
                    #endif /* configUSE_MUTEXES */

二 接收任务接收不到信号量时,提升互斥量持有者任务的优先级

还是xQueueGenericReceive()函数接收互斥量,互斥量为空(被别的任务持有),而且时间未超时时,就是第一次尝试接收时,进行优先级继承,紫色字体函数

 /* Update the timeout state to see if it has expired yet. */
        if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
        {
            if( prvIsQueueEmpty( pxQueue ) != pdFALSE )
            {
                traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );

                #if ( configUSE_MUTEXES == 1 )
                {
                    if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
                    {
                        taskENTER_CRITICAL();
                        {
                            vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );
                        }
                        taskEXIT_CRITICAL();
                    }
                    else
                    {
                        mtCOVERAGE_TEST_MARKER();
                    }
                }
                #endif

                vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
                prvUnlockQueue( pxQueue );
                if( xTaskResumeAll() == pdFALSE )
                {
                    portYIELD_WITHIN_API();
                }
                else
                {
                    mtCOVERAGE_TEST_MARKER();
                }
            }

三 最终实现函数TaskPriorityInherit()解析

void vTaskPriorityInherit( TaskHandle_t const pxMutexHolder )
    {
    TCB_t * const pxTCB = ( TCB_t * ) pxMutexHolder;

       
        if( pxMutexHolder != NULL )
        {
            
            if( pxTCB->uxPriority < pxCurrentTCB->uxPriority )
            {
                   /* Adjust the mutex holder state to account for its new
                priority.  Only reset the event list item value if the value is
                not    being used for anything else. */
                if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) //获取互斥量持有任务的节点辅助值,用于迁移到新优先级就绪链表时的排序
                {
                    listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ); //设定互斥量持有任务的节点辅助值,用于迁移到新优先级就绪链表时的排序
                }
                else
                {
                    mtCOVERAGE_TEST_MARKER();
                }

                /* If the task being modified is in the ready state it will need
                to be moved into a new list. */
                if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xStateListItem ) ) != pdFALSE )//互斥量持有者任务现在处于就绪列表
                {
                    if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 )//将互斥量持有者任务从其所在就绪列表移除
                    {
                        taskRESET_READY_PRIORITY( pxTCB->uxPriority );
                    }
                    else
                    {
                        mtCOVERAGE_TEST_MARKER();
                    }

                    /* Inherit the priority before being moved into the new list. */
                    pxTCB->uxPriority = pxCurrentTCB->uxPriority;//将互斥量持有者任务优先级赋值为当前任务优先级
                    prvAddTaskToReadyList( pxTCB );//将互斥量持有者任务移到相应优先级列表
                }
                else
                {
                    /* Just inherit the priority. */
                    pxTCB->uxPriority = pxCurrentTCB->uxPriority;  //将互斥量持有者任务优先级赋值为当前任务优先级,只进行优先级上升级,因为现在不在就绪列表中
                }

                traceTASK_PRIORITY_INHERIT( pxTCB, pxCurrentTCB->uxPriority );
            }
            else
            {
                mtCOVERAGE_TEST_MARKER();
            }
        }
        else
        {
            mtCOVERAGE_TEST_MARKER();
        }
    }
 

相关文章:

  • C++课设:实现简易文件加密工具(凯撒密码、异或加密、Base64编码)
  • python版若依框架开发:集成Dash应⽤
  • Python爬虫实战:研究Unirest库相关技术
  • GIC700组件
  • 复变函数中的正弦函数:解析与可视化
  • Spring——Spring相关类原理与实战
  • 桑荫不徙 · 时之沙 | 在筛选与共生之间,向轻盈之境远航
  • 11.无重复字符的最长子串
  • 电路图识图基础知识-电动机制动控制电路(十八)
  • Java 8 Stream API 入门到实践详解
  • 人工智能赋能高中学科教学的应用与前景研究
  • 【Qt】背景知识 + 环境搭建
  • Xilinx FPGA MIPI DSI TX Subsystem 仿真笔记
  • 【Langchain】构建RAG基本流程
  • QT使用AES加解密,openssl及QCA问题记录
  • 综合笔试知识点
  • 文字转语音
  • 关于汉语普通话元音音位最好归纳为几个的问题
  • 能上Nature封面的idea!强化学习+卡尔曼滤波
  • 【Electron】应用打包教程(包含 C++ 后端 + 前端)
  • 烟台建设工程信息网站/产品的推广及宣传思路
  • 东营市报名系统网站设计公司/百度首页推荐关不掉吗
  • 做批发网站有哪些/百度指数教程
  • 做王境泽表情的网站/个人怎么做百度竞价
  • 郑州专门做喷绘安装的网站/免费行情网站的推荐理由
  • 鹏鹞网站页面代码/seo公司 杭州