认识uCOS-II(一)

我们以往的单片机裸机程序设计中,系统是由一个无限循环的主程序和中断处理程序组成,主程序用来顺序处理事件,中断程序负责处理一些需要急需处理的突发事件。在,遇到强干扰时,程序的运行经常会产生异常,出现出错、跑飞,甚至死循环的状况,造成系统崩溃。引入操作系统,会大大提高系统的稳定性,提高程序的开发效率。关于uCOS-II的详细介绍,可参阅相关书籍。本文主要记录了uCOS-II源码中的一些基本知识点,这对移植uCOS-II有一定先导作用。

1、ucos-ii中的任务

如果把ucos-ii系统下单片机系统程序看作一个进程,那么任务就类似于操作系统中的线程,各个任务负责各自模块的管理,ucos-ii系统通过对时间的管理,让单片机轮流处理各个任务。ucos-ii通过一个任务控制块链表实现系统中任务的管理,任务控制块结构如下:

/*
*********************************************************************************************************
*                       TASK CONTROL BLOCK
*********************************************************************************************************
*/

typedef struct os_tcb {
    OS_STK          *OSTCBStkPtr;   
     /* Pointer to current top of stack       */

    struct os_tcb   *OSTCBNext;      
    /* Pointer to next     TCB in the TCB list                 */
    struct os_tcb   *OSTCBPrev;             
    /* Pointer to previous TCB in the TCB list                 *

    INT16U           OSTCBDly;             
     /* Nbr ticks to delay task or, timeout waiting for event  */
    INT8U            OSTCBStat;    
    /* Task status */
  /* Task PEND status */
    INT8U            OSTCBPrio;            
     /* Task priority (0 == highest) */

    INT8U            OSTCBX;                
    /* Bit position in group  corresponding to task priority   */
    INT8U            OSTCBY;               
     /* Index into ready table corresponding to task priority  */
#if OS_LOWEST_PRIO <= 63
    INT8U            OSTCBBitX;            
     /* Bit mask to access bit position in ready table   */
    INT8U            OSTCBBitY;             
    /* Bit mask to access bit position in ready group  */
#else
    INT16U           OSTCBBitX;             
    /* Bit mask to access bit position in ready table  */
    INT16U           OSTCBBitY;            
     /* Bit mask to access bit position in ready group   */
#endif
} OS_TCB;

任务的几种状态:睡眠状态、就绪状态、运行状态、等待状态、中断服务状态。
几个常用的全局变量:

OS_TCB           *OSTCBCur;                       
 /* Pointer to currently running TCB         */
OS_EXT  OS_TCB           *OSTCBFreeList;                   
/* Pointer to list of free TCBs           */
OS_EXT  OS_TCB           *OSTCBHighRdy;                    
/* Pointer to highest priority TCB R-to-R   */
OS_EXT  OS_TCB           *OSTCBList;                       
/* Pointer to doubly linked list of TCBs    */
OS_EXT  OS_TCB           *OSTCBPrioTbl[OS_LOWEST_PRIO + 1];
/* Table of pointers to created TCBs   知道某个任务的优先级就可直接从数组中取出对应任务控制块了     */

OS_EXT  OS_TCB     OSTCBTbl[OS_MAX_TASKS + OS_N_SYS_TASKS];   
/* Table of TCBs                  */

2、任务优先级及就绪表的管理

