当前位置:   article > 正文

UC/OS-II 操作系统最高优先级任务的任务ID 计算_us/os

us/os

一、us/os-II 操作系统任务管理

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!   */
  • 1
  • 2

3、64 个任务分成了 8 个组(OSRdyGrp),每个组8个任务(OSRdytbl),用一个8bits 的数OSRdyGrp来表示任务组, OSRdyGrp 的哪个bit 位置1,就表示哪个组里面有任务进入了就绪态,然后再看OSRdyGrp 就知道具体是哪一个任务了

os_ii.h

#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*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3.1、任务编号管理图1:
在这里插入图片描述
----------------------------------------------------------- 图1 --------------------------------------------------------------------------------
3.2、任务编号管理图2:
在这里插入图片描述
----------------------------------------------------------- 图2 --------------------------------------------------------------------------------

4、最高优先级任务的任务ID 解码表 OSUnMapTbl,计算最高优先级任务的时候需要查两次这个解码表

os_core.c

/*
*********************************************************************************************************
*                                      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                   */
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

---------------------------------------------------------- 解码表4.1 ---------------------------------------------------------------------------

4.2、计算就绪态最高优先级任务的任务ID的函数接口 OS_SchedNew

os_core.c

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
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

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 -----------------------------------------------------------------------------------

7、总结:只要知道了就绪态任务的最高优先级任务的组号 OSRdyGrp 和任务号OSRdyTbl,就可以计算出来就绪态最高优先级的任务ID,然后系统就会自动切换、运行该任务。这就是uc/os-II 操作系统的一个特性:不管你系统当前正在运行谁的任务,只要我的任务优先级是最高的,而且已经就绪了的,就会停止你的任务,然后来运行我的任务,这样好处就是系统实时性高,坏处就是额…额…

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/460158
推荐阅读
相关标签
  

闽ICP备14008679号