赞
踩
1、最多支持 64 个任务统一进行管理、调度,并给每个任务编了个号码(任务ID),当然也可扩展至256个任务,甚至更多,这里以 64 个任务为例讲解计算最高优先级任务的任务ID 计算方式。(8 x 8 个任务)
2、在 os_cfg.h 文件中有说明操作系统支持的任务数量,优先级数字越小,优先级越高。优先级: 0 ~ 63
#define OS_LOWEST_PRIO 63 /* Defines the lowest priority that can be assigned ... */
/* ... MUST NEVER be higher than 254! */
3、64 个任务分成了 8 个组(OSRdyGrp),每个组8个任务(OSRdytbl),用一个8bits 的数OSRdyGrp来表示任务组, OSRdyGrp 的哪个bit 位置1,就表示哪个组里面有任务进入了就绪态,然后再看OSRdyGrp 就知道具体是哪一个任务了
#if OS_LOWEST_PRIO <= 63u // OS_LOWEST_PRIO == 63
typedef INT8U OS_PRIO;
#else
typedef INT16U OS_PRIO;
#endif
OS_EXT OS_PRIO OSRdyGrp; /*Ready list group*/
3.1、任务编号管理图1:
----------------------------------------------------------- 图1 --------------------------------------------------------------------------------
3.2、任务编号管理图2:
----------------------------------------------------------- 图2 --------------------------------------------------------------------------------
4、最高优先级任务的任务ID 解码表 OSUnMapTbl,计算最高优先级任务的时候需要查两次这个解码表
/* ********************************************************************************************************* * PRIORITY RESOLUTION TABLE * Note: Index into table is bit pattern to resolve highest priority * Indexed value corresponds to highest priority bit position (i.e. 0..7) ********************************************************************************************************* */ INT8U const OSUnMapTbl[256] = { 0u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x00 to 0x0F */ 4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x10 to 0x1F */ 5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x20 to 0x2F */ 4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x30 to 0x3F */ 6u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x40 to 0x4F */ 4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x50 to 0x5F */ 5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x60 to 0x6F */ 4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x70 to 0x7F */ 7u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x80 to 0x8F */ 4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0x90 to 0x9F */ 5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xA0 to 0xAF */ 4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xB0 to 0xBF */ 6u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xC0 to 0xCF */ 4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xD0 to 0xDF */ 5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, /* 0xE0 to 0xEF */ 4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u /* 0xF0 to 0xFF */ };
---------------------------------------------------------- 解码表4.1 ---------------------------------------------------------------------------
4.2、计算就绪态最高优先级任务的任务ID的函数接口 OS_SchedNew
static void OS_SchedNew(void) { #if OS_LOWEST_PRIO <= 63u /*See if we support up to 64 tasks,这个函数可以只关注下面这三行,else 后面的可以先不关注,原理都是一样的*/ INT8U y; y = OSUnMapTbl[OSRdyGrp]; // OSUnMapTbl 计算最高优先级的解码表, y 表示是哪个组里面有任务进入就绪态了 OSPrioHighRdy = (INT8U)((y << 3u) + OSUnMapTbl[OSRdyTbl[y]]); // OSUnMapTbl[OSRdyTbl[y]]) 表示该任务组里面的具体哪个任务任务是最高优先级的, y << 3u 相当于 y * 8,u代表这个3 是一个无符号整数,即正整数 #else /*We support up to 256 tasks, 后面的可以先不用关注*/ INT8U y; OS_PRIO *ptbl; if ((OSRdyGrp & 0xFFu) != 0u) { y = OSUnMapTbl[OSRdyGrp & 0xFFu]; } else { y = OSUnMapTbl[(OS_PRIO)(OSRdyGrp >> 8u) & 0xFFu] + 8u; } ptbl = &OSRdyTbl[y]; if ((*ptbl & 0xFFu) != 0u) { OSPrioHighRdy = (INT8U)((y << 4u) + OSUnMapTbl[(*ptbl & 0xFFu)]); } else { OSPrioHighRdy = (INT8U)((y << 4u) + OSUnMapTbl[(OS_PRIO)(*ptbl >> 8u) & 0xFFu] + 8u); } #endif }
5、计算最高优先级
假设当前最高优先级任务是编号53 的任务,通过查找上面的图2可知:任务53 在任务组6(OSRdyGrp[6]),任务5(OSRdyTbl[5])
OSRdyGrp:0100 0000 bit[6]置1,转换成十进制就是:64(0x40),然后查解码表4.1得 OSUnMapTbl[64] = 6
OSRdyTbl: 0010 0000 bit[5]置1,转换成十进制就是:32(0x20),然后查解码表4.1得 OSUnMapTbl[32] = 5
最终得到就绪态任务的最高优先级的任务ID, OSPrioHighRdy = 6 * 8 + 5 = 53,符合预期
6、假设:
y = OSRdyGrp = 1000 0000 (bit[7] = 1,第7组有任务就绪了),转换成十进制:128(0x80),查解码表4.1得 y = OSUnmapTbl[128] = 7
x = OSRdyTbl = 0001 0000 (bit[4] = 1, 第4个任务优先级最高),转换成十进制:16(0x10),查解码表4.1得 x = OSUnmapTbl[16] = 4
故,最高优先级OSPrioHighRdy = y * 8 + x = 7 * 8 + 4 = 60
刚好对应的是任务ID 为60 的任务,如图6.1所示,表示任务60 是就绪优先级最高的,系统马上会切换并执行该任务
![在这里插入图片描述](https://img-blog.csdnimg.cn/51be59f0234b41f8b284b6ac679c23df.png
----------------------------------------------------------------------------------------- 图6.1 -----------------------------------------------------------------------------------
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。