ucos-ii 中任务优先级别也类似任务的标号,系统中任务的优先级必须不相同,优先级号越低,优先级别越高。系统中的任务切换,也是通过优先级别号来寻找最高优先级的就绪任务来运行。为了更好地解决就绪任务的管理问题,系统中引入了就绪管理表的概念。这里也涉及到两个全局变量(任务数目最高为63):
INT8U OSRdyGrp; /* Ready list group */
INT8U OSRdyTbl[OS_RDY_TBL_SIZE]; /* Table of tasks which are ready to run */
task waiting excel
那么问题就来了,任务控制块中的任务优先级OSTCBPrio是怎样与就绪表对应上的呢?在任务切换时,我们如何快速地查找最高优先级别的任务运行呢?
先说第一个问题,任务创建时,给定一个优先级号(INT8U)prio的任务,很显然prio的bit5、bit4、bit3决定着 OSRdyGrp 的值,bit2、bit1、bit0决定着OSRdyTbl[OS_RDY_TBL_SIZE] 的值,就有下面的计算公式:
OSRdyGrp |= 1 <<(prio>>3);
OSRdyTbl[prio>>3] |=1<<(prio&0x07);
清除就绪位则为:
OSRdyTbl[prio>>3] &=~(1<<(prio&0x07));
OSRdyGrp &= ~(1 <<(prio>>3));
ucosii 为了提高运算速度,采用了查表的形式:
OSRdyGrp |= OSMapTbl[prio>>3]);
OSRdyTbl[prio>>3] |=OSMapTbl(prio&0x07);
清除就绪位
OSRdyTbl[prio>>3] |&=~OSMapTbl(prio&0x07);
OSRdyGrp &= ~OSMapTbl[prio>>3]);

INT8U const OSMapTbl[] ={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
需要注意的是,清除就绪位时,必须先清除优先级号在OSRdyTbl中的值后,才能清除OSRdyGrp中的值。这时我们看下OS_TCB定义的OSTCBX=prio&0x07 、OSTCBY = prio>>3、OSTCBBitX = OSMapTbl[prio&0x07]、OSTCBBitY = OSMapTbl[prio>>3]。

第二个问题,系统如何查找最高优先级别的就绪任务,通过顺序查找OSRdyTbl和OSRdyGrp对时间开销很大,ucosii引入了一张索引表来解决这一问题,列举如下:

/*
*********************************************************************************************************
*                                       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] = {
    0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,      
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       
    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       
    7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       
    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       
    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0        
};

我们在查找最高优先级任务时,首先确定OSRdyGrp的8位中置位的最低位在哪位上,若bit2=1,bit1=1(OSRdyGrp = 6)则确定最高优先级任务的优先级号value of High prio OSRdyGrp = 0x01, OSUnMapTbl的作用就是通过映射整个就绪表分组值OSRdyGrp确定value of High prio OSRdyGrp,即OSUnMapTbl[6] = 1。同理,OSRdyTbl的确定也采用这种方法,优先级别确定算法如下:

 y    = OSUnMapTbl[OSRdyGrp];    
 x    = OSUnMapTbl[OSRdyTbl[y]];
 prio = (INT8U)((y << 3) + x);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
\SOFTWARE The main directory from the root where all software-related files are placed. \SOFTWARE\BLOCKS The main directory where all ‘Building Blocks’ are located. With μC/OS-II, I included a ‘building block’ that handles DOS-type compatible functions that are used by the example code. \SOFTWARE\BLOCKS\TO This directory contains the files for the TO utility (see Appendix E, TO). The source file is TO.C and is found in the \SOFTWARE\TO\SOURCE directory. The DOS executable file (TO.EXE) is found in the \SOFTWARE\TO\EXE directory. Note that TO requires a file called TO.TBL which must reside on your root directory. An example of TO.TBL is also found in the \SOFTWARE\TO\EXE directory. You will need to move TO.TBL to the root directory if you are to use TO.EXE. \SOFTWARE\uCOS-II The main directory where all μC/OS-II files are located. \SOFTWARE\uCOS-II\EX1_x86L This directory contains the source code for EXAMPLE #1 (see section 1.07, Example #1) which is intended to run under DOS (or a DOS window under Windows 95). \SOFTWARE\uCOS-II\EX2_x86L This directory contains the source code for EXAMPLE #2 (see section 1.08, Example #2) which is intended to run under DOS (or a DOS window under Windows 95). \SOFTWARE\uCOS-II\EX3_x86L This directory contains the source code for EXAMPLE #3 (see section 1.09, Example #3) which is intended to run under DOS (or a DOS window under Windows 95). \SOFTWARE\uCOS-II\Ix86L This directory contains the source code for the processor dependent code (a.k.a. the port) of μC/OS-II for an 80x86 Real-Mode, Large Model processor. \SOFTWARE\uCOS-II\SOURCE This directory contains the source code for processor independent portion of μC/OS-II. This code is fully portable to other processor architectures.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值