• 【FreeRTOS】内核查找最高优先级就绪任务


    查找最高优先级就绪任务

    FreeRTOS\Source\tasks.c

    #if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 )
    
    /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is
     * performed in a generic way that is not optimised to any particular
     * microcontroller architecture. */
    
    /* uxTopReadyPriority holds the priority of the highest priority ready
     * state task. */
        #define taskRECORD_READY_PRIORITY( uxPriority ) \
        {                                               \
            if( ( uxPriority ) > uxTopReadyPriority )   \
            {                                           \
                uxTopReadyPriority = ( uxPriority );    \
            }                                           \
        } /* taskRECORD_READY_PRIORITY */
    
    /*-----------------------------------------------------------*/
    
        #define taskSELECT_HIGHEST_PRIORITY_TASK()                                \
        {                                                                         \
            UBaseType_t uxTopPriority = uxTopReadyPriority;                       \
                                                                                  \
            /* Find the highest priority queue that contains ready tasks. */      \
            while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopPriority ] ) ) ) \
            {                                                                     \
                configASSERT( uxTopPriority );                                    \
                --uxTopPriority;                                                  \
            }                                                                     \
                                                                                  \
            /* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \
             * the  same priority get an equal share of the processor time. */                    \
            listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \
            uxTopReadyPriority = uxTopPriority;                                                   \
        } /* taskSELECT_HIGHEST_PRIORITY_TASK */
    
    /*-----------------------------------------------------------*/
    
    /* Define away taskRESET_READY_PRIORITY() and portRESET_READY_PRIORITY() as
     * they are only required when a port optimised method of task selection is
     * being used. */
        #define taskRESET_READY_PRIORITY( uxPriority )
        #define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority )
    
    #else /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
    
    /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 1 then task selection is
     * performed in a way that is tailored to the particular microcontroller
     * architecture being used. */
    
    /* A port optimised version is provided.  Call the port defined macros. */
        #define taskRECORD_READY_PRIORITY( uxPriority )    portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority )
    
    /*-----------------------------------------------------------*/
    
        #define taskSELECT_HIGHEST_PRIORITY_TASK()                                                  \
        {                                                                                           \
            UBaseType_t uxTopPriority;                                                              \
                                                                                                    \
            /* Find the highest priority list that contains ready tasks. */                         \
            portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority );                          \
            configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 ); \
            listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) );   \
        } /* taskSELECT_HIGHEST_PRIORITY_TASK() */
    
    /*-----------------------------------------------------------*/
    
    /* A port optimised version is provided, call it only if the TCB being reset
     * is being referenced from a ready list.  If it is referenced from a delayed
     * or suspended list then it won't be in a ready list. */
        #define taskRESET_READY_PRIORITY( uxPriority )                                                     \
        {                                                                                                  \
            if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ ( uxPriority ) ] ) ) == ( UBaseType_t ) 0 ) \
            {                                                                                              \
                portRESET_READY_PRIORITY( ( uxPriority ), ( uxTopReadyPriority ) );                        \
            }                                                                                              \
        }
    
    #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */

    查找机制有两种:通用方法和基于特定处理器架构的优化方法

    通用方法倒序遍历优先级链表,找出置位的最高优先级标志,进而拿到最高优先级就绪任务的控制块

    优化方法使用的是处理器支持的计算前导零指令 clz

    计算前导零

    FreeRTOS\Source\portable\GCC\ARM_CM4F\portmacro.h

    __attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
    {
        uint8_t ucReturn;
        __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
        return ucReturn;
    }

    汇编代码说明:

    __asm:c内嵌汇编
    volatile:禁用编译器优化
    "clz %0, %1":汇编代码模板,0%对应第一个参数(ucReturn),1%对应第二个参数(ulBitmap)
    "=r" ( ucReturn ):输出操作数,=r操作数使用通用寄存器
    "r" ( ulBitmap ):输入操作数,r操作数使用通用寄存器
    "memory":寄存器
     
     
     
  • 相关阅读:
    浅析Go中的MPG模式(一)
    panic: assignment to entry in nil map
    Golang 新手可能会踩的 50 个坑
    小刘的go面试题
    go 单元测试整理
    go test 测试单个文件和测试单个函数
    mac pro锁屏后没有声音了怎么处理
    go json返回时间字符串处理time.Time类型
    php求一个字符串中不重复的最长子串
    业务订单号生成算法,每秒50W左右,不同机器保证不重复,包含日期可读性好
  • 原文地址:https://www.cnblogs.com/skullboyer/p/16193428.html
Copyright © 2020-2023  润新知