μC/OS-Ⅱ内核调度分析

本文详细介绍了μC/OS-Ⅱ实时内核的调度特性,包括仅支持基于优先级的抢占式调度、64个优先级限制以及内核调度算法的高效实现。此外,文章还探讨了任务控制块OS_TCB的结构和功能,如任务栈、任务状态管理以及就绪表的内存映射实现,强调了μC/OS-Ⅱ的高效和灵活性。
摘要由CSDN通过智能技术生成

一. 内核概述:
    多任务系统中,内核负责管理各个任务,或者说为每个任务分配CPU时间,并且负责任务之间的通讯。内核提供的基本服务是任务切换。之所以使用实时内核可以 大大简化应用系统的设计,是因为实时内核允许将应用分成若干个任务,由实时内核来管理它们。内核本身也增加了应用程序的额外负荷,代码空间增加ROM的用 量,内核本身的数据结构增加了RAM的用量。但更主要的是,每个任务要有自己的栈空间,这一块吃起内存来是相当厉害的。内核本身对CPU的占用时间一般在2到5个百分点之间。μC/OS-Ⅱ有一个精巧的内核调度算法,实时内核精小,执行效率高,算法巧妙,代码空间很少。

二. μC/OS-Ⅱ内核调度特点:

  1. 只支持基于优先级的抢占式调度算法,不支持时间片轮循
  2. 64个优先级,只能创建64个任务,用户只能创建56个任务;
  3. 每个任务优先级都不相同;
  4. 不支持优先级逆转;
  5. READY队列通过内存映射表实现快速查询。效率非常高;
  6. 支持时钟节拍;
  7. 支持信号量,消息队列,事件控制块,事件标志组,消息邮箱任务通讯机制;
  8. 支持中断嵌套,中断嵌套层数可达255层,中断使用当前任务的堆栈保存上下文;
  9. 每个任务有自己的堆栈,堆栈大小用户自己设定;
  10. 支持动态修改任务优先级;
  11. 任务TCB为静态数组,建立任务只是从中获得一个TCB,不用动态分配,释放内存;
  12. 任务堆栈为用户静态或者动态创建,在任务创建外完成,任务创建本身不进行动态内存分配;
  13. 任务的总个数(OS_MAX_TASKS)由用户决定;
  14. 0优先级最高,63优先级最低
  15. 有一个优先级最低的空闲任务,在没有用户任务运行的时候运行.

三. 任务控制块 OS_TCB描述
    μC/OS-Ⅱ的TCB数据结构简单,内容容易理解,保存最基本的任务信息,同时还支持裁减来减小内存消耗,TCB是事先根据用户配置,静态分配内存的结构数组,通过优先级序号进行添加,查找,删除等功能。减少动态内存分配和释放。因为依靠优先级进行TCB分配,每个任务必须有自己的优先级,不能和其他任务具有相同的优先级。

typedef struct os_tcb           //任务控制块的数据结构
{
    OS_STK        *OSTCBStkPtr; //当前任务栈顶的指针
#if OS_TASK_CREATE_EXT_EN       //允许创建任务扩展模块
    void          *OSTCBExtPtr;
    OS_STK        *OSTCBStkBottom;
    INT32U         OSTCBStkSize;
    INT16U         OSTCBOpt;
    INT16U         OSTCBId;
#endif
    struct os_tcb *OSTCBNext;
    struct os_tcb *OSTCBPrev;
#if (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_EN || OS_SEM_EN
    OS_EVENT      *OSTCBEventPtr;
#endif 
#if (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_EN
    void          *OSTCBMsg;
#endif 
    INT16U         OSTCBDly;
    INT8U          OSTCBStat;
    INT8U          OSTCBPrio;
    INT8U          OSTCBX;
    INT8U          OSTCBY;
    INT8U          OSTCBBitX;
    INT8U          OSTCBBitY;
#if OS_TASK_DEL_EN
    BOOLEAN        OSTCBDelReq;
#endif
} OS_TCB;

 

.OSTCBStkPtr:是指向当前任务栈顶的指针。μC/OS-Ⅱ允许每个任务有自己的栈,尤为重要的是,每个任务的栈的容量可以是任意的。有些商业 内核要求所有任务栈的容量都一样,除非用户写一个复杂的接口函数来改变之。这种限制浪费了RAM,当各任务需要的栈空间不同时,也得按任务中预期栈容量需 求最多的来分配栈空间。OSTCBStkPtr是OS_TCB数据结构中唯一的一个能用汇编语言来处置的变量(在任务切换段的代码Context- switching code之中,)把OSTCBStkPtr放在数据结构的最前面,使得从汇编语言中处理这个变量时较为容易;

 

.*OSTCBExtPtr:指向用户定义的任务控制块扩展。用户可以扩展任务控制块而不必修改μC/OS-Ⅱ的源代码。.OSTCBExtPtr只在函 数OstaskCreateExt()中使用,故使用时要将OS_TASK_CREAT_EN设为1,以允许建立任务函数的扩展。例如用户可以建立一个数 据结构,这个数据结构包含每个任务的名字,或跟踪某个任务的执行时间,或者跟踪切换到某个任务的次数(见例3)。注意,笔者将这个扩展指针变量放在紧跟着 堆栈指针的位置,为的是当用户需要在汇编语言中处理这个变量时,从数据结构的头上算偏移量比较方便;


.*OSTCBStkBottom:是指向任务栈底的指针。如果微处理器的栈指针是递减的,即栈存储器从高地址向低地址方向分配,则 OSTCBStkBottom指向任务使用的栈空间的最低地址。类似地,如果微处理器的栈是从低地址向高地址递增型的,则OSTCBStkBottom指 向任务可以使用的栈空间的最高地址。函数OSTaskStkChk()要用到变量OSTCBStkBottom,在运行中检验栈空间的使用情况。用户可以 用它来确定任务实际需要的栈空间。这个功能只有当用户在任务建立时允许使用OSTaskCreateExt()函数时才能实现。这就要求用户将 OS_TASK_CREATE_EXT_EN设为1,以便允许该功能;

.OSTCBStkSize:存有栈中可容纳的指针数目而不是用字节(Byte)表示的栈容量总数。也就是说,如果栈中可以保存1,000个入口地址,每个地址宽度是32位的,则实际栈容量是4,000字节。同样是1,000个入口地址,如果每个地址宽度是16位的,则总栈容量只有2,000字节。在函数OSStakChk()中要调用OSTCBStkSize。同理,若使用该函数的话,要将OS_TASK_CREAT_EXT_EN设为1;


.OSTCBOpt:把“选择项”传给OSTaskCreateExt(),只有在用户将OS_TASK_CREATE_EXT_EN设为1时,这

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值