【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":寄存器
__asm volatile:用法详见 https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
再牛逼的梦想也架不住傻逼似的坚持
分类:
FreeRTOS
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