• 【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":寄存器
     
     
     
  • 相关阅读:
    centos下vsftpd不能显示文件,不能创建文件及文件夹
    PHP过滤常用标签的正则表达式
    px、dp、sp、mm、in、pt这些单位有什么区别?
    Android Studio升级后报 method not found: 'runProguard'的错误
    Android应用签名
    Android技巧小结之新旧版本Notification
    java中 synchronized 的使用,确保异步执行某一段代码。
    android开发笔记(二)导入项目到eclipse和另一个项目
    android开发笔记(一)Android studio 输入法
    这个算asp.net的一个bug吗?
  • 原文地址:https://www.cnblogs.com/skullboyer/p/16193428.html
Copyright © 2020-2023  润新知