前言
- 通过查看uCOS-III,获取最高优先级,不再使用查找【判定表】的方式获取,获取的方法与uCOS-II 有一定的区别,并且可以让【优先级】的最大个数,不再限制为:64,可以更大
两个表
-
OSRdyList
就绪表:链表的数组,数组的个数是优先级最大个数,怎么理解呢?也就是个数等于uCOS-III 支持的最大优先级个数,这个格式并不是写死的,可以配置更改。如64个,256个,甚至更多,注意占用的RAM将会更多。 - 因为uCOS-III 使用了链表,也就是多个任务可以使用同一个【任务优先级】,也就是【任务个数】不再受【任务优先级个数】的限制,如果RAM够多,任务个数因为挂在【链表】上,不受限制
/* READY LIST ------------------------------- */
OS_EXT OS_RDY_LIST OSRdyList[OS_CFG_PRIO_MAX];
/* Table of tasks ready to run */
- 优先级表
OSPrioTbl
,这个表的个数是为了快速获取 最高优先级,个数不是优先级最大个数,而是使用【位图】的方式,一个位代表一个优先级,如32位的MCU上,32个优先级,就是一个32位值,64个优先级,就是两个 32位值,一次类推。 - 一个优先级占一位
CPU_DATA OSPrioTbl[OS_PRIO_TBL_SIZE];
/* Declare the array local to this file to allow for ... */
获取最高优先级
- 在RTOS中,高优先级的任务(优先级的值最小,优先级越高)有限运行
- 每创建(初始化)一个任务,就会在 优先级表
OSPrioTbl
(是一个数组)中置位,也就是按:CPU的位长,如STM32这种32位的MCU上,按32分组,先从优先级表OSPrioTbl
数组索引为【0】开始,获取不为0的值,找到优先级最高的【组】,因为只要这个值不为0,说明有个优先级存在(置过其中的某位或某些位) - 在获取不为0的【组】中 【首个1】出现的位置,这里uCOS-III 与 uCOS-II 处理上不同,获取的方法不同
- uCOS-II 初始化线程时: 分组中,最高位 (31、15、7位)是最高优先级, uCOS-II(0位)是最高优先级,这个在任务初始化,插入链表时做了处理
void OS_PrioInsert (OS_PRIO prio)
{
CPU_DATA bit;
CPU_DATA bit_nbr;
OS_PRIO ix;
ix = prio / DEF_INT_CPU_NBR_BITS;
bit_nbr = (CPU_DATA)prio & (DEF_INT_CPU_NBR_BITS - 1u);
bit = 1u;
bit <<= (DEF_INT_CPU_NBR_BITS - 1u) - bit_nbr; /* 注意,这里与uCOS-II不同,如分组32,本来是9,不是 1<<9,而是 1<< (31-9),也就是 1<<22,翻转了一下,这样保证最高位(31位)是最高的优先级 */
OSPrioTbl[ix] |= bit;
}
- 由于uCOS-III 的分组中的最高位是【最高优先级】,所以获取的方法如下:
OS_PRIO OS_PrioGetHighest (void)
{
CPU_DATA *p_tbl;
OS_PRIO prio;
prio = (OS_PRIO)0;
p_tbl = &OSPrioTbl[0];
while (*p_tbl == (CPU_DATA)0) { /* Search the bitmap table for the highest priority */
prio += DEF_INT_CPU_NBR_BITS; /* Compute the step of each CPU_DATA entry */
p_tbl++;
}
prio += (OS_PRIO)CPU_CntLeadZeros(*p_tbl); /* Find the position of the first bit set at the entry */
return (prio);
}
- 其中的:
CPU_CntLeadZeros
实现可以使用平台(如ARM平台)的相关指令实现 - STM32上 实现方法如下:
CPU_CntLeadZeros
CLZ R0, R0 ; Count leading zeros
BX LR
- 这是因为,最高优先级放在高位,第一个出现1的位置索引,等于前面全部是0的个数(前导0个数)
uCOS-III 官方优先级的描述
- 8位分组(一般是CPU 位长),可以配置
- 16 位分组(一般是CPU 位长),可以配置
- 32位分组(一般是CPU 位长),可以配置
- 注意这里没有提 :优先级最大个数的【上限】,理论上只会增加调度的时间与占用更多的内存(RAM)资源,也就是可以根据需要设置,如32、64、256、1024,等等
小结
- 了解了uCOS-III 任务优先级管理的方法,与uCOS-II 有区别,并且uCOS-III 支持更多的优先级个数,可以不受最大限制
- uCOS-III 就绪表采用的是【链表数组】,这样支持任务【相同优先级】,这样运行创建相同优先级的任务,相同优先级的任务,挂在相同优先级就绪表的链表上,理论上,最大创建的任务数量不再受限制,并且运行创建相同优先级的任务,不再像uCOS-II 那样,强制每个任务需要不同的优先级,从而影响任务的【最大个数】